?? RIGHT := 110 ??
?? NEWTITLE := ' NOS/VE File Server: log_esm_data ', EJECT ??
MODULE dfm$log_esm_data;
{
{  This module contains the processes which construct the Engineering log entry
{  for ESM/Stornet failure data.
{
?? TITLE := '    Global Declarations ', EJECT ??
*copyc dft$esm_log_data
*copyc ost$status
*copyc cml$5380_100_lsp_failure_data
*copyc cml$7040_200_lsp_failure_data
*copyc dfc$esm_driver_error_codes
*copyc oss$job_paged_literal
*copyc dfi$console_display
*copyc cmp$get_element_definition
*copyc cmp$get_element_name_via_lun
*copyc cmp$return_desc_data_by_lun_lpn
*copyc sfp$activate_system_statistic
*copyc sfp$emit_statistic
?? TITLE := '    [XDCL] dfp$log_esm_data', EJECT ??
  PROCEDURE [XDCL] dfp$log_esm_data (p_data: ^SEQ ( * );
    VAR status: ost$status);


    VAR
      counters_p: ^array [1 .. * ] of sft$counter,
      data_p: ^SEQ ( * ),
      descriptor_data: ost$string,
      element_definition: cmt$element_definition,
      element_descriptor: cmt$element_descriptor,
      esm_log_data_p: ^dft$esm_log_data,
      iou_number: dst$iou_number,
      length: integer,
      logical_unit: iot$logical_unit,
      phy_pp_number: 0 .. 31,
      pp_number: iot$pp_number,
      seq_p: ^SEQ ( * ),
      statistic_code: sft$statistic_code,
      statistics_established: [STATIC] boolean := FALSE,
      stornet_product_id: [READ, oss$job_paged_literal] cmt$product_identification
            := [' $5380', '_', '100'],
      symptom_code: integer;


    status.normal := TRUE;
    IF NOT statistics_established THEN
      establish_statistics (status);
      IF status.normal THEN
        statistics_established := TRUE;
      ELSE
        RETURN;
      IFEND;
    IFEND;

    data_p := p_data;
    NEXT esm_log_data_p IN data_p;
    pp_number := esm_log_data_p^.pp_number;
    logical_unit := esm_log_data_p^.logical_unit;

{ Get product_id.
    cmp$get_element_name_via_lun (logical_unit,
        element_descriptor.peripheral_descriptor.element_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    element_descriptor.element_type := cmc$communications_element;
    element_descriptor.peripheral_descriptor.use_logical_identification := TRUE;
    cmp$get_element_definition (element_descriptor, element_definition, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Get descriptor data.
    cmp$return_desc_data_by_lun_lpn (logical_unit, pp_number, iou_number, descriptor_data, phy_pp_number);

    length := 21;

    PUSH counters_p: [1 .. length];

    {   Set counter [1] to the PP number. Set bit 57 for an I4 concurrent PP.
    {                                     Set bits 46 - 51 to IOU number.
    {   Set counter [2] to the Channel number.  Set bit 57 if an I4 concurrent channel.
    {                                           Set bit 56 if I4 concurrent PORT B.
    {                                           Set bit 55 if I4 concurrent PORT A.
    {                                           Set bits 46 - 51 to IOU number.
    IF esm_log_data_p^.channel.concurrent THEN
      counters_p^ [1] := pp_number + 40(16);
      IF esm_log_data_p^.channel.port = cmc$port_a THEN
        counters_p^ [2] := esm_log_data_p^.channel.number + 40(16) + 100(16);
      ELSE {port_b
        counters_p^ [2] := esm_log_data_p^.channel.number + 40(16) + 80(16);
      IFEND;
    ELSE
      counters_p^ [1] := pp_number;
      counters_p^ [2] := esm_log_data_p^.channel.number;
    IFEND;
    counters_p^ [1] := counters_p^ [1] + iou_number * 1000(16);
    counters_p^ [2] := counters_p^ [2] + iou_number * 1000(16);

    counters_p^ [3] := 0;
    counters_p^ [4] := 0;

    IF element_definition.product_id = stornet_product_id THEN
      counters_p^ [5] := 1;
      statistic_code := cml$5380_100_lsp_failure_data;
    ELSE
      counters_p^ [5] := 0;
      statistic_code := cml$7040_200_lsp_failure_data;
    IFEND;

    counters_p^ [6] := 1;  {logical operation always READ}

    IF esm_log_data_p^.error_log_response.flags.unrecovered_error THEN
      counters_p^ [7] := 1;
    ELSE
      counters_p^ [7] := 0;
    IFEND;

    counters_p^ [8] := esm_log_data_p^.error_log_response.error_condition;

    counters_p^ [9] := esm_log_data_p^.error_log_response.retry_count;

    counters_p^ [10] := esm_log_data_p^.error_log_response.esm_address;

    counters_p^ [11] := esm_log_data_p^.error_log_response.transfer_byte_count DIV 8;

    counters_p^ [12] := 0; {Unused}

    counters_p^ [13] := esm_log_data_p^.error_log_response.last_ch_function;

    counters_p^ [14] := esm_log_data_p^.error_log_response.residual_byte_count;

    counters_p^ [15] := esm_log_data_p^.error_log_response.esm_lsp_status;

    IF esm_log_data_p^.error_log_response.flags.c170_dma_adapter AND
       esm_log_data_p^.error_log_response.flags.executing_adapter_io THEN
      IF esm_log_data_p^.error_log_response.flags.adapter_t_register_loaded THEN
        counters_p^ [16] := (esm_log_data_p^.error_log_response.initial_adapter_t_register
           .byte_count * 100000000(16)) + esm_log_data_p^.error_log_response
           .initial_adapter_t_register.cm_address;
        counters_p^ [21] := (esm_log_data_p^.error_log_response.adapter_t_register.byte_count * 100000000(16))
            + esm_log_data_p^.error_log_response.adapter_t_register.cm_address;
      ELSE
        counters_p^ [16] := -1;
        counters_p^ [21] := -1;
      IFEND;
      counters_p^ [17] := esm_log_data_p^.error_log_response.adapter_control_register;
      counters_p^ [18] := esm_log_data_p^.error_log_response.adapter_op_status_register;
      counters_p^ [19] := esm_log_data_p^.error_log_response.adapter_error_status;
      counters_p^ [20] := 2; {PP word counter always 2}
    ELSE { Driver not C170 DMA Adapter mode.
      counters_p^ [16] := -1;
      counters_p^ [17] := -1;
      counters_p^ [18] := -1;
      counters_p^ [19] := -1;
      counters_p^ [20] := -1;
      counters_p^ [21] := -1;
    IFEND;

    emit_statistic (statistic_code, counters_p, descriptor_data, esm_log_data_p, status);

  PROCEND dfp$log_esm_data;
?? TITLE := '    emit_statistic', EJECT ??
  PROCEDURE emit_statistic
    (    statistic_code: sft$statistic_code;
         counters_p: ^array [1 .. * ] OF sft$counter;
         descriptor_data: ost$string;
         esm_log_data_p: ^dft$esm_log_data;
     VAR status: ost$status);


    VAR
      k: integer,
      m_length: integer,
      message_p: ^string ( * ),
      size: integer;


    status.normal := TRUE;

{ Combine descriptor data with class and symptom message.

    size := descriptor_data.size;
    m_length := size + 4 + dfc$symptom_message_length;
    PUSH message_p: [m_length];
    message_p^ (1, size) := descriptor_data.value;
    k := size + 1;
    CASE counters_p^ [7] OF
    = 0 =
      message_p^ (k, 4) := '.RF.';
    = 1 =
      message_p^ (k, 4) := '.UF.';
    ELSE
    CASEND;
    k := k + 4;
    message_p^ (k, * ) := esm_log_data_p^.symptom_message;
    IF counters_p^ [5] = 1 THEN
      message_p^ (k+6 , 4) := '7302'; {element id was $5380_100}
    ELSE
      message_p^ (k+6 , 4) := '7303'; {element id was $7040_200}
    IFEND;

    sfp$emit_statistic (statistic_code, message_p^, counters_p, status);

    display_to_console (message_p^);

  PROCEND emit_statistic;
?? TITLE := '    establish_statistics ', EJECT ??
  PROCEDURE establish_statistics (VAR status: ost$status);

    CONST
      number_of_statistics = 2;

    VAR
      statistics: array [1 .. number_of_statistics] of sft$statistic_code,
      i: integer;


    statistics [1] := cml$5380_100_lsp_failure_data;
    statistics [2] := cml$7040_200_lsp_failure_data;

    FOR i := 1 TO number_of_statistics DO
      sfp$activate_system_statistic (statistics [i], $sft$binary_logset [pmc$engineering_log], status);
      IF status.normal = FALSE THEN
        RETURN;
      IFEND;
    FOREND;

  PROCEND establish_statistics;

MODEND dfm$log_esm_data;
