?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Configuration Management : VED DS Display' ??
MODULE cmm$ved_display_conf;

{ PURPOSE:
{   This module resides in OSF$JOB_TEMPLATE_223 and allows the use of the VED display command to display
{   configuration status.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc clt$value
*copyc cme$physical_configuration_mgr
*copyc cmt$device_status_display
*copyc clt$display_control
*copyc jmt$system_supplied_name
*copyc ost$status
*copyc pmp$get_mainframe_id
*copyc ost$string
?? POP ??
*copyc clp$close_display
*copyc clp$convert_integer_to_rjstring
*copyc cmp$count_con_access_job
*copyc cmp$get_element_state
*copyc clp$new_display_line
*copyc cmp$pc_get_element
*copyc clp$put_display
*copyc cmp$search_active_volume_table
*copyc cmp$search_peripheral_table
*copyc dpp$put_next_line
*copyc dpp$clear_window
*copyc ofp$open_display
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$set_status_abnormal
*copyc cmv$peripheral_element_table
*copyc cmv$physical_configuration
*copyc cmv$logical_unit_table
*copyc cmv$state_info_table
*copyc cmv$pp_element_table
*copyc iov$tusl_p
*copyc osv$task_private_heap
*copyc osd$virtual_address
*copyc oss$job_paged_literal
*copyc oss$task_private
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  VAR
    cmv$device_status: ^array [1 .. * ] of cmt$device_status_display := NIL;

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

  PROCEDURE [XDCL, #GATE] cmp$ved_display_configuration
    (    wid: dpt$window_id;
         display_name: ost$name;
         file_name: amt$local_file_name;
         initial_call: boolean;
     VAR status: ost$status);

    VAR
      default_state_names: [STATIC, READ, oss$job_paged_literal] array [cmt$element_state] of string (4) :=
            ['ON  ', 'OFF ', 'DOWN'],
      title: [READ, oss$job_paged_literal] string (80) :=
            'Name(15 chars)  Product   State UN8 ----- Iou/Channel ----- VSN    QC MAC LUN FF';

    VAR
      avt_entry_not_found: boolean,
      current_mainframe: pmt$mainframe_id,
      display_control: clt$display_control,
      display_line: string (80),
      element_desc: cmt$element_descriptor,
      element_res: cmt$element_reservation,
      entry_type: rmt$device_class,
      external_vsn: rmt$external_vsn,
      i: integer,
      ignore: ost$status,
      index: integer,
      iou_name: cmt$element_name,
      jc: integer,
      lun: iot$logical_unit,
      recorded_vsn: rmt$recorded_vsn,
      search_key: dmt$avt_search_key,
      state: cmt$element_state,
      str: ost$string,
      table_index: integer;

?? NEWTITLE := 'abort_handler', EJECT ??

{ PURPOSE:
{   This procedure provides clean-up processing when a task abort or a task exit occurs.

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           save_area_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      IF cmv$device_status <> NIL THEN
        FREE cmv$device_status IN osv$task_private_heap^;
      IFEND;
      IF wid = 0 THEN
        clp$close_display (display_control, ignore);
      IFEND;

    PROCEND abort_handler;
?? OLDTITLE ??
?? EJECT ??
    status.normal := TRUE;
    pmp$get_mainframe_id (current_mainframe, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    find_all_device_info (current_mainframe, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    IF wid = 0 THEN
      osp$establish_block_exit_hndlr (^abort_handler);
    IFEND;
    IF initial_call THEN
      ofp$open_display (file_name, wid, dpc$wc_sharing, dpc$wk_table, title, display_control, status);
      IF NOT status.normal THEN
        RETURN; {----->
      IFEND;
    IFEND;

  /display_open/
    BEGIN
      IF wid = 0 THEN
        clp$put_display (display_control, '', clc$trim, status);
      ELSE
        dpp$clear_window (wid, status);
      IFEND;
      IF NOT status.normal THEN
        EXIT /display_open/; {----->
      IFEND;

    /display_element/
      FOR index := LOWERBOUND (cmv$device_status^) TO UPPERBOUND (cmv$device_status^) DO
        display_line (1, * ) := '   ';
        display_line (1, 15) := cmv$device_status^ [index].element_name;
        IF cmv$device_status^ [index].element_name (16, 1) <> ' ' THEN
          display_line (16, 1) := '.';
        IFEND;

        form_product_string (cmv$device_status^ [index].product_id, str);
        display_line (17, 10) := str.value (1, 10);
        cmp$get_element_state (cmv$device_status^ [index].element_name, {unused} iou_name, state, ignore);
        display_line (28, 4) := default_state_names [state];

        clp$convert_integer_to_rjstring (cmv$device_status^ [index].physical_address, 8, FALSE, ' ',
              display_line (32, 3), ignore);

        display_line (37, 4) := cmv$device_status^ [index].channels [1].iou;
        display_line (41, 1) := '/';
        display_line (42, 6) := cmv$device_status^ [index].channels [1].name;
        IF cmv$device_status^ [index].channels [2].name <> ' ' THEN
          display_line (49, 4) := cmv$device_status^ [index].channels [2].iou;
          display_line (53, 1) := '/';
          display_line (54, 6) := cmv$device_status^ [index].channels [2].name;
        IFEND;

      /loop/
        FOR i := LOWERBOUND (cmv$state_info_table^) TO UPPERBOUND (cmv$state_info_table^) DO
          IF (cmv$state_info_table^ [i].element_name = cmv$device_status^ [index].element_name) AND
                (cmv$state_info_table^ [i].element_type <> cmc$data_channel_element) THEN
            lun := cmv$state_info_table^ [i].logical_unit;
            EXIT /loop/; {----->
          IFEND;
        FOREND /loop/;

        IF lun <> 0 THEN
          clp$convert_integer_to_rjstring (lun, 10, FALSE, ' ', display_line (74, 4), ignore);
          IF cmv$logical_unit_table^ [lun].configured AND (cmv$logical_unit_table^ [lun].
                unit_interface_table^.unit_type <= ioc$highest_tape_unit) THEN

          /search_tusl_for_evsn/
            FOR i := LOWERBOUND (iov$tusl_p^) TO UPPERBOUND (iov$tusl_p^) DO
              IF (cmv$device_status^ [index].element_name = iov$tusl_p^ [i].element_name) AND
                    (iov$tusl_p^ [i].assignment_state <> ioc$not_assigned) THEN
                display_line (61, 6) := iov$tusl_p^ [i].evsn;
                EXIT /search_tusl_for_evsn/; {----->
              IFEND;
            FOREND /search_tusl_for_evsn/;
          ELSE
            search_key.value := dmc$search_avt_by_lun;
            search_key.logical_unit_number := lun;
            cmp$search_active_volume_table (search_key, recorded_vsn, avt_entry_not_found);
            IF NOT avt_entry_not_found THEN
              display_line (61, 6) := recorded_vsn;
              IF cmv$logical_unit_table^ [lun].configured THEN
                clp$convert_integer_to_rjstring (cmv$logical_unit_table^ [lun].unit_interface_table^.
                      queue_count, 10, FALSE, ' ', display_line (67, 4), ignore);
              IFEND;
            IFEND;
          IFEND;
        IFEND;

        IF lun <> 0 THEN
          IF cmv$device_status^ [index].element_type = cmc$storage_device_element THEN
            IF (cmv$logical_unit_table^ [lun].unit_interface_table <> NIL) THEN
              CASE cmv$logical_unit_table^ [lun].unit_interface_table^.unit_type OF
              = ioc$dt_ms5833_1p, ioc$dt_ms5833_3p,
                ioc$dt_ms5837_1p, ioc$dt_ms5837_3p,
                ioc$dt_ms5838_1p, ioc$dt_ms5838_3p,
                ioc$dt_ms47444_1p, ioc$dt_ms47444_3p =

                IF cmv$logical_unit_table^ [lun].unit_interface_table^.unit_status.force_format THEN
                  display_line (79, 1) := 'T';
                ELSE
                  display_line (79, 1) := 'F';
                IFEND;
              ELSE
                ;
              CASEND;
            IFEND;
          IFEND;
        IFEND;

        element_desc.element_type := cmv$device_status^ [index].element_type;
        element_desc.peripheral_descriptor.use_logical_identification := TRUE;
        element_desc.peripheral_descriptor.element_name := cmv$device_status^ [index].element_name;
        cmp$search_peripheral_table (element_desc, element_res, FALSE, table_index, ignore);
        IF ignore.normal THEN
          CASE cmv$peripheral_element_table.pointer^ [table_index].maintenance_activity.access OF
          = msc$concurrent_access =
            cmp$count_con_access_job (table_index, jc, ignore);
            clp$convert_integer_to_rjstring (jc, 10, FALSE, ' ', display_line (71, 3), ignore);
          = msc$dedicated_access =
            display_line (73, 1) := 'D';
          ELSE
            ;
          CASEND;
        IFEND;
        IF display_line <> '   ' THEN
          IF wid = 0 THEN
            clp$put_display (display_control, display_line, clc$trim, status);
          ELSE
            dpp$put_next_line (wid, display_line, status);
          IFEND;
          IF NOT status.normal THEN
            EXIT /display_open/; {----->
          IFEND;
        IFEND;
      FOREND /display_element/;

    END /display_open/;

    IF cmv$device_status <> NIL THEN
      FREE cmv$device_status IN osv$task_private_heap^;
    IFEND;

    IF wid = 0 THEN
      clp$close_display (display_control, status);
      osp$disestablish_cond_handler;
    IFEND;

  PROCEND cmp$ved_display_configuration;
?? OLDTITLE ??
?? NEWTITLE := 'find_all_device_info', EJECT ??

{ PURPOSE:
{   This procedure scans the active physical configuration to build an array of device information to be
{   displayed on the system console.

  PROCEDURE find_all_device_info
    (    current_mainframe: pmt$mainframe_id;
     VAR status: ost$status);

    VAR
      ch_element: ^cmt$element_definition,
      cm_port: cmt$communications_port_number,
      count: integer,
      ct_port: cmt$controller_port_number,
      device_status_entry_p: ^cmt$device_status_display,
      element: ^cmt$element_definition,
      element_definition: cmt$element_definition,
      eq: cmt$physical_equipment_number,
      i: integer,
      ignore: ost$status,
      iou_name: cmt$element_name,
      j: integer,
      port: cmt$data_storage_port_number,
      start: integer,
      storage_device_p: ^cmt$storage_device_definition,
      table_index: integer;

    count := 0;
    FOR i := 1 TO UPPERBOUND (cmv$physical_configuration^) DO
      IF (cmv$physical_configuration^ [i].element_type <> cmc$data_channel_element) THEN
        count := count + 1;
      IFEND;
    FOREND;

    IF cmv$device_status <> NIL THEN
      FREE cmv$device_status IN osv$task_private_heap^;
    IFEND;

    ALLOCATE cmv$device_status: [1 .. count] IN osv$task_private_heap^;
    FOR i := 1 TO count DO
      FOR j := 1 TO 2 DO
        cmv$device_status^ [i].channels [j].iou := '    ';
        cmv$device_status^ [i].channels [j].name := '      ';
      FOREND;
    FOREND;

    table_index := 0;

  /physical_configuration/
    FOR i := 1 TO UPPERBOUND (cmv$physical_configuration^) DO
      IF cmv$physical_configuration^ [i].element_type = cmc$data_channel_element THEN
        CYCLE /physical_configuration/; {----->
      IFEND;

      table_index := table_index + 1;
      start := 1;
      element_definition := cmv$physical_configuration^ [i];
      device_status_entry_p := ^cmv$device_status^ [table_index];

      device_status_entry_p^.element_name := element_definition.element_name;
      device_status_entry_p^.element_type := element_definition.element_type;
      device_status_entry_p^.product_id := element_definition.product_id;

      CASE element_definition.element_type OF
      = cmc$storage_device_element =
        storage_device_p := ^element_definition.storage_device;
        device_status_entry_p^.physical_address := storage_device_p^.physical_unit_number;

      /loop/
        FOR port := LOWERVALUE (cmt$data_storage_port_number) TO UPPERVALUE (cmt$data_storage_port_number) DO
          IF start > 2 THEN
            EXIT /loop/; {----->
          IFEND;

          IF storage_device_p^.connection.port [port].configured THEN
            IF storage_device_p^.connection.port [port].upline_connection_type = cmc$data_channel_element THEN
              iou_name := storage_device_p^.connection.port [port].iou;
            IFEND;

            cmp$pc_get_element (storage_device_p^.connection.port [port].element_name, iou_name, element,
                  ignore);
            IF NOT ignore.normal THEN
              CYCLE /loop/; {----->
            IFEND;

            IF element^.element_type = cmc$controller_element THEN

            /inner_loop/
              FOR ct_port := LOWERVALUE (cmt$controller_port_number)
                    TO UPPERVALUE (cmt$controller_port_number) DO
                IF (element^.controller.connection.port [ct_port].configured)
{             } AND (element^.controller.connection.port [ct_port].mainframe_ownership =
                      current_mainframe) THEN
                  cmp$pc_get_element (element^.controller.connection.port [ct_port].element_name,
                        element^.controller.connection.port [ct_port].iou, ch_element, ignore);
                  IF NOT ignore.normal THEN
                    CYCLE /inner_loop/; {----->
                  IFEND;
                  IF ch_element^.element_type = cmc$data_channel_element THEN
                    device_status_entry_p^.channels [start].name := element^.controller.connection.
                          port [ct_port].element_name (1, 6);
                    device_status_entry_p^.channels [start].iou := element^.controller.connection.
                          port [ct_port].iou (1, 4);
                    start := start + 1;
                  IFEND;
                IFEND;
              FOREND /inner_loop/;

            ELSE
              IF element^.data_channel.mainframe_ownership = current_mainframe THEN
                device_status_entry_p^.channels [start].name := element^.element_name (1, 6);
                device_status_entry_p^.channels [start].iou := element^.data_channel.iou (1, 4);
                start := start + 1;
              IFEND;
            IFEND;
          IFEND;
        FOREND /loop/;

      = cmc$communications_element =
        device_status_entry_p^.physical_address := element_definition.communications_element.
              physical_equipment_number;

      /loop1/
        FOR cm_port := LOWERVALUE (cmt$communications_port_number)
              TO UPPERVALUE (cmt$communications_port_number) DO

          IF (start > 2) THEN
            EXIT /loop1/; {----->
          IFEND;
          IF (element_definition.communications_element.connection.port [cm_port].configured) AND
                (element_definition.communications_element.connection.port [cm_port].mainframe_ownership =
                current_mainframe) THEN
            cmp$pc_get_element (element_definition.communications_element.connection.port [cm_port].
                  element_name, element_definition.communications_element.connection.port [cm_port].iou,
                  ch_element, ignore);
            IF NOT status.normal THEN
              CYCLE /loop1/; {----->
            IFEND;
            IF ch_element^.element_type = cmc$data_channel_element THEN
              device_status_entry_p^.channels [start].name := element_definition.communications_element.
                    connection.port [cm_port].element_name (1, 6);
              device_status_entry_p^.channels [start].iou := element_definition.communications_element.
                    connection.port [cm_port].iou (1, 4);
              start := start + 1;
            IFEND;
          IFEND;
        FOREND /loop1/;

      = cmc$channel_adapter_element =
        device_status_entry_p^.physical_address := element_definition.channel_adapter.
              physical_equipment_number;
        IF element_definition.channel_adapter.connection.channel.configured THEN
          device_status_entry_p^.channels [1].name := element_definition.channel_adapter.connection.channel.
                element_name (1, 6);
          device_status_entry_p^.channels [1].iou := element_definition.channel_adapter.connection.channel.
                iou (1, 4);
        IFEND;

      = cmc$external_processor_element =
        device_status_entry_p^.physical_address := element_definition.external_processor.
              physical_equipment_number;

      /loop2/
        FOR eq := LOWERVALUE (cmt$physical_equipment_number) TO UPPERVALUE (cmt$physical_equipment_number) DO
          IF start > 2 THEN
            EXIT /loop2/; {----->
          IFEND;
          IF element_definition.external_processor.connection.io_port [eq].configured THEN

            cmp$pc_get_element (element_definition.external_processor.connection.io_port [eq].element_name,
                  element_definition.external_processor.connection.io_port [eq].iou, ch_element, ignore);
            IF NOT ignore.normal THEN
              CYCLE /loop2/; {----->
            IFEND;
            device_status_entry_p^.channels [start].name := element_definition.external_processor.connection.
                  io_port [eq].element_name (1, 6);
            device_status_entry_p^.channels [start].iou := element_definition.external_processor.connection.
                  io_port [eq].iou (1, 4);
            start := start + 1;
          IFEND;
        FOREND /loop2/;

      = cmc$controller_element =
        device_status_entry_p^.physical_address := element_definition.controller.physical_equipment_number;

      /loop3/
        FOR cm_port := LOWERVALUE (cmt$controller_port_number) TO UPPERVALUE (cmt$controller_port_number) DO
          IF (start > 2) THEN
            EXIT /loop3/; {----->
          IFEND;
          IF element_definition.controller.connection.port [cm_port].configured THEN
            device_status_entry_p^.channels [start].name := element_definition.controller.connection.
                  port [cm_port].element_name (1, 6);
            device_status_entry_p^.channels [start].iou := element_definition.controller.connection.
                  port [cm_port].iou (1, 4);
            start := start + 1;
          IFEND;
        FOREND /loop3/;

      ELSE
        ;
      CASEND;
    FOREND /physical_configuration/;

  PROCEND find_all_device_info;
?? OLDTITLE ??
?? NEWTITLE := '[inline] FORM_PRODUCT_STRING', EJECT ??

  PROCEDURE [INLINE] form_product_string
    (    product_id: cmt$product_identification;
     VAR pid_string: ost$string);

    pid_string.size := 10;
    pid_string.value (1, 6) := product_id.product_number;
    pid_string.value (7, 1) := product_id.underscore;
    pid_string.value (8, 3) := product_id.model_number;

  PROCEND form_product_string;
?? OLDTITLE ??
MODEND cmm$ved_display_conf;
