MODULE ofm$mass_storage_usage_display;
?? RIGHT := 110 ??

{Mass Storage Usage
{ CPU Idle:  0/ 0,  0/ 0
{
{     Queue  Requests incl. Swap  --Avg-Response-Time-  Byte/  Total  Req.--Total',
{VSN  Count   Read Write  Total    Read   Write    Unit  Req   Seeks Cyl.-Skipped',
{--------------------------------------------------------------------------------';
{xxxxxx  xxxx xxxxx xxxxxx xxxxxx xxx.xx xxx.xx xxx.xx xxxxx xxxxxx xxxxxx xxxxxx

?? NEWTITLE := 'Global Declarations Referenced By This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc oss$job_paged_literal
*copyc oss$task_shared
*copyc dmt$active_volume_table_index
*copyc ost$halfword
*copyc ost$status
?? POP ??
*copyc clp$close_display
*copyc clp$put_display
*copyc cmp$get_element_entry_via_lun
*copyc dmp$calculate_device_capacity
*copyc dmp$get_allocation_info
*copyc dmp$get_out_of_space_sets
*copyc dpp$clear_window
*copyc dpp$put_next_line
*copyc ofp$build_system_line
*copyc ofp$get_next_avt_index
*copyc ofp$open_display
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc pmp$binary_to_ascii_fit
*copyc cmv$logical_unit_table
*copyc dmv$active_volume_table
*copyc iov$disk_unit_usage_p
*copyc ofv$mass_storage_display_infos
*copyc osv$task_shared_heap

  VAR
    dmv$q_devices_added: [XREF] integer;

?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared By This Module', EJECT ??

  CONST
    c$title_1 = '     Queue  Requests incl. Swap  --Avg-Response-Time-  Byte/  Total  Req.--Total',
    c$title_2 = 'VSN  Count   Read Write  Total    Read   Write    Unit  Req   Seeks Cyl.-Skipped',
    c$title_3 = '--------------------------------------------------------------------------------';

  TYPE
    t$total_attributes = record
      queue_count: integer,
      read_requests: integer,
      read_qtime: integer,
      read_mau_count: integer,
      write_requests: integer,
      write_qtime: integer,
      write_data_and_preset_maus: integer,
      swap_in_requests: integer,
      swap_in_qtime: integer,
      swap_in_mau_count: integer,
      swap_out_requests: integer,
      swap_out_qtime: integer,
      swap_out_data_and_preset_maus: integer,
      requests_causing_skipped_cyl: integer,
      total_cylinders_skipped: integer,
      total_streamed_requests: integer,
      bytes_per_mau: integer,
    recend;

  TYPE
    t$volume_attributes = record
      vsn: rmt$recorded_vsn,
      available: boolean,
      data_available: boolean,
      queue_count: 0 .. 0ffff(16),
      read_requests: integer,
      read_qtime: integer,
      read_mau_count: integer,
      write_requests: integer,
      write_qtime: integer,
      write_data_and_preset_maus: integer,
      swap_in_requests: integer,
      swap_in_qtime: integer,
      swap_in_mau_count: integer,
      swap_out_requests: integer,
      swap_out_qtime: integer,
      swap_out_data_and_preset_maus: integer,
      requests_causing_skipped_cyl: integer,
      total_cylinders_skipped: integer,
      total_streamed_requests: integer,
      bytes_per_mau: integer,
    recend;

  TYPE
    t$statistics = array [1 .. * ] of ^t$volume_attributes;

  VAR
    v$nil_total_attributes: [READ, oss$job_paged_literal] t$total_attributes := [
{ QUEUE_COUNT                          } 0,
{ READ_REQUESTS                        } 0,
{ READ_QTIME                           } 0,
{ READ_MAU_COUNT                       } 0,
{ WRITE_REQUESTS                       } 0,
{ WRITE_QTIME                          } 0,
{ WRITE_DATA_AND_PRESET_MAUS           } 0,
{ SWAP_IN_REQUESTS                     } 0,
{ SWAP_IN_QTIME                        } 0,
{ SWAP_IN_MAU_COUNT                    } 0,
{ SWAP_OUT_REQUESTS                    } 0,
{ SWAP_OUT_QTIME                       } 0,
{ SWAP_OUT_DATA_AND_PRESET_MAUS        } 0,
{ REQUESTS_CAUSING_SKIPPED_CYL         } 0,
{ TOTAL_CYLINDERS_SKIPPED              } 0,
{ TOTAL_STREAMED_REQUESTS              } 0,
{ BYTES_PER_MAU                        } 0];

  VAR
    v$nil_volume_attributes: [READ, oss$job_paged_literal] t$volume_attributes := [
{ VSN                                  } '',
{ AVAILABLE                            } FALSE,
{ DATA_AVAILABLE                       } FALSE,
{ QUEUE_COUNT                          } 0,
{ READ_REQUESTS                        } 0,
{ READ_QTIME                           } 0,
{ READ_MAU_COUNT                       } 0,
{ WRITE_REQUESTS                       } 0,
{ WRITE_QTIME                          } 0,
{ WRITE_DATA_AND_PRESET_MAUS           } 0,
{ SWAP_IN_REQUESTS                     } 0,
{ SWAP_IN_QTIME                        } 0,
{ SWAP_IN_MAU_COUNT                    } 0,
{ SWAP_OUT_REQUESTS                    } 0,
{ SWAP_OUT_QTIME                       } 0,
{ SWAP_OUT_DATA_AND_PRESET_MAUS        } 0,
{ REQUESTS_CAUSING_SKIPPED_CYL         } 0,
{ TOTAL_CYLINDERS_SKIPPED              } 0,
{ TOTAL_STREAMED_REQUESTS              } 0,
{ BYTES_PER_MAU                        } 0];

?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #GATE] OFP$MASS_STORAGE_SPACE_DISPLAY', EJECT ??

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

    VAR
      v$title: [READ, oss$job_paged_literal] string (18) := 'Mass Storage Usage';

    VAR
      v$previous_data_for_display: [STATIC, oss$task_shared] boolean := FALSE,
      v$previous_stats_p: [STATIC, oss$task_shared] ^t$statistics := NIL,
      v$system_line_info: [STATIC, oss$task_shared] ^oft$system_line_info := NIL;

    VAR
      avt_index: dmt$active_volume_table_index,
      class: dmt$class_member,
      class_index: integer,
      classes: dmt$class,
      control: oft$msdi_volume_access_control,
      display_control: clt$display_control,
      index: integer,
      name_length: integer,
      out_of_space_sets_p: ^dmt$out_of_space_sets,
      set_count: integer,
      set_name: stt$set_name,
      eot: boolean,
      str: string (80),
      string_length: integer,
      total_attributes: t$total_attributes,
      volume_attributes: t$volume_attributes;

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

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

      VAR
        ignore_status: ost$status;

      IF wid = 0 THEN
        clp$close_display (display_control, ignore_status);
      IFEND;

    PROCEND p$abort_handler;
?? OLDTITLE ??
?? NEWTITLE := 'p$build_total_attributes', EJECT ??

    PROCEDURE p$build_total_attributes
      (    volume_attributes: t$volume_attributes;
       VAR total_attributes: t$total_attributes);

      total_attributes.queue_count := total_attributes.queue_count + volume_attributes.queue_count;
      total_attributes.read_requests := total_attributes.read_requests + volume_attributes.read_requests;
      total_attributes.read_qtime := total_attributes.read_qtime + volume_attributes.read_qtime;
      total_attributes.read_mau_count := total_attributes.read_mau_count + volume_attributes.read_mau_count;
      total_attributes.write_requests := total_attributes.write_requests + volume_attributes.write_requests;
      total_attributes.write_qtime := total_attributes.write_qtime + volume_attributes.write_qtime;
      total_attributes.write_data_and_preset_maus := total_attributes.write_data_and_preset_maus +
            volume_attributes.write_data_and_preset_maus;
      total_attributes.swap_in_requests := total_attributes.swap_in_requests +
            volume_attributes.swap_in_requests;
      total_attributes.swap_in_qtime := total_attributes.swap_in_qtime + volume_attributes.swap_in_qtime;
      total_attributes.swap_in_mau_count := total_attributes.swap_in_mau_count +
            volume_attributes.swap_in_mau_count;
      total_attributes.swap_out_requests := total_attributes.swap_out_requests +
            volume_attributes.swap_out_requests;
      total_attributes.swap_out_qtime := total_attributes.swap_out_qtime + volume_attributes.swap_out_qtime;
      total_attributes.swap_out_data_and_preset_maus := total_attributes.swap_out_data_and_preset_maus +
            volume_attributes.swap_out_data_and_preset_maus;
      total_attributes.requests_causing_skipped_cyl := total_attributes.requests_causing_skipped_cyl +
            volume_attributes.requests_causing_skipped_cyl;
      total_attributes.total_cylinders_skipped := total_attributes.total_cylinders_skipped +
            volume_attributes.total_cylinders_skipped;
      total_attributes.total_streamed_requests := total_attributes.total_streamed_requests +
            volume_attributes.total_streamed_requests;
      total_attributes.bytes_per_mau := total_attributes.bytes_per_mau + volume_attributes.bytes_per_mau;

    PROCEND p$build_total_attributes;
?? OLDTITLE ??
?? NEWTITLE := 'p$build_volume_attribute_update', EJECT ??

    PROCEDURE p$build_volume_attribute_update
      (VAR previous_volume_attributes_p: ^t$volume_attributes;
       VAR volume_attributes: t$volume_attributes);

      VAR
        new_volume_attributes: t$volume_attributes;

      IF previous_volume_attributes_p = NIL THEN
        ALLOCATE previous_volume_attributes_p IN osv$task_shared_heap^;
        previous_volume_attributes_p^ := volume_attributes;

      ELSEIF previous_volume_attributes_p^.vsn <> volume_attributes.vsn THEN
        previous_volume_attributes_p^ := volume_attributes;

      ELSE
        new_volume_attributes := volume_attributes;
        new_volume_attributes.available := volume_attributes.available AND
              previous_volume_attributes_p^.available;
        new_volume_attributes.data_available := volume_attributes.data_available AND
              previous_volume_attributes_p^.data_available;

        IF (new_volume_attributes.vsn <> '') AND (new_volume_attributes.available) AND
              (new_volume_attributes.data_available) THEN
          new_volume_attributes.queue_count := volume_attributes.queue_count;
          new_volume_attributes.read_requests := volume_attributes.read_requests -
                previous_volume_attributes_p^.read_requests;
          new_volume_attributes.read_qtime := volume_attributes.read_qtime -
                previous_volume_attributes_p^.read_qtime;
          new_volume_attributes.read_mau_count := volume_attributes.read_mau_count -
                previous_volume_attributes_p^.read_mau_count;
          new_volume_attributes.write_requests := volume_attributes.write_requests -
                previous_volume_attributes_p^.write_requests;
          new_volume_attributes.write_qtime := volume_attributes.write_qtime -
                previous_volume_attributes_p^.write_qtime;
          new_volume_attributes.write_data_and_preset_maus :=
                volume_attributes.write_data_and_preset_maus - previous_volume_attributes_p^.
                write_data_and_preset_maus;
          new_volume_attributes.swap_in_requests := volume_attributes.swap_in_requests -
                previous_volume_attributes_p^.swap_in_requests;
          new_volume_attributes.swap_in_qtime := volume_attributes.swap_in_qtime -
                previous_volume_attributes_p^.swap_in_qtime;
          new_volume_attributes.swap_in_mau_count := volume_attributes.swap_in_mau_count -
                previous_volume_attributes_p^.swap_in_mau_count;
          new_volume_attributes.swap_out_requests := volume_attributes.swap_out_requests -
                previous_volume_attributes_p^.swap_out_requests;
          new_volume_attributes.swap_out_qtime := volume_attributes.swap_out_qtime -
                previous_volume_attributes_p^.swap_out_qtime;
          new_volume_attributes.swap_out_data_and_preset_maus :=
                volume_attributes.swap_out_data_and_preset_maus -
                previous_volume_attributes_p^.swap_out_data_and_preset_maus;
          new_volume_attributes.requests_causing_skipped_cyl :=
                volume_attributes.requests_causing_skipped_cyl -
                previous_volume_attributes_p^.requests_causing_skipped_cyl;
          new_volume_attributes.total_cylinders_skipped := volume_attributes.total_cylinders_skipped -
                previous_volume_attributes_p^.total_cylinders_skipped;
          new_volume_attributes.total_streamed_requests := volume_attributes.total_streamed_requests -
                previous_volume_attributes_p^.total_streamed_requests;
          new_volume_attributes.bytes_per_mau := volume_attributes.bytes_per_mau;
        IFEND;
        previous_volume_attributes_p^ := volume_attributes;
        volume_attributes := new_volume_attributes;
      IFEND;

    PROCEND p$build_volume_attribute_update;
?? OLDTITLE ??
?? NEWTITLE := 'p$format_total_attributes', EJECT ??

    PROCEDURE p$format_total_attributes
      (    total_attributes: t$total_attributes;
       VAR str: string (80));

      VAR
        avg_byte_count_per_request: integer,
        i: integer,
        qtime_read_requests: real,
        qtime_time_total_requests: integer,
        qtime_total_requests: real,
        qtime_write_requests: real,
        total_bytes: integer,
        total_read_requests: integer,
        total_requests: integer,
        total_seeks: integer,
        total_write_requests: integer;

      str := '';
      pmp$binary_to_ascii_fit (total_attributes.queue_count, 10, 4, 4, str (8, 4));

      total_read_requests := total_attributes.read_requests + total_attributes.swap_in_requests;
      total_write_requests := total_attributes.write_requests + total_attributes.swap_out_requests;
      total_requests := total_read_requests + total_write_requests;
      total_bytes := (total_attributes.read_mau_count + total_attributes.write_data_and_preset_maus +
            total_attributes.swap_in_mau_count + total_attributes.swap_out_data_and_preset_maus) *
            total_attributes.bytes_per_mau;
      total_seeks := total_requests - total_attributes.total_streamed_requests;

      qtime_time_total_requests := total_attributes.read_qtime + total_attributes.write_qtime +
            total_attributes.swap_in_qtime + total_attributes.swap_out_qtime;

      IF total_attributes.read_requests <> 0 THEN
        qtime_read_requests := $REAL (total_attributes.read_qtime) / $REAL (total_attributes.read_requests) /
              1000.0;
      ELSE
        qtime_read_requests := 0.0;
      IFEND;

      IF total_attributes.write_requests <> 0 THEN
        qtime_write_requests := $REAL (total_attributes.write_qtime) /
              $REAL (total_attributes.write_requests) / 1000.0;
      ELSE
        qtime_write_requests := 0.0;
      IFEND;

      IF total_requests <> 0 THEN
        qtime_total_requests := $REAL (qtime_time_total_requests) / $REAL (total_requests) / 1000.0;
        avg_byte_count_per_request := total_bytes DIV total_requests;
      ELSE
        qtime_total_requests := 0.0;
        avg_byte_count_per_request := 0;
      IFEND;

      pmp$binary_to_ascii_fit (total_read_requests, 10, 5, 5, str (13, 5));
      pmp$binary_to_ascii_fit (total_write_requests, 10, 5, 5, str (19, 5));
      pmp$binary_to_ascii_fit (total_requests, 10, 6, 6, str (25, 6));
      STRINGREP (str (31, 48), i, qtime_read_requests: 8: 2, qtime_write_requests: 8: 2,
            qtime_total_requests: 8: 2);
      pmp$binary_to_ascii_fit (avg_byte_count_per_request, 10, 5, 5, str (56, 5));
      pmp$binary_to_ascii_fit (total_seeks, 10, 6, 6, str (62, 5));
      pmp$binary_to_ascii_fit (total_attributes.requests_causing_skipped_cyl, 10, 6, 6, str (68, 5));
      pmp$binary_to_ascii_fit (total_attributes.total_cylinders_skipped, 10, 6, 6, str (74, 7));

    PROCEND p$format_total_attributes;
?? OLDTITLE ??
?? NEWTITLE := 'p$format_volume_attributes', EJECT ??

    PROCEDURE p$format_volume_attributes
      (    volume_attributes: t$volume_attributes;
       VAR str: string (80));

      VAR
        avg_byte_count_per_request: integer,
        i: integer,
        qtime_read_requests: real,
        qtime_time_total_requests: integer,
        qtime_total_requests: real,
        qtime_write_requests: real,
        total_bytes: integer,
        total_read_requests: integer,
        total_requests: integer,
        total_seeks: integer,
        total_write_requests: integer;

      str := volume_attributes.vsn;
      pmp$binary_to_ascii_fit (volume_attributes.queue_count, 10, 4, 4, str (8, 4));

      IF volume_attributes.available = FALSE THEN
        str (13, * ) := 'volume unavailable';
      ELSEIF volume_attributes.data_available = FALSE THEN
        str (13, * ) := 'volume statistic unavailable';
      ELSE
        total_read_requests := volume_attributes.read_requests + volume_attributes.swap_in_requests;
        total_write_requests := volume_attributes.write_requests + volume_attributes.swap_out_requests;
        total_requests := total_read_requests + total_write_requests;
        total_bytes := (volume_attributes.read_mau_count + volume_attributes.write_data_and_preset_maus +
              volume_attributes.swap_in_mau_count + volume_attributes.swap_out_data_and_preset_maus) *
              volume_attributes.bytes_per_mau;
        total_seeks := total_requests - volume_attributes.total_streamed_requests;

        qtime_time_total_requests := volume_attributes.read_qtime + volume_attributes.write_qtime +
              volume_attributes.swap_in_qtime + volume_attributes.swap_out_qtime;

        IF volume_attributes.read_requests <> 0 THEN
          qtime_read_requests := $REAL (volume_attributes.read_qtime) /
                $REAL (volume_attributes.read_requests) / 1000.0;
        ELSE
          qtime_read_requests := 0.0;
        IFEND;

        IF volume_attributes.write_requests <> 0 THEN
          qtime_write_requests := $REAL (volume_attributes.write_qtime) /
                $REAL (volume_attributes.write_requests) / 1000.0;
        ELSE
          qtime_write_requests := 0.0;
        IFEND;

        IF total_requests <> 0 THEN
          qtime_total_requests := $REAL (qtime_time_total_requests) / $REAL (total_requests) / 1000.0;
          avg_byte_count_per_request := total_bytes DIV total_requests;
        ELSE
          qtime_total_requests := 0.0;
          avg_byte_count_per_request := 0;
        IFEND;

        pmp$binary_to_ascii_fit (total_read_requests, 10, 5, 5, str (13, 5));
        pmp$binary_to_ascii_fit (total_write_requests, 10, 5, 5, str (19, 5));
        pmp$binary_to_ascii_fit (total_requests, 10, 6, 6, str (25, 6));
        STRINGREP (str (31, 48), i, qtime_read_requests: 8: 2, qtime_write_requests: 8: 2,
              qtime_total_requests: 8: 2);
        pmp$binary_to_ascii_fit (avg_byte_count_per_request, 10, 5, 5, str (56, 5));
        pmp$binary_to_ascii_fit (total_seeks, 10, 5, 5, str (62, 5));
        pmp$binary_to_ascii_fit (volume_attributes.requests_causing_skipped_cyl, 10, 5, 5, str (68, 5));
        pmp$binary_to_ascii_fit (volume_attributes.total_cylinders_skipped, 10, 7, 7, str (74, 7));
      IFEND;

    PROCEND p$format_volume_attributes;
?? OLDTITLE ??
?? NEWTITLE := 'p$get_volume_attributes', EJECT ??

    PROCEDURE p$get_volume_attributes
      (    avt_index: dmt$active_volume_table_index;
       VAR volume_attributes: t$volume_attributes);

      VAR
        allocation_info: dmt$allocation_info,
        entry_p: ^cmt$peripheral_element_entry,
        logical_unit_p: ^cmt$logical_unit,
        lun: iot$logical_unit,
        status: ost$status,
        unit_interface_entry_p: ^iot$unit_interface_table;

      volume_attributes := v$nil_volume_attributes;
      volume_attributes.vsn := dmv$active_volume_table.table_p^ [avt_index].mass_storage.recorded_vsn;
      IF dmv$active_volume_table.table_p^ [avt_index].mass_storage.volume_unavailable THEN
        RETURN; {----->
      IFEND;

      volume_attributes.available := TRUE;
      lun := dmv$active_volume_table.table_p^ [avt_index].logical_unit_number;
      logical_unit_p := ^cmv$logical_unit_table^ [lun];
      unit_interface_entry_p := logical_unit_p^.unit_interface_table;
      IF (logical_unit_p^.configured) AND (unit_interface_entry_p <> NIL) THEN
        volume_attributes.queue_count := unit_interface_entry_p^.queue_count;
      IFEND;

      IF (iov$disk_unit_usage_p <> NIL) AND (iov$disk_unit_usage_p^ [lun] <> NIL) THEN
        volume_attributes.data_available := TRUE;
        volume_attributes.read_requests := iov$disk_unit_usage_p^ [lun]^.read_requests;
        volume_attributes.read_qtime := iov$disk_unit_usage_p^ [lun]^.read_qtime;
        volume_attributes.read_mau_count := iov$disk_unit_usage_p^ [lun]^.read_mau_count;
        volume_attributes.write_requests := iov$disk_unit_usage_p^ [lun]^.write_requests;
        volume_attributes.write_qtime := iov$disk_unit_usage_p^ [lun]^.write_qtime;
        volume_attributes.write_data_and_preset_maus := iov$disk_unit_usage_p^ [lun]^.
              write_data_and_preset_maus;
        volume_attributes.swap_in_requests := iov$disk_unit_usage_p^ [lun]^.swap_in_requests;
        volume_attributes.swap_in_qtime := iov$disk_unit_usage_p^ [lun]^.swap_in_qtime;
        volume_attributes.swap_in_mau_count := iov$disk_unit_usage_p^ [lun]^.swap_in_mau_count;
        volume_attributes.swap_out_requests := iov$disk_unit_usage_p^ [lun]^.swap_out_requests;
        volume_attributes.swap_out_qtime := iov$disk_unit_usage_p^ [lun]^.swap_out_qtime;
        volume_attributes.swap_out_data_and_preset_maus := iov$disk_unit_usage_p^ [lun]^.
              swap_out_data_and_preset_maus;
        volume_attributes.requests_causing_skipped_cyl := iov$disk_unit_usage_p^ [lun]^.
              requests_causing_skipped_cyl;
        volume_attributes.total_cylinders_skipped := iov$disk_unit_usage_p^ [lun]^.total_cylinders_skipped;
        volume_attributes.total_streamed_requests := iov$disk_unit_usage_p^ [lun]^.streamed_req_count_read +
              iov$disk_unit_usage_p^ [lun]^.streamed_req_count_write;
        volume_attributes.bytes_per_mau := iov$disk_unit_usage_p^ [lun]^.bytes_per_mau;
      IFEND;

    PROCEND p$get_volume_attributes;
?? OLDTITLE ??
?? NEWTITLE := '[inline] p$put_line', EJECT ??

    PROCEDURE [INLINE] p$put_line
      (    str: string ( * <= 80));

      VAR
        status: ost$status;

      IF wid <> 0 THEN
        dpp$put_next_line (wid, str, status);
      ELSE
        clp$put_display (display_control, str, clc$trim, status);
      IFEND;

    PROCEND p$put_line;
?? OLDTITLE ??
?? EJECT ??

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

    IF NOT v$previous_data_for_display THEN
      ALLOCATE v$system_line_info IN osv$task_shared_heap^;
      ALLOCATE v$previous_stats_p: [LOWERBOUND (dmv$active_volume_table.
            table_p^) .. UPPERBOUND (dmv$active_volume_table.table_p^)] IN osv$task_shared_heap^;
      FOR avt_index := LOWERBOUND (dmv$active_volume_table.table_p^)
            TO UPPERBOUND (dmv$active_volume_table.table_p^) DO
        v$previous_stats_p^ [avt_index] := NIL;
      FOREND;

      v$system_line_info^.initialized := FALSE;
      v$previous_data_for_display := TRUE;
    IFEND;

    ofp$build_system_line (v$system_line_info^, str);
    IF wid <> 0 THEN
      dpp$clear_window (wid, status);
    IFEND;

    p$put_line (str);
    p$put_line ('');
    p$put_line (c$title_1);
    p$put_line (c$title_2);
    p$put_line (c$title_3);

    IF ofc$msdi_classes_out_of_space IN ofv$mass_storage_display_infos [ofc$ved_msu].display_options.
          values THEN
      PUSH out_of_space_sets_p: [1 .. UPPERBOUND (dmv$active_volume_table.table_p^) + 1];
      dmp$get_out_of_space_sets (out_of_space_sets_p^, set_count);

      FOR index := 1 TO set_count DO
        set_name := out_of_space_sets_p^ [index].set_name;
        classes := out_of_space_sets_p^ [index].classes;
        IF (classes <> $dmt$class []) THEN
          IF (set_name = osc$null_name) THEN
            STRINGREP (str, string_length, ' Classes out of space:');
          ELSE
            name_length := STRLENGTH (set_name);
            WHILE (name_length > 0) AND (set_name (name_length) = ' ') DO
              name_length := name_length - 1;
            WHILEND;
            STRINGREP (str, string_length, ' ', set_name (1, name_length), ' classes out of space:');
          IFEND;
          class_index := string_length + 1;

          FOR class := LOWERVALUE (dmt$class_member) TO UPPERVALUE (dmt$class_member) DO
            IF class IN classes THEN
              IF (class_index >= STRLENGTH (str)) THEN
                p$put_line (str (1, class_index - 1));
                str (1, string_length) := ' ';
                class_index := string_length + 1;
              IFEND;
              str (class_index, 1) := ' ';
              str (class_index + 1, 1) := $CHAR ($INTEGER (class));
              class_index := class_index + 2;
            IFEND;
          FOREND;

          p$put_line (str (1, class_index - 1));
        IFEND;
      FOREND;
    IFEND;

    IF ofc$msdi_crit_class_added_count IN ofv$mass_storage_display_infos [ofc$ved_msu].display_options.
          values THEN
      IF dmv$q_devices_added <> 0 THEN
        STRINGREP (str, string_length, ' Class Q devices automatically added: ', dmv$q_devices_added);
        p$put_line (str (1, string_length));
      IFEND;
    IFEND;

    control.last_used_index := 0;
    control.sort_option_p := ^ofv$mass_storage_display_infos [ofc$ved_msu].sort_option;
    IF (control.sort_option_p^.key = ofc$msdi_user_defined)
{ } AND (control.sort_option_p^.display_omitted_units) THEN
      PUSH control.avt_entries_displayed_p: [LOWERBOUND (dmv$active_volume_table.
            table_p^) .. UPPERBOUND (dmv$active_volume_table.table_p^)];
      FOR avt_index := LOWERBOUND (control.avt_entries_displayed_p^)
            TO UPPERBOUND (control.avt_entries_displayed_p^) DO
        control.avt_entries_displayed_p^ [avt_index] := FALSE;
      FOREND;
    ELSE
      control.avt_entries_displayed_p := NIL;
    IFEND;

    total_attributes := v$nil_total_attributes;

    REPEAT
      ofp$get_next_avt_index (control, avt_index, eot);
      IF NOT eot THEN
        p$get_volume_attributes (avt_index, volume_attributes);

{       IF ofc$msdi_total IN ofv$mass_storage_display_infos [ofc$ved_msu].display_options.values THEN
        p$build_volume_attribute_update (v$previous_stats_p^ [avt_index], volume_attributes);
{       IFEND;

        IF ofc$msdi_total IN ofv$mass_storage_display_infos [ofc$ved_msu].display_options.values THEN
          p$build_total_attributes (volume_attributes, total_attributes);
        IFEND;

        p$format_volume_attributes (volume_attributes, str);
        p$put_line (str);
      IFEND;
    UNTIL eot;

    IF ofc$msdi_total IN ofv$mass_storage_display_infos [ofc$ved_msu].display_options.values THEN
      p$put_line (c$title_3);
      p$format_total_attributes (total_attributes, str);
      p$put_line (str);
    IFEND;

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

  PROCEND ofp$mass_storage_usage_display;
?? OLDTITLE ??
MODEND ofm$mass_storage_usage_display;
