?? RIGHT := 110 ??
?? NEWTITLE := ' NOS/VE File Server: process_server_response ', EJECT ??
MODULE dfm$process_server_response;
{
{  This module contains the file server PP resquest response handlers.
{
?? NEWTITLE := 'Global Declarations Referenced By This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc dfs$server_wired
*copyc oss$mainframe_wired
*copyc dfc$client_pause_break
*copyc dfc$client_terminate_break
*copyc dfc$esm_driver_error_codes
*copyc dfc$poll_constants
*copyc dfc$test_jr_constants
*copyc tmc$signal_identifiers
*copyc dfd$driver_queue_types
*copyc dfd$request_package
*copyc dfe$error_condition_codes
*copyc ioe$st_errors
*copyc mme$condition_codes
*copyc dft$cpu_queue
*copyc dft$esm_log_data
*copyc dft$fs_error_log_response
*copyc dft$fs_pp_response
*copyc dft$inquiry_message
*copyc dft$one_word_response_handler
*copyc dft$page_io_request
*copyc dft$page_io_response
*copyc dft$server_descriptor
*copyc dft$transaction_state
*copyc dmt$disk_file_descriptor
*copyc iot$disk_request
*copyc iot$pp_interface_table
*copyc pmt$condition_name
*copyc syt$monitor_status
?? POP ??
*copyc i#test_set_bit
*copyc dfp$convert_list_pointer
*copyc dfp$convert_p_io_request_to_qit
*copyc dfp$determine_action_for_server
*copyc dfp$fetch_queue_entry
*copyc dfp$form_inquiry_tracer
*copyc dfp$get_served_file_desc_p
*copyc dfp$queue_inquiry_request
*copyc dfp$queue_request
*copyc dfp$record_transaction_data
*copyc dfp$release_queue_entry
*copyc dmp$get_disk_file_descriptor_p
*copyc dpp$convert_int_to_str_dec
*copyc dpp$display_error
*copyc dsp$report_system_message
*copyc gfp$mtr_get_fde_p
*copyc mmp$mtr_process_io_completion
*copyc mmp$mtr_process_server_complete
*copyc mmp$unlock_rma_list
*copyc mtp$cst_p
*copyc mtp$error_stop
*copyc syp$mtr_hang_if_system_jrt_set
*copyc tmp$check_taskid
*copyc tmp$send_signal
*copyc tmp$set_task_ready
*copyc cmv$logical_pp_table_p
*copyc cmv$logical_unit_table
*copyc dfi$monitor_display
*copyc dfv$file_server_debug_enabled
*copyc jmv$ijl_p
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared By This Module', EJECT ??

{ The following variables provide for testing of File Server retransmission.
{ Value must be set via the Core Debugger.
{   dfv$force_retran_interval     - Time interval in minutes between simulation
{                                   of ESM I/O errors. This value must be non-zero
{                                   to enable testing.
{   dfv$force_retran_qe_type      - This value specifies the type of queue entry
{                                   for which failures will be forced.
{                                     0 = EITHER_QE, Task or Monitor queue entry type.
{                                     1 = TASK_QE, Task queue entry type only.
{                                     2 = MONITOR_QE, Monitor queue entry type only.
{   dfv$force_retran_failure_side - This value specifies the side on which failures
{                                   failures will be forced. Code must be enabled on
{                                   on side failure is to occur.
{                                     0 = FAIL_EITHER client or server side (loop back).
{                                     1 = FAIL_CLIENT side only.
{                                     2 = FAIL_SERVER side only.
{   dfv$force_retran_failure_item - This value specifies the message element on
{                                   which the simulated error is to occur.
{                                     0 = HEADER_ERR, driver's message header which
{                                         allows identification of the queue and
{                                         queue entry to which the message belongs.
{                                     1 = BUFFER_ERR, the Command or Response portion
{                                         of the file server transaction.
{                                     2 = DATA_ERR, the file page data portion of
{                                         the file server transaction.
{
{ To set values for the force retransmission variables enter :
{   1. at critical window      -    SYSDEBUG 0
{   2. in core debugger window -    CM variable_name value number_of_bytes
{      where variable_name   = one of the force retransmission variable names.
{            value           = 0 thru 2.
{            number_of_bytes = 1 (all are one byte fields).
{   3. in core debugger window -    RUN
{
{ The variable dfv$previous_force_retran_time is used in code to determine
{ elapsed time since the previous forced retransmission. In the code which
{ uses this value, if it is found to be zero it is set to the current time,
{ otherwise it is set to the current time each time a retransmission is forced.

  VAR
    dfv$previous_force_retran_time: [XDCL,#GATE, dfs$server_wired] integer := 0,
    dfv$force_retran_interval: [XDCL, #GATE, dfs$server_wired] 0 .. 0ff(16) := 0,
    dfv$force_retran_qe_type: [XDCL, #GATE, dfs$server_wired]
        (dfc$either_qe, dfc$task_qe, dfc$monitor_qe) := dfc$monitor_qe,
    dfv$force_retran_failure_side: [XDCL, #GATE, dfs$server_wired]
        (dfc$fail_either, dfc$fail_client, dfc$fail_server) := dfc$fail_either,
    dfv$force_retran_failure_item: [XDCL, #GATE, dfs$server_wired]
        (dfc$header_err, dfc$buffer_err, dfc$data_err) := dfc$header_err;


  VAR
    dfv$null_global_task_id: [XDCL, #GATE] ost$global_task_id := [0, 0];

  VAR
    dfv$one_word_response_handler: [XDCL, STATIC, #GATE, OSS$MAINFRAME_WIRED]
          dft$one_word_response_handler := ^dfp$process_server_response;

  VAR
    dfv$process_multiword_response: [XDCL, STATIC, #GATE, OSS$MAINFRAME_WIRED]
          iot$response_processor := ^dfp$process_multiword_response;

?? TITLE := '    [XDCL] dfp$process_server_response', EJECT ??
  PROCEDURE [XDCL] dfp$process_server_response
    (    one_word_response_p: ^dft$fs_pp_response;
         pp_number: 1 .. ioc$pp_count;
     VAR status: syt$monitor_status);

    {
    {  This procedure executes in the Monitor and is called to process responses
    {  from the File Server's PP driver.
    {
    {  It consists of the interface between iop$process_io_completions and
    {  dfp$process_server_response_a. The latter procedure was generated in
    {  order that server termination could have an entry point which did not
    {  depend upon the value of the logical unit in the one word response.

    VAR
      p_queue_interface_table: dft$p_queue_interface_table;

    IF cmv$logical_unit_table^ [one_word_response_p^.logical_unit].unit_interface_table = NIL THEN

{ We've encountered an artifact of a server pp response which is no longer valid.  Simply return.

      RETURN;
    IFEND;

    dfp$convert_p_io_request_to_qit (
        cmv$logical_unit_table^ [one_word_response_p^.logical_unit].
        unit_interface_table^.next_request, p_queue_interface_table);
    dfp$process_server_response_a (one_word_response_p, p_queue_interface_table, status);

  PROCEND dfp$process_server_response;

?? TITLE := '    [XDCL] dfp$process_server_response_a', EJECT ??
  PROCEDURE [XDCL] dfp$process_server_response_a
    (    one_word_response_p: ^dft$fs_pp_response;
         p_queue_interface_table: dft$p_queue_interface_table;
     VAR status: syt$monitor_status);

    {  This procedure is a continuation of dfp$process_server_response as well as
    {  being an entry point when the queue interface table is known but the logical
    {  unit number may not be.
    {
    {  The response_flags portion of the fs_pp_response are as follows -
    {
    {   SPECIAL_RESPONSE - This flag is detected by iom$process_io_completions
    {          which calls the response processor specified in the logical unit
    {          table. File Server that procedure is dfp$process_server_response.
    {
    {   ONE_WORD_RESPONSE - This flag indicates that the response is eight bytes
    {          in length (one CM word). These responses are processed in this
    {          procedure.
    {
    {   ERROR_RESPONSE - The response is due to an abnormal condition detected
    {          by the File Server's PP driver on processing a noninquiry message
    {          request. The response_parameter field of the one_word_response
    {          contains the condition code.
    {
    {   INQUIRY_RESPONSE - The response is due to an inquiry_message request.
    {          The response_parameter field of the one_word_response contains
    {          the inquiry_message.
    {
    {   TERMINATION_PSEUDO_RESPONSE - Indicates dfp$process_server_response_a has
    {          been called directly as part of termination processing. The response
    {          is not contained in the PP response buffer and does not contain a
    {          valid logical unit number.

    TYPE
      dft$connection_side = (server_side, client_side, unknown_side);

    VAR
      action_for_server: dft$action_for_server,
      connection_side: dft$connection_side,
      cst_p: ^ost$cpu_state_table,
      current_time: integer,
      dfd_p: ^dmt$disk_file_descriptor,
      elapsed_time: integer,
      io_error: iot$io_error,
      io_status: syt$monitor_status,
      io_type: iot$io_function,
      local_priority: jmt$dispatching_priority,
      local_task_id: ost$global_task_id,
      m_status: syt$monitor_status,
      normal: boolean,
      p_buffer_header: ^dft$buffer_header,
      p_cpu_queue_entry: ^dft$cpu_queue_entry,
      p_driver_queue_entry: ^dft$driver_queue_entry,
      p_fde: gft$file_desc_entry_p,
      p_fs_pp_response: ^dft$fs_pp_response,
      p_page_io_response: ^dft$page_io_response,
      p_page_io_request: ^dft$page_io_request,
      p_rma_list: ^mmt$rma_list,
      p_server_descriptor: dft$server_descriptor_p,
      p_status_response: ^dft$status_response,
      queue_entry_index: dft$queue_entry_index,
      queue_index: dft$queue_index,
      queue_release_status: dft$release_queue_entry_status,
      remote_request: dft$remote_request;

    status.normal := TRUE;

    queue_index := one_word_response_p^.queue_index;
    queue_entry_index := one_word_response_p^.queue_entry_index;

    IF (queue_entry_index <> 0) AND (queue_index <> 0) THEN
      { one word PP response is associated with a known queue entry.
      dfp$fetch_queue_entry (p_queue_interface_table, queue_index,
          queue_entry_index, p_driver_queue_entry, p_cpu_queue_entry);

      IF (p_queue_interface_table^.queue_directory.driver_queue_pva_directory [queue_index].
          p_driver_queue^.queue_header.flags.idle) AND
         (NOT one_word_response_p^.response_flags.termination_pseudo_response) THEN
        { QUEUE IS IDLE, IGNORE PP RESPONSES.
        p_driver_queue_entry^.flags.process_response := FALSE;
        IF dfv$file_server_debug_enabled THEN
          dpp$display_error ('DF - INFORMATIVE, PRO_S_R - QUEUE IS IDLE, IGNORE PP RESPONSE.');
        IFEND;
        RETURN;
      IFEND;

      IF p_queue_interface_table^.queue_directory.driver_queue_pva_directory [queue_index].
           p_driver_queue^.queue_header.connection_descriptor.source.flags.server_to_client THEN
        connection_side := server_side;
      ELSE
        connection_side := client_side;
      IFEND;
    ELSE
      connection_side := unknown_side;
    IFEND;


{   This code provided for testing File Server Retransmission logic.
{   The variable dfv$force_retran_interval must be set non-zero via the
{   Core Debugger to enable execution of this test code.

    IF dfv$force_retran_interval > 0 THEN
      IF dfv$previous_force_retran_time = 0 THEN
        dfv$previous_force_retran_time := #FREE_RUNNING_CLOCK (0);
      ELSE
        current_time := #FREE_RUNNING_CLOCK (0);
        elapsed_time := current_time - dfv$previous_force_retran_time;
        IF (elapsed_time >= dfv$force_retran_interval * 60000000)
           AND (NOT one_word_response_p^.response_flags.error_response) THEN
          IF ((connection_side = client_side) AND (dfv$force_retran_failure_side = dfc$fail_client))
             OR ((connection_side = server_side) AND (dfv$force_retran_failure_side = dfc$fail_server))
             OR ((connection_side <> unknown_side) AND (dfv$force_retran_failure_side = dfc$fail_either)) THEN

            IF ((p_cpu_queue_entry^.processor_type = dfc$task_services) AND
                   (dfv$force_retran_qe_type = dfc$task_qe))
               OR ((p_cpu_queue_entry^.processor_type = dfc$monitor) AND
                   (dfv$force_retran_qe_type = dfc$monitor_qe))
               OR (dfv$force_retran_qe_type = dfc$either_qe) THEN

              CASE dfv$force_retran_failure_item OF
              = DFC$HEADER_ERR =
                IF ((p_driver_queue_entry^.flags.buffer_received) AND
                    (NOT p_driver_queue_entry^.flags.data_received))
                   OR one_word_response_p^.response_flags.inquiry_response THEN

                  IF one_word_response_p^.response_flags.inquiry_response THEN
                    dpp$display_error ('DF - TST RETRAN, PRETEND DRIVER FAILED ON INQUIRY MESSAGE.');
                  ELSE
                    p_driver_queue_entry^.held_over_esm_division_number := 0;
                    p_driver_queue_entry^.held_over_cm_word_count := 0;
                    p_driver_queue_entry^.flags.buffer_received := FALSE;
                    p_driver_queue_entry^.flags.process_response := FALSE;
                    dpp$display_error ('DF - TST RETRAN, PRETEND DRIVER FAILED ON HEADER.');
                  IFEND;
                  display_integer_monitor ('       QUEUE INDEX = ', queue_index);
                  display_integer_monitor ('       QUEUE ENTRY = ', queue_entry_index);
                  one_word_response_p^.response_flags.error_response := TRUE;
                  one_word_response_p^.response_parameter.error_condition := dfc$esm_double_bit_parity_error;
                  connection_side := unknown_side;
                  dfv$previous_force_retran_time := #FREE_RUNNING_CLOCK (0);
                IFEND;

              = DFC$BUFFER_ERR =
                IF (p_driver_queue_entry^.flags.buffer_received) AND
                   (NOT p_driver_queue_entry^.flags.data_received) THEN
                  dpp$display_error ('DF - TST RETRAN, PRETEND DRIVER FAILED ON BUFFER.');
                  display_integer_monitor ('       QUEUE INDEX = ', queue_index);
                  display_integer_monitor ('       QUEUE ENTRY = ', queue_entry_index);
                  p_driver_queue_entry^.flags.driver_error_alert := TRUE;
                  p_driver_queue_entry^.flags.buffer_received := FALSE;
                  p_driver_queue_entry^.held_over_esm_division_number := 0;
                  p_driver_queue_entry^.held_over_cm_word_count := 0;
                  one_word_response_p^.response_flags.error_response := TRUE;
                  one_word_response_p^.response_parameter.error_condition := dfc$esm_double_bit_parity_error;
                  p_driver_queue_entry^.error_condition := dfc$esm_double_bit_parity_error;
                  dfv$previous_force_retran_time := #FREE_RUNNING_CLOCK (0);
                IFEND;

              = DFC$DATA_ERR =
                IF p_driver_queue_entry^.flags.data_received THEN
                  dpp$display_error ('DF - TST RETRAN, PRETEND DRIVER FAILED ON DATA.');
                  display_integer_monitor ('       QUEUE INDEX = ', queue_index);
                  display_integer_monitor ('       QUEUE ENTRY = ', queue_entry_index);
                  p_driver_queue_entry^.flags.driver_error_alert := TRUE;
                  p_driver_queue_entry^.flags.data_received := FALSE;
                  p_driver_queue_entry^.held_over_esm_division_number := 0;
                  p_driver_queue_entry^.held_over_cm_word_count := 0;
                  one_word_response_p^.response_flags.error_response := TRUE;
                  one_word_response_p^.response_parameter.error_condition := dfc$esm_double_bit_parity_error;
                  p_driver_queue_entry^.error_condition := dfc$esm_double_bit_parity_error;
                  dfv$previous_force_retran_time := #FREE_RUNNING_CLOCK (0);
                IFEND;

              ELSE
                ;
              CASEND;
            IFEND;
          IFEND;
        IFEND;
      IFEND;
    IFEND; { End Of Retransmission Test Code.}


    IF one_word_response_p^.response_flags.error_response THEN
      IF dfv$file_server_debug_enabled THEN
        display_integer_monitor ('DF - INFORMATIVE, PRO_S_R - ERROR CONDITION ', $integer (
          one_word_response_p^.response_parameter.error_condition));
        IF one_word_response_p^.response_flags.inquiry_response THEN
          dpp$display_error ('DF - IGNORE ERROR ON INQUIRY MESSAGE');
        IFEND;
        display_integer_monitor ('DF - QUEUE INDEX', queue_index);
        display_integer_monitor ('DF - QUEUE ENTRY INDEX ' , queue_entry_index);
      IFEND;
      CASE one_word_response_p^.response_parameter.error_condition OF
      = dfc$invalid_command_code, dfc$invalid_length_in_command, dfc$invalid_address_in_command,
        dfc$invalid_length_in_ind_list, dfc$invalid_address_in_ind_list, dfc$reserved_field_not_zero,
        dfc$pit_lockword_error, dfc$no_held_info_in_queue_entry, dfc$invalid_queue_index,
        dfc$invalid_queue_entry_index, dfc$insufficient_length_spec,
        dfc$esm_address_overflow, dfc$invalid_driver_queue_rma,
        dfc$unused_reserved_46, dfc$unused_reserved_47, dfc$unused_reserved_48, dfc$unused_reserved_49 =
        { Interface Error Condition.
        display_integer_monitor (' Server interface error ', $INTEGER
               (one_word_response_p^.response_parameter.error_condition));
        IF dfv$file_server_debug_enabled THEN
          IF one_word_response_p^.response_flags.inquiry_response THEN
            RETURN;
          IFEND;
          mtp$error_stop ('DF - PRO_S_R, FILE SERVER DRIVER INTERFACE ERROR DETECTED');
        IFEND;
        IF connection_side = unknown_side THEN
          dpp$display_error (' File Server Interface Error detected on unknown connection.');
          RETURN;
        IFEND;
        IF (p_queue_interface_table^.queue_directory.cpu_queue_pva_directory [queue_index].
              p_cpu_queue^.queue_header.partner_status.server_state = dfc$active) THEN
          p_queue_interface_table^.queue_directory.cpu_queue_pva_directory [queue_index].
                p_cpu_queue^.queue_header.partner_status.timeout_partner := TRUE;
          dpp$display_error (' Timing Out File Server because Interface Error Condition');
        IFEND;
        RETURN;

      = dfc$function_timeout, dfc$iou_channel_parity_error, dfc$esm_channel_parity_error,
        dfc$esm_double_bit_parity_error, dfc$esm_address_parity_error, dfc$esm_flag_operation_abort,
        dfc$adp_uncorrected_cm_error, dfc$adp_cm_reject, dfc$adp_invalid_cm_response,
        dfc$adp_cm_response_parity_err, dfc$adp_cmi_read_parity_err, dfc$adp_clock_fault,
        dfc$adp_input_buffer_overflow, dfc$adp_input_data_parity_error, dfc$adp_12_16_conversion_error,
        dfc$adp_jy_data_parity_error, dfc$adp_kx_pp_data_parity_error, dfc$adp_kz_board_detected_error,
        dfc$adp_jy_board_detected_error, dfc$adp_kx_board_detected_error,
        dfc$channel_inactive_error, dfc$dma_xfer_halted_early,
        dfc$destination_machine_down, dfc$inactive_queue_entry, dfc$driver_action_flag_not_set,
        dfc$lsp_deadman_timeout,
        dfc$unused_reserved_25, dfc$unused_reserved_26,
        dfc$unused_reserved_27, dfc$unused_reserved_28, dfc$unused_reserved_29,
        dfc$queue_idle =
        IF dfv$file_server_debug_enabled THEN
          CASE one_word_response_p^.response_parameter.error_condition OF
          = dfc$destination_machine_down, dfc$inactive_queue_entry,
            dfc$driver_action_flag_not_set, dfc$queue_idle =
            dpp$display_error ('DF - INFORMATIVE, PRO_S_R - FILE_SERVER INACTIVE INTERFACE DETECTED');
          ELSE
            dpp$display_error ('DF - INFORMATIVE, PRO_S_R - FILE SERVER MEDIA ERROR DETECTED.');
          CASEND;
        IFEND;

        { Determine action to be taken after error.
        { No driver queue flags set by driver for inquiry messages.
        IF one_word_response_p^.response_flags.inquiry_response THEN
          IF one_word_response_p^.response_parameter.error_condition =
             dfc$destination_machine_down THEN
            IF (p_queue_interface_table^.queue_directory.cpu_queue_pva_directory [queue_index].
                p_cpu_queue^.queue_header.partner_status.server_state = dfc$active) THEN
              p_queue_interface_table^.queue_directory.cpu_queue_pva_directory [queue_index].
                  p_cpu_queue^.queue_header.partner_status.timeout_partner := TRUE;
              dpp$display_error (' Timeout File Server because destination mainframe down');
            IFEND;
          IFEND;
{         With the exception of dfc$destination_machine_down,
{         No action taken on failures detected while processing inquiries.
          RETURN;
        IFEND;

        CASE one_word_response_p^.response_parameter.error_condition OF
        = dfc$destination_machine_down =
          IF (p_queue_interface_table^.queue_directory.cpu_queue_pva_directory [queue_index].
                p_cpu_queue^.queue_header.partner_status.server_state = dfc$active) THEN
            p_queue_interface_table^.queue_directory.cpu_queue_pva_directory [queue_index].
                  p_cpu_queue^.queue_header.partner_status.timeout_partner := TRUE;
            dpp$display_error (' Timeout File Server because destination mainframe down');
          IFEND;
{         Continue processing at CLIENT_SIDE/SERVER_SIDE case.

        = dfc$inactive_queue_entry, dfc$queue_idle, dfc$driver_action_flag_not_set =
{         Driver does not update queue_entry on these errors.
          RETURN;
        ELSE
        CASEND;

        CASE connection_side OF
        = CLIENT_SIDE =
          p_driver_queue_entry^.flags.process_response := FALSE;
          p_cpu_queue_entry^.transaction_state := dfc$media_error;
          CASE one_word_response_p^.response_parameter.error_condition OF
          = dfc$destination_machine_down =
            { Allow request timeout process to detect media error state and
            { attempt retransmission. Retransmission count will be reset for
            { initial POLL message so client waits for server to become active.
            RETURN;
          ELSE
            { Attempt immediate retransmission.
            dfp$retransmit_request (p_queue_interface_table, queue_index,
                queue_entry_index, p_cpu_queue_entry, p_driver_queue_entry);
            RETURN;
          CASEND;
        = SERVER_SIDE =
          p_cpu_queue_entry^.transaction_state := dfc$media_error;
          { Check if data pages to release.
          IF p_driver_queue_entry^.data_descriptor.actual_length = 0 THEN
            p_driver_queue_entry^.flags.process_response := FALSE;
            RETURN;
          { ELSE must do complete request processing to release pages.
          IFEND;
        = UNKNOWN_SIDE =
          IF dfv$file_server_debug_enabled THEN
            CASE one_word_response_p^.response_parameter.error_condition OF
            = dfc$inactive_queue_entry, dfc$queue_idle, dfc$driver_action_flag_not_set =
              dpp$display_error ('DF - INFORMATIVE, PRO_S_R - QI=0, FS INACTIVE INTERFACE DETECTED');
            ELSE
              dpp$display_error ('DF - INFORMATIVE, PRO_S_R - QI=0, FS MEDIA ERROR DETECTED.');
            CASEND;
          IFEND;
          RETURN;
        ELSE
          ;
        CASEND;
      ELSE { Case error condition unknown.
        IF dfv$file_server_debug_enabled THEN
          dpp$display_error ('DF - INFORMATIVE, PRO_S_R - UNDETERMINED FS DRIVER ERROR REPORTED');
        IFEND;
        RETURN;
      CASEND;

    ELSE { Not error response.
      CASE connection_side OF
      = UNKNOWN_SIDE =
        IF dfv$file_server_debug_enabled THEN
          dpp$display_error ('DF - INFORMATIVE, PRO_S_R - INVALID RESPONSE, QI/QEI ZERO WITHOUT ERROR');
        IFEND;
        RETURN;
      ELSE
        ;
      CASEND;
      IF one_word_response_p^.response_flags.inquiry_response THEN
        p_fs_pp_response := one_word_response_p;
        process_inquiry_message (p_fs_pp_response, p_queue_interface_table, queue_index,
             queue_entry_index, p_driver_queue_entry, p_cpu_queue_entry, status);
        { No driver queue flags set by driver for inquiry messages.
        RETURN;
      IFEND;

      { Determine Transaction State.
      CASE connection_side OF
      = SERVER_SIDE =
        IF ((p_driver_queue_entry^.flags.buffer_received) AND
           (p_driver_queue_entry^.held_over_cm_word_count <> 0)) THEN
          p_cpu_queue_entry^.transaction_state := dfc$server_must_read_page_data;
        ELSEIF p_driver_queue_entry^.flags.buffer_sent THEN
          { PP sent response to indicate locked pages for data may be released.
          p_cpu_queue_entry^.transaction_state := dfc$server_waiting_request;
        ELSE
          { All request information has been received on server side.
          p_cpu_queue_entry^.transaction_state := dfc$server_received_request;
        IFEND;
      = CLIENT_SIDE =
        IF ((p_driver_queue_entry^.flags.buffer_received) AND
           (p_driver_queue_entry^.held_over_cm_word_count <> 0)) THEN
          p_cpu_queue_entry^.transaction_state := dfc$client_must_read_page_data;
        ELSE
          { All response information has been received on client side.
          p_cpu_queue_entry^.transaction_state := dfc$response_received;
          p_cpu_queue_entry^.retransmission_count := 0;
        IFEND;
      CASEND;
    IFEND;

    dfp$record_transaction_data (p_driver_queue_entry^, p_cpu_queue_entry^,
         p_queue_interface_table^.queue_directory.
         cpu_queue_pva_directory [queue_index].p_cpu_queue^.queue_header.
         transaction_data);


    CASE p_cpu_queue_entry^.processor_type OF

    = dfc$task_services =

      tmp$check_taskid (p_cpu_queue_entry^.global_task_id, tmc$opt_return, status);
      IF NOT status.normal THEN
        status.normal := TRUE;
        IF dfv$file_server_debug_enabled THEN
          dpp$display_error ('DF - INFORMATIVE, PRO_S_R - TASK NO LONGER ACTIVE');
          display_integer_monitor ('DF - INVALID TASK ID, INDEX = ', $integer (
                p_cpu_queue_entry^.global_task_id.index));
          display_integer_monitor ('DF - INVALID TASK ID, SEQNO = ', $integer (
                p_cpu_queue_entry^.global_task_id.seqno));
          display_integer_monitor ('DF - QUEUE INDEX', queue_index);
          display_integer_monitor ('DF - QUEUE ENTRY INDEX ' , queue_entry_index);
        IFEND;
        RETURN;
      IFEND;

{ Keep the window as small as possible between the setting of subsystem action and the ready task, so that
{ with dual processors the other processor is not likely to release the queue entry before being readied.  A
{ local variable is used for global_task_id, because if the queue entry is released the
{ p_cpu_queue_entry^.global_task_id is cleared, but the task id is still likely to be valid, since the task is
{ still probably running.  The current window is if the second processor sees the subsystem action, releases
{ the queue entry, and the task terminates before the ready task occurs here.

      mtp$cst_p (cst_p);
      local_priority := cst_p^.dispatching_priority;
      local_task_id := p_cpu_queue_entry^.global_task_id;
      p_driver_queue_entry^.flags.process_response := FALSE;
      p_driver_queue_entry^.flags.subsystem_action := TRUE;
      tmp$set_task_ready (local_task_id, local_priority {readying_task_priority},
           tmc$rc_ready_conditional);

    = dfc$monitor =
      p_driver_queue_entry^.flags.subsystem_action := TRUE;
      p_driver_queue_entry^.flags.process_response := FALSE;

      CASE connection_side OF
      = SERVER_SIDE =
        { SERVER SIDE - PROCESS REQUEST (2.1.2.1) }

        { Determine cause of response.
        dfp$determine_action_for_server (p_cpu_queue_entry, p_driver_queue_entry, action_for_server);

        RESET p_cpu_queue_entry^.p_receive_buffer;
        NEXT p_buffer_header IN p_cpu_queue_entry^.p_receive_buffer;

        CASE action_for_server OF

        = dfc$new_request, dfc$retransmitted_request =
          { Server must execute new request from client.
          { Retransmitted request treated same as new request.

          IF p_cpu_queue_entry^.p_server_iocb^.server_state <> mmc$ss_waiting THEN
            dpp$display_error ('DF - INFORMATIVE, SERVER STATE INVALID FOR NEW REQUEST');
            display_integer_monitor ('DF - QUEUE INDEX', queue_index);
            display_integer_monitor ('DF - QUEUE ENTRY INDEX ' , queue_entry_index);
            display_integer_monitor ('DF - SERVER STATE ',
                  $INTEGER (p_cpu_queue_entry^.p_server_iocb^.server_state));
            IF dfv$file_server_debug_enabled THEN
              dpp$display_error (' NEED DUMP OF BOTH CLIENT AND SERVER.');
              mtp$error_stop ('DF - PRO_S_R, SERVER STATE INVALID FOR NEW REQUEST.');
            { else - continue normally.
            IFEND;
          IFEND;

          { Move request parameters to server IOCB.
          NEXT p_page_io_request IN p_cpu_queue_entry^.p_receive_buffer;
          p_cpu_queue_entry^.p_server_iocb^.global_file_name :=
               p_page_io_request^.global_file_name;
          p_cpu_queue_entry^.p_server_iocb^.sfid :=
               p_page_io_request^.remote_sfid;
          p_cpu_queue_entry^.p_server_iocb^.offset :=
               p_page_io_request^.segment_offset;
          p_cpu_queue_entry^.p_server_iocb^.length :=
               p_page_io_request^.segment_length;
          p_cpu_queue_entry^.p_server_iocb^.eoi :=
               p_page_io_request^.eoi_byte_address;

          { Initialize remainder of server IOCB.
          p_cpu_queue_entry^.p_server_iocb^.server_state := mmc$ss_waiting;
 { * ? *  p_cpu_queue_entry^.p_server_iocb^.sub_reqcode := ;
          p_cpu_queue_entry^.p_server_iocb^.condition :=
               dfc$null_server_condition;
          p_cpu_queue_entry^.p_server_iocb^.io_already_active := FALSE;
          p_cpu_queue_entry^.p_server_iocb^.active_io_count := 0;
          p_cpu_queue_entry^.p_server_iocb^.reissue_request := FALSE;
          p_cpu_queue_entry^.p_server_iocb^.restart_count := 0;

          { Convert remote_processor to new ordinal type.
          CASE p_buffer_header^.remote_processor OF
          = dfc$write_pages =
            remote_request := dfc$write_for_client;
            { initial process: read_from_client }
            p_cpu_queue_entry^.io_id.io_function := ioc$read_from_client;
            { final process: write_for_server }

          = dfc$read_pages =
            remote_request := dfc$read_for_client;
            { initial process: read_for_server }
            p_cpu_queue_entry^.io_id.io_function := ioc$read_for_server;
            { final process: write_to_client }

          = dfc$allocate =
            remote_request := dfc$allocate_space_for_client;
            { initial process = final process: allocate }
            p_cpu_queue_entry^.io_id.io_function := ioc$allocate;

          ELSE
            dpp$display_error ('DF - INFORMATIVE, UNKNOWN REMOTE_PROCESSOR ON SERVER');
            display_integer_monitor ('DF - QUEUE INDEX', queue_index);
            display_integer_monitor ('DF - QUEUE ENTRY INDEX ' , queue_entry_index);
            IF dfv$file_server_debug_enabled THEN
              dpp$display_error (' NEED DUMP OF BOTH CLIENT AND SERVER.');
              mtp$error_stop ('DF - PRO_S_R, UNKNOWN REMOTE_PROCESSOR ON SERVER');
            ELSE
              p_queue_interface_table^.queue_directory.cpu_queue_pva_directory [queue_index].
                    p_cpu_queue^.queue_header.partner_status.timeout_partner := TRUE;
              dpp$display_error (' Timing Out File Server because processor unknown.');
              RETURN;
            IFEND;
          CASEND;

          io_status.normal := TRUE;
          io_status.condition := 0;

          syp$mtr_hang_if_system_jrt_set (dfc$tjr_prosr_new_request);
          mmp$mtr_process_server_complete (remote_request,
             p_cpu_queue_entry^.io_id, p_cpu_queue_entry^.p_server_iocb,
             io_status);

        = dfc$complete_request, dfc$complete_request_on_error =
          { Server must complete processing of request.
          { With or without driver error condition -
          { Response and page data has been sent to client, prompt for data request completed,
          { or driver detected error while processing a request which involved page data.
          { In either case pages will be released.

          io_status.normal := TRUE;
          io_status.condition := 0;
          IF (p_cpu_queue_entry^.data_pages_locked) AND
             (p_driver_queue_entry^.data_descriptor.actual_length <> 0) THEN
            IF one_word_response_p^.response_parameter.error_condition = 0 THEN
              io_error := ioc$no_error;
            ELSEIF one_word_response_p^.response_parameter.error_condition =
                  dfc$destination_machine_down THEN
              io_error := ioc$media_error;
              io_status.normal := FALSE;
              io_status.condition := dfe$server_has_terminated;
            ELSE
              io_error := ioc$media_error;
              io_status.normal := FALSE;
              io_status.condition := ioc$disk_media_error;
            IFEND;

            dfp$convert_list_pointer (p_cpu_queue_entry^.p_data_rma_list, p_rma_list);

            mmp$unlock_rma_list (p_cpu_queue_entry^.io_type, p_rma_list,
                p_driver_queue_entry^.data_descriptor.actual_length DIV 8,
                p_cpu_queue_entry^.io_id, {MF_JOB_FILE} FALSE, io_error, m_status);

            IF NOT m_status.normal THEN
              dpp$display_error ('DF - INFORMATIVE, ABNORMAL STATUS FROM UNLOCK_RMA_LIST');
              display_integer_monitor ('DF - QUEUE INDEX', queue_index);
              display_integer_monitor ('DF - QUEUE ENTRY INDEX ' , queue_entry_index);
              IF dfv$file_server_debug_enabled THEN
                dpp$display_error (' NEED DUMP OF BOTH CLIENT AND SERVER.');
                mtp$error_stop ('DF - PRO_S_R, ABNORMAL STATUS FROM UNLOCK_RMA_LIST');
              ELSE
                p_queue_interface_table^.queue_directory.cpu_queue_pva_directory [queue_index].
                      p_cpu_queue^.queue_header.partner_status.terminate_partner := TRUE;
                dpp$display_error (' Terminating File Server because abnormal unlock status.');
                RETURN;
              IFEND;
            IFEND;

            p_driver_queue_entry^.data_descriptor.actual_length := 0;
            p_cpu_queue_entry^.data_pages_locked := FALSE;

          IFEND;

          remote_request := dfc$completing_previous_request;

          syp$mtr_hang_if_system_jrt_set (dfc$tjr_prosr_complete_request);
          mmp$mtr_process_server_complete (remote_request,
             p_cpu_queue_entry^.io_id, p_cpu_queue_entry^.p_server_iocb,
             io_status);

          { Get pointer to FDE.
          gfp$mtr_get_fde_p (p_cpu_queue_entry^.sfid, NIL, p_fde);
          dmp$get_disk_file_descriptor_p (p_fde, dfd_p);

          { Decrement read/write count in the disk_file_descriptor.
          dfd_p^.read_write_count := dfd_p^.read_write_count - 1;

        = dfc$transaction_out_of_sequence =
          dpp$display_error ('DF - INFORMATIVE, TRANSACTION OUT OF SEQUENCE');
          display_integer_monitor ('DF - QUEUE INDEX', queue_index);
          display_integer_monitor ('DF - QUEUE ENTRY INDEX ' , queue_entry_index);
          IF dfv$file_server_debug_enabled THEN
            dpp$display_error (' NEED DUMP OF BOTH CLIENT AND SERVER.');
            mtp$error_stop ('DF - PRO_S_R, TRANSACTION OUT OF SEQUENCE');
          ELSE
            p_queue_interface_table^.queue_directory.cpu_queue_pva_directory [queue_index].
                  p_cpu_queue^.queue_header.partner_status.timeout_partner := TRUE;
            dpp$display_error (' Timing out File Server because transaction out of sequence.');
            RETURN;
          IFEND;

        ELSE
          dpp$display_error ('DF - INVALID CASE FOR PROCESSING STATE');
          display_integer_monitor ('DF - QUEUE INDEX', queue_index);
          display_integer_monitor ('DF - QUEUE ENTRY INDEX ' , queue_entry_index);
          IF dfv$file_server_debug_enabled THEN
            dpp$display_error (' NEED DUMP OF BOTH CLIENT AND SERVER.');
            mtp$error_stop ('DF - PRO_S_R, INVALID CASE FOR PROCESSING STATE');
          ELSE
            p_queue_interface_table^.queue_directory.cpu_queue_pva_directory [queue_index].
                  p_cpu_queue^.queue_header.partner_status.terminate_partner := TRUE;
            dpp$display_error (' Terminating File Server because case invalid for state.');
            RETURN;
          IFEND;
        CASEND; {action_for_server}


      = CLIENT_SIDE =
        { CLIENT SIDE - PROCESS RESPONSE (2.1.2.2) }

        RESET p_cpu_queue_entry^.p_receive_buffer;
        NEXT p_status_response IN p_cpu_queue_entry^.p_receive_buffer;

        io_status := p_status_response^.status;

        { Convert remote_processor to io_type.
        CASE p_status_response^.buffer_header.remote_processor OF
        = dfc$read_pages =
          io_type := ioc$read_page;

        = dfc$write_pages =
          io_type := ioc$write_page;

        = dfc$allocate =
          io_type := ioc$allocate;

        ELSE
          dpp$display_error ('DF - INFORMATIVE, UNKNOWN REMOTE_PROCESSOR ON CLIENT.');
          display_integer_monitor ('DF - QUEUE INDEX', queue_index);
          display_integer_monitor ('DF - QUEUE ENTRY INDEX ' , queue_entry_index);
          IF dfv$file_server_debug_enabled THEN
            dpp$display_error (' NEED DUMP OF BOTH CLIENT AND SERVER.');
            mtp$error_stop ('DF - PRO_S_R, UNKNOWN REMOTE_PROCESSOR ON CLIENT');
          ELSE
            p_queue_interface_table^.queue_directory.cpu_queue_pva_directory [queue_index].
                  p_cpu_queue^.queue_header.partner_status.timeout_partner := TRUE;
            dpp$display_error (' Timing Out File Server because unknown client process.');
            RETURN;
          IFEND;

        CASEND; {remote_processor}

        IF (p_cpu_queue_entry^.data_pages_locked) AND
           (p_driver_queue_entry^.data_descriptor.actual_length <> 0) THEN

          IF io_status.normal THEN
            io_error := ioc$no_error;
          ELSE
            IF io_type = ioc$allocate THEN
{             We are not concerned with the io_status.condition; we just need to know the allocate failed.
              io_error := ioc$server_allocation_error;
            ELSE
              CASE io_status.condition OF
                = dfe$server_has_terminated =
                  io_error := ioc$server_has_terminated;
                = mme$volume_unavailable, dfe$server_not_active =
                  io_error := ioc$unrecovered_error_unit_down;
                = dfe$sfid_gfn_mismatch, ioe$unrecovered_disk_error =
                  io_error := ioc$unrecovered_error;
                = ioc$disk_media_error =
                  io_error := ioc$media_error;
              ELSE
{ ??????
              CASEND;
            IFEND;
          IFEND;

          dfp$convert_list_pointer (p_cpu_queue_entry^.p_data_rma_list, p_rma_list);

          mmp$unlock_rma_list (io_type, p_rma_list,
              p_driver_queue_entry^.data_descriptor.actual_length DIV 8,
              p_cpu_queue_entry^.io_id, {MF_JOB_FILE} FALSE, io_error, m_status);

          IF NOT m_status.normal THEN
            dpp$display_error ('DF - INFORMATIVE, ABNORMAL STATUS FROM UNLOCK_RMA_LIST');
            display_integer_monitor ('DF - QUEUE INDEX', queue_index);
            display_integer_monitor ('DF - QUEUE ENTRY INDEX ' , queue_entry_index);
            IF dfv$file_server_debug_enabled THEN
              dpp$display_error (' NEED DUMP OF BOTH CLIENT AND SERVER.');
              mtp$error_stop ('DF - PRO_S_R, ABNORMAL STATUS FROM UNLOCK_RMA_LIST');
            ELSE
              p_queue_interface_table^.queue_directory.cpu_queue_pva_directory [queue_index].
                    p_cpu_queue^.queue_header.partner_status.terminate_partner := TRUE;
              dpp$display_error (' Terminating File Server because abnormal unlock status.');
              RETURN;
            IFEND;
          IFEND;

          p_driver_queue_entry^.data_descriptor.actual_length := 0;
          p_cpu_queue_entry^.data_pages_locked := FALSE;

        IFEND;

        IF p_cpu_queue_entry^.io_id.specified THEN
          mmp$mtr_process_io_completion (p_cpu_queue_entry^.io_id, io_type,
              io_status);
        IFEND;

        { Get pointer to FDE.
        gfp$mtr_get_fde_p (p_cpu_queue_entry^.sfid, NIL, p_fde);
        dfp$get_served_file_desc_p (p_fde, p_server_descriptor);

        { Decrement read/write count in the server_descriptor.
        p_server_descriptor^.header.read_write_count := p_server_descriptor^.header.read_write_count - 1;

        NEXT p_page_io_response IN p_cpu_queue_entry^.p_receive_buffer;

        IF p_page_io_response^.total_allocated_length >
            p_server_descriptor^.header.total_allocated_length THEN

          p_server_descriptor^.header.total_allocated_length :=
              p_page_io_response^.total_allocated_length;

        IFEND;

        IF io_error = ioc$server_allocation_error THEN
{
{ If the current total_allocated_length is less than the requested segment_length, set up a record which
{ lets job-mode restart the allocation with the correct data.  Otherwise, another request for allocation
{ has already completed for a greater segment_length than this request.  Always take the save the largest
{ request that is pending.
{
          IF p_page_io_response^.segment_length - p_server_descriptor^.header.total_allocated_length > 0 THEN
            p_server_descriptor^.header.allocation_info.allocation_needed_on_server := TRUE;
            IF p_page_io_response^.segment_length - p_server_descriptor^.header.total_allocated_length >
                  p_server_descriptor^.header.allocation_info.bytes_to_allocate THEN
              p_server_descriptor^.header.allocation_info.bytes_to_allocate := p_page_io_response^.
                    segment_length - p_server_descriptor^.header.total_allocated_length;
            IFEND;
          IFEND;
        IFEND;

        dfp$release_queue_entry (p_queue_interface_table, queue_index,
            queue_entry_index, queue_release_status);

        IF queue_release_status <> dfc$rqes_entry_released THEN
          dpp$display_error ('DF - INFORMATIVE, UNABLE TO RELEASE QUEUE ENTRY');
          display_integer_monitor ('DF - QUEUE INDEX', queue_index);
          display_integer_monitor ('DF - QUEUE ENTRY INDEX ' , queue_entry_index);
          IF dfv$file_server_debug_enabled THEN
            dpp$display_error (' NEED DUMP OF BOTH CLIENT AND SERVER.');
            mtp$error_stop ('DF - PRO_S_R, UNABLE TO RELEASE QUEUE ENTRY');
          ELSE
            p_queue_interface_table^.queue_directory.cpu_queue_pva_directory [queue_index].
                  p_cpu_queue^.queue_header.partner_status.timeout_partner := TRUE;
            dpp$display_error (' Timing Out File Server queue entry release failed.');
            RETURN;
          IFEND;
        IFEND;

      ELSE
      CASEND; {connection_side}

    ELSE
      dpp$display_error ('DF - INFORMATIVE, INVALID CPU QUEUE PROCESSOR TYPE');
      display_integer_monitor ('DF - QUEUE INDEX', queue_index);
      display_integer_monitor ('DF - QUEUE ENTRY INDEX ' , queue_entry_index);
      IF dfv$file_server_debug_enabled THEN
        dpp$display_error (' NEED DUMP OF BOTH CLIENT AND SERVER.');
        mtp$error_stop ('DF - PRO_S_R, INVALID CPU QUEUE PROCESSOR TYPE');
      ELSE
        p_queue_interface_table^.queue_directory.cpu_queue_pva_directory [queue_index].
              p_cpu_queue^.queue_header.partner_status.timeout_partner := TRUE;
        dpp$display_error (' Timing Out File Server invalid cpu queue processor type.');
        RETURN;
      IFEND;
    CASEND;  {cpu_queue_entry.processor_type}

  PROCEND dfp$process_server_response_a;

?? TITLE := '    [XDCL] dfp$process_multiword_response', EJECT ??
  PROCEDURE [XDCL] dfp$process_multiword_response
    (    pp_response_p: ^iot$pp_response;
         detailed_status_p: ^iot$detailed_status;
         pp_number: 1 .. ioc$pp_count;
     var status: syt$monitor_status);

    {
    {  This process executes in the Monitor and is called by
    {  IOP$Process_IO_Completions to process multi word PP
    {  responses from the File Server's PP driver.
    {

    VAR
      completed_request_p: ^iot$disk_request,
      count: integer,
      previously_set: boolean,
      pp_interface_table_p: ^iot$pp_interface_table,
      time: integer,
      timeout: integer;


    status.normal := TRUE;

    completed_request_p := pp_response_p^.request^.device_request_p;

    CASE pp_response_p^.response_code.primary_response OF
    = ioc$normal_response =


{  Interlock the pp_interface_table.

      time := #free_running_clock (0);
      timeout := time + 2000000;
      count := 0;

      REPEAT
        i#test_set_bit (^pp_interface_table_p^, ioc$pp_interface_table_lock_bit, previously_set);
        count := count + 1;
        IF count >= 100 THEN
          time := #free_running_clock (0);
          count := 0;
        IFEND;
      UNTIL (NOT previously_set) OR (time > timeout);

      CASE completed_request_p^.request.command[1].command_code OF
      = ioc$cc_idle =
        IF NOT previously_set THEN
          pp_interface_table_p^.idle_status := TRUE;
        IFEND;

      = ioc$cc_resume =
        IF NOT previously_set THEN
          pp_interface_table_p^.idle_status := FALSE;
        IFEND;

      ELSE
      CASEND;

      IF NOT previously_set THEN
        pp_interface_table_p^.lock := FALSE;
      ELSE
        status.normal := FALSE;
        status.condition := ioc$pp_interlock_set;
      IFEND;

    = ioc$unsolicited_response =

      IF dfv$file_server_debug_enabled THEN
        mtp$error_stop ('dfp$process_multiword_response - unexpected response.');
      IFEND;

    = ioc$abnormal_response =

      IF dfv$file_server_debug_enabled THEN
        mtp$error_stop ('dfp$process_multiword_response - abnormal response.');
      IFEND;

    = ioc$intermediate_response =

    ELSE
    CASEND;

  PROCEND dfp$process_multiword_response;
?? TITLE := '    [XDCL] dfp$process_error_log_response', EJECT ??
  PROCEDURE [XDCL] dfp$process_error_log_response
    (    p_fs_pp_response: ^dft$fs_pp_response;
         p_fs_error_log_response: ^dft$fs_error_log_response;
         pp_number: 1 .. ioc$pp_count;
     VAR status: syt$monitor_status);

    {
    {  This processes constructs a sequence containing ESM log data and calls
    {  dsp$report_system_message which copies the data to a circular buffer.
    {
    {  At a later time the OS will call dfp$log_esm_data which will construct
    {  a sequence of "counter" fields which will be written to the engineering
    {  log by procedure sfp$emit_statistic .
    {

    VAR
      channel: cmt$physical_channel,
      esm_log_seq: SEQ (REP 1 OF dft$esm_log_data),
      iou_number: dst$iou_number,
      logical_unit: iot$logical_unit,
      msg: string (dfc$symptom_message_length),
      msg1: string (40),
      msg_level: dst$system_message_levels,
      msg_recorded: boolean,
      msg_type: dst$system_logging_types,
      p_esm_log_data: ^dft$esm_log_data,
      seq_p: ^SEQ ( * ),
      ud: integer;


    status.normal := TRUE;
    IF NOT cmv$logical_pp_table_p^ [pp_number].flags.configured THEN
      RETURN;
    IFEND;

    logical_unit := p_fs_pp_response^.logical_unit;

  /find_ud/
    BEGIN
      FOR ud := LOWERBOUND (cmv$logical_pp_table_p^ [pp_number].pp_info.
            pp_interface_table_p^.unit_descriptors) TO
            UPPERBOUND (cmv$logical_pp_table_p^ [pp_number].pp_info.
            pp_interface_table_p^.unit_descriptors) DO
        IF cmv$logical_pp_table_p^ [pp_number].pp_info.pp_interface_table_p^.
              unit_descriptors [ud].logical_unit = logical_unit THEN
          EXIT /find_ud/;
        IFEND;
      FOREND;
    END /find_ud/;

    logical_unit := cmv$logical_pp_table_p^ [pp_number].pp_info.pp_interface_table_p^.
          unit_descriptors [ud].logical_unit;
    channel.number := cmv$logical_pp_table_p^ [pp_number].pp_info.pp_interface_table_p^.
          unit_descriptors [ud].physical_path.channel_number;
    channel.concurrent := cmv$logical_pp_table_p^ [pp_number].pp_info.channel_interlock_p^.
          channel_characteristics [channel.number].concurrent_channel;
    iou_number := cmv$logical_pp_table_p^ [pp_number].pp_info.channel.iou_number;

    IF channel.concurrent THEN
      IF cmv$logical_pp_table_p^ [pp_number].pp_info.pp_interface_table_p^.
            unit_descriptors [ud].physical_path.port = 0 THEN
        channel.port := cmc$port_a;
      ELSE
        channel.port := cmc$port_b;
      IFEND;
    ELSE
      channel.port := cmc$unspecified_port;
    IFEND;

{ Put esm_log_data into sequence.

    seq_p := ^esm_log_seq;
    RESET seq_p;
    NEXT p_esm_log_data IN seq_p;
    RESET seq_p;

    p_esm_log_data^.error_log_response := p_fs_error_log_response^;
    p_esm_log_data^.logical_unit := logical_unit;

    p_esm_log_data^.iou_number := iou_number;
    p_esm_log_data^.pp_number := pp_number;

    p_esm_log_data^.channel := channel;

{ Determine symptom message.

    CASE p_fs_error_log_response^.error_condition OF
    = dfc$function_timeout =
      p_esm_log_data^.symptom_message := 'ERR=VP73000001, CHANNEL FUNCTION TIMEOUT';
    = dfc$iou_channel_parity_error =
      p_esm_log_data^.symptom_message := 'ERR=VP73000002, IOU CHANNEL PARITY ERROR';
    = dfc$esm_channel_parity_error =
      p_esm_log_data^.symptom_message := 'ERR=VP73000003, ESM CHANNEL PARITY ERROR';
    = dfc$esm_double_bit_parity_error =
      p_esm_log_data^.symptom_message := 'ERR=VP73000004, ESM DOUBLE BIT PARITY ERROR';
    = dfc$esm_address_parity_error =
      p_esm_log_data^.symptom_message := 'ERR=VP73000005, ESM ADDRESS PARITY ERROR';
    = dfc$esm_flag_operation_abort =
      p_esm_log_data^.symptom_message := 'ERR=VP73000006, ESM FLAG OPERATION ABORT';
    = dfc$adp_uncorrected_cm_error =
      p_esm_log_data^.symptom_message := 'ERR=VP73000007, ADAPTER UNCORRECTED CM ERROR';
    = dfc$adp_cm_reject =
      p_esm_log_data^.symptom_message := 'ERR=VP73000008, ADAPTER CM REJECT';
    = dfc$adp_invalid_cm_response =
      p_esm_log_data^.symptom_message := 'ERR=VP73000009, ADAPTER INVALID CM RESPONSE';
    = dfc$adp_cm_response_parity_err =
      p_esm_log_data^.symptom_message := 'ERR=VP73000010, ADAPTER CM RESPONSE PARITY ERROR';
    = dfc$adp_cmi_read_parity_err =
      p_esm_log_data^.symptom_message := 'ERR=VP73000011, ADAPTER CMI READ PARITY ERROR';
    = dfc$adp_clock_fault =
      p_esm_log_data^.symptom_message := 'ERR=VP73000012, ADAPTER CLOCK FAULT';
    = dfc$adp_input_buffer_overflow =
      p_esm_log_data^.symptom_message := 'ERR=VP73000013, ADAPTER INPUT BUFFER OVERFLOW';
    = dfc$adp_input_data_parity_error =
      p_esm_log_data^.symptom_message := 'ERR=VP73000014, ADAPTER INPUT DATA PARITY ERROR';
    = dfc$adp_12_16_conversion_error =
      p_esm_log_data^.symptom_message := 'ERR=VP73000015, ADAPTER 12/16 CONVERTION ERROR';
    = dfc$adp_jy_data_parity_error =
      p_esm_log_data^.symptom_message := 'ERR=VP73000016, ADAPTER JY DATA PARITY ERROR';
    = dfc$adp_kx_pp_data_parity_error =
      p_esm_log_data^.symptom_message := 'ERR=VP73000017, ADAPTER BAS (KX PP DATA) PARITY ERROR';
    = dfc$adp_kz_board_detected_error =
      p_esm_log_data^.symptom_message := 'ERR=VP73000018, ADAPTER KZ BOARD DETECTED ERROR';
    = dfc$adp_jy_board_detected_error =
      p_esm_log_data^.symptom_message := 'ERR=VP73000019, ADAPTER JY BOARD DETECTED ERROR';
    = dfc$adp_kx_board_detected_error =
      p_esm_log_data^.symptom_message := 'ERR=VP73000020, ADAPTER KX BOARD DETECTED ERROR';
    = dfc$esm_address_overflow =
      p_esm_log_data^.symptom_message := 'ERR=VP73000021, ESM ADDRESS OVERFLOW';
    = dfc$channel_inactive_error =
      p_esm_log_data^.symptom_message := 'ERR=VP73000022, CHANNEL INACTIVE ERROR';
    = dfc$dma_xfer_halted_early =
      p_esm_log_data^.symptom_message := 'ERR=VP73000023, ADAPTER TRANSFER HALTED EARLY';
    = dfc$lsp_deadman_timeout =
      p_esm_log_data^.symptom_message := 'ERR=VP73000024, LOW SPEED PORT DEADMAN TIMEOUT';
    = dfc$unused_reserved_25 =
      p_esm_log_data^.symptom_message := 'ERR=VP73000025, UNDEFINED ERROR CONDITION';
    = dfc$unused_reserved_26 =
      p_esm_log_data^.symptom_message := 'ERR=VP73000026, UNDEFINED ERROR CONDITION';
    = dfc$unused_reserved_27 =
      p_esm_log_data^.symptom_message := 'ERR=VP73000027, UNDEFINED ERROR CONDITION';
    = dfc$unused_reserved_28 =
      p_esm_log_data^.symptom_message := 'ERR=VP73000028, UNDEFINED ERROR CONDITION';
    = dfc$unused_reserved_29 =
      p_esm_log_data^.symptom_message := 'ERR=VP73000029, UNDEFINED ERROR CONDITION';

    ELSE
      p_esm_log_data^.symptom_message := 'ERR=VP7300GT29, UNDEFINED ERROR CONDITION';
    CASEND;

    IF p_fs_error_log_response^.flags.unrecovered_error THEN
      msg_level := dsc$unrecovered_error;
    ELSE
      msg_level := dsc$recovered_error;
    IFEND;

    msg_type := dsc$fs_stornet_errors;
    dsp$report_system_message (seq_p, msg_type, msg_level, msg_recorded);

    IF dfv$file_server_debug_enabled THEN
{                       1         2         3
{              123456789012345678901234567890
      msg1 := 'IOU   CHnn  -             ';
      dpp$convert_int_to_str_dec (1, iou_number, msg1 (4, *));
      dpp$convert_int_to_str_dec (2, channel.number, msg1 (9, *));

      IF channel.concurrent THEN
        msg1 (6,1) := 'C';       { CIO Channel }
        IF channel.port = cmc$port_a THEN
          msg1 (11,1) := 'A';      { Change to CIO channel PORT A }
        ELSE {port b
          msg1 (11,1) := 'B';      { Change to CIO channel PORT B }
        IFEND;
      ELSE
        ;                          { No change for NIO channel }
      IFEND;

      CASE msg_level OF
      = dsc$unrecovered_error =
        msg1 (15, 11) := 'UNRECOVERED';
      ELSE
        msg1 (15, 11) := 'RECOVERED  ';
      CASEND;

      dpp$display_error (msg1);
      dpp$display_error (p_esm_log_data^.symptom_message);
      display_error_log_response (p_fs_pp_response, p_fs_error_log_response, channel.number, iou_number);
    IFEND;

  PROCEND dfp$process_error_log_response;
?? TITLE := '    process_inquiry_message', EJECT ??

  PROCEDURE process_inquiry_message (
         p_fs_pp_response: ^dft$fs_pp_response;
         p_queue_interface_table: dft$p_queue_interface_table;
         queue_index: dft$queue_index;
         queue_entry_index: dft$queue_entry_index;
         p_driver_queue_entry: ^dft$driver_queue_entry;
         p_cpu_queue_entry: ^dft$cpu_queue_entry;
     VAR status: syt$monitor_status);

{ This procedure processes inquiry messages. The inquiry tracer portion of the
{ inquiry message must match the last digits of the transaction sequence number
{ and the retransmission count in the cpu queue entry or the inquiry message
{ is ignored unless all of the following conditions are true -
{          1. The inquiry message is received on server side,
{          2. Server's queue entry transaction state is dfc$media_error or
{             or dfc$server_waiting_request.
{          3. The inquiry message transaction digit is one greater than
{             the last transaction count digit in the queue entry.
{        For this case an inquiry response will be returned to the client.
{
{ If the inquiry message is received for the server a transaction state and
{ the inquiry tracer is returned to the client in an inquiry message (response).
{ The transaction state to be returned to the client is not necessarily that
{ which resides in the server's cpu queue entry. The transaction state of
{ dfc$server_sent_response never resides in the server's cpu queue entry but
{ is determined by this procedure.
{ If the inquiry message is received for the client it is a response to an
{ inquiry message sent earlier by the the client. The transaction state in the
{ cpu queue entry will be changed to a more current state if this procedure
{ determines that the inquiry response is appropriate.


    VAR
      local_tracer: dft$inquiry_tracer,
      inquiry_message: dft$inquiry_message,
      ignore_queue_request_status: dft$queue_request_status,
      p_condition: ^pmt$condition_name,
      signal: pmt$signal;

    status.normal := TRUE;

    IF p_fs_pp_response^.response_parameter.inquiry_message.
        transaction_state = dfc$terminate_break_signal THEN
      signal.identifier := pmc$multi_task_condition;
      p_condition := #LOC(signal.contents);
      p_condition^ := dfc$client_terminate_break;
      tmp$send_signal (p_cpu_queue_entry^.global_task_id, signal, status);
      IF NOT status.normal THEN
        dpp$display_error ('DF - Bad status trying to send terminate_break signal');
        status.normal := TRUE;
      IFEND;
      RETURN;
    IFEND;

    IF p_fs_pp_response^.response_parameter.inquiry_message.
        transaction_state = dfc$pause_break_signal THEN
      signal.identifier := pmc$multi_task_condition;
      p_condition := #LOC(signal.contents);
      p_condition^ := dfc$client_pause_break;
      tmp$send_signal (p_cpu_queue_entry^.global_task_id, signal, status);
      IF NOT status.normal THEN
        dpp$display_error ('DF - Bad status trying to send pause_break signal');
        status.normal := TRUE;
      IFEND;
      RETURN;
    IFEND;

    dfp$form_inquiry_tracer (p_cpu_queue_entry^.transaction_count,
        p_cpu_queue_entry^.retransmission_count, local_tracer);

    IF p_fs_pp_response^.response_parameter.inquiry_message.inquiry_tracer = local_tracer THEN

      IF p_queue_interface_table^.queue_directory.driver_queue_pva_directory[queue_index].
         p_driver_queue^.queue_header.connection_descriptor.source.flags.server_to_client THEN
        { SERVER SIDE - PROCESS INQUIRY MESSAGE }

          CASE p_cpu_queue_entry^.transaction_state OF
          = dfc$server_waiting_request =
            IF p_driver_queue_entry^.flags.driver_action THEN
              { Server has processed the request and queued the response, however the
              { the response has not been sent by the driver yet.
              { The request response should reach client before this inquiry
              { response, so the inquiry response will not be sent.
              RETURN;
            ELSE
              { Server processed the request and the response has been sent by the driver.
              { Send Inquiry response so that if Client side PP driver could'nt
              { read the header portion of the request response to identify the QE
              { the request can be timed out and retransmitted.
              inquiry_message.transaction_state := dfc$server_sent_response;
            IFEND;

          = dfc$server_must_read_page_data, dfc$server_received_request,
            dfc$message_content_error, dfc$media_error =
            inquiry_message.transaction_state := p_cpu_queue_entry^.transaction_state;
          ELSE
            ;
          CASEND;
          inquiry_message.inquiry_tracer := local_tracer;
          { Answer inquiry message.
          dfp$queue_inquiry_request (p_queue_interface_table, queue_index, queue_entry_index,
              inquiry_message, ignore_queue_request_status);

      ELSE
        { CLIENT SIDE - PROCESS INQUIRY RESPONSE }

        CASE p_cpu_queue_entry^.transaction_state OF
        = dfc$request_sent, dfc$server_waiting_request, dfc$server_sent_response,
          dfc$server_must_read_page_data, dfc$server_received_request =
          { These transaction state indicate Client is waiting for a request response.
          { Set Client's latest transaction state to that in inquiry response.
          p_cpu_queue_entry^.transaction_state := p_fs_pp_response^.response_parameter.
               inquiry_message.transaction_state;

          { Now check the transaction_state received by the Client.
          CASE p_fs_pp_response^.response_parameter.inquiry_message.transaction_state OF
          = dfc$server_waiting_request, dfc$server_sent_response =
            { Increment timeout_count each time client receives this inquiry response
            { so that incase Client or Server side driver fails reading header portion of
            { the message the request will be timed out and retransmitted.
            p_cpu_queue_entry^.request_timeout_count :=  p_cpu_queue_entry^.request_timeout_count + 1;
          = dfc$server_must_read_page_data, dfc$server_received_request =
            { Re-set timeout_count each time client receives this inquiry response.
            { As long as inquiry response indicate this state the connection is
            { still alive, Server is just slow in processing request.
            p_cpu_queue_entry^.request_timeout_count := 0;
          ELSE
          ;
          CASEND;

        ELSE { ignore inquiry response for all other client state cases }
          ;
        CASEND;

      IFEND;
    ELSE { No match on inquiry tracer.
      { Increment local_tracer.transaction_digit by one and compare.
      dfp$form_inquiry_tracer (p_cpu_queue_entry^.transaction_count + 1,
          p_cpu_queue_entry^.retransmission_count, local_tracer);
      IF (p_queue_interface_table^.queue_directory.driver_queue_pva_directory[queue_index].
          p_driver_queue^.queue_header.connection_descriptor.source.flags.server_to_client)
         AND (p_fs_pp_response^.response_parameter.inquiry_message.inquiry_tracer.
              transaction_digit = local_tracer.transaction_digit) THEN
        CASE p_cpu_queue_entry^.transaction_state OF
        = dfc$media_error, dfc$message_content_error, dfc$server_waiting_request =
        { Server side, inquiry for transaction which is one greater than the
        { last transaction processed by the server.
        { If transaction_state is dfc$media_error, assume that a failure
        { occured while reading 'command buffer' portion of the request so that
        { transaction_count was not incremented.
        { If transaction_state is dfc$server_waiting_request, assume that
        { a failure occured while reading the 'header" portion of the request
        { so that the queue entry could not be identified and updated to
        { the transaction_state of dfc$media_error.

          inquiry_message.inquiry_tracer := p_fs_pp_response^.response_parameter.
               inquiry_message.inquiry_tracer;
          inquiry_message.transaction_state := p_cpu_queue_entry^.transaction_state;
          { Answer inquiry message.
          dfp$queue_inquiry_request (p_queue_interface_table, queue_index, queue_entry_index,
              inquiry_message, ignore_queue_request_status);

        = dfc$server_received_request, dfc$server_must_read_page_data =
          IF NOT p_driver_queue_entry^.flags.subsystem_action THEN

{           This is the case when the PP response is processed in dfp$process_server_response,
{           the transaction_state has been set, the subsystem_action flag has been set,
{           but the queue_entry has been cleared prior to the tmp$set_task_ready call.

            IF dfv$file_server_debug_enabled THEN
              dpp$display_error ('DF - INFORMATIVE, SERVER SIDE MISSED TASK READY.');
              display_integer_monitor ('DF - QUEUE INDEX', queue_index);
              display_integer_monitor ('DF - QUEUE ENTRY INDEX ' , queue_entry_index);
            IFEND;
            p_driver_queue_entry^.flags.subsystem_action := TRUE;
          IFEND;
        ELSE
        ;
        CASEND;
      ELSE { Still no match on Inquiry Tracer.
        IF (p_queue_interface_table^.queue_directory.driver_queue_pva_directory[queue_index].
            p_driver_queue^.queue_header.connection_descriptor.source.flags.server_to_client)
           AND (queue_entry_index = dfc$poll_queue_index) THEN
{         Server Side, inquiry is for POLLER.
          CASE p_queue_interface_table^.queue_directory.cpu_queue_pva_directory[queue_index].
            p_cpu_queue^.queue_header.partner_status.server_state OF
          = dfc$inactive, dfc$terminated, dfc$awaiting_recovery =
            IF p_queue_interface_table^.queue_directory.cpu_queue_pva_directory[queue_index].
               p_cpu_queue^.queue_header.partner_status.verify_queue THEN

{             The operator on the client machine typed ACTS before the operator
{             on the server machine typed ACTC so that the POLLER's
{             "verify_queue" message was never delivered to the server.
{             {sequence example: 1. deactivate_server 2. terminate_server
{                                3. activate_server   4. activate_client }
{             If the server side was never terminated (TERC) the transaction
{             sequence count is not re-set. Force response to inquiry messages
{             so that timeout and retransmission will occur.

              inquiry_message.inquiry_tracer := p_fs_pp_response^.response_parameter.
                   inquiry_message.inquiry_tracer;
              inquiry_message.transaction_state := p_cpu_queue_entry^.transaction_state;
              { Answer inquiry message.
              dfp$queue_inquiry_request (p_queue_interface_table, queue_index, queue_entry_index,
                  inquiry_message, ignore_queue_request_status);
            IFEND;
          ELSE
            ;
          CASEND;
        IFEND;
      IFEND;
    IFEND;

  PROCEND process_inquiry_message;

?? TITLE := '    [XDCL] dfp$process_request_timeout', EJECT ??
  PROCEDURE [XDCL] dfp$process_request_timeout
    (    p_queue_interface_table: dft$p_queue_interface_table;
         queue_index: dft$queue_index;
         queue_entry_index: dft$queue_entry_index);

{ This procedure processes request timeouts for the client.
{ Depending on the timeout count and the current transaction state
{ either an inquiry will be sent to the server, or the request will
{ be retransmitted.
{ The request_timeout_count is incremented in procedure Process_Inquiry_Response
{ so that request retransmission due to timeout is only attempted when the
{ the connection is not broken (inquiries getting through).
{ The "deadman timeout" on POLL requests in dfm$manage_server_connection
{ process Time_Out_Requests will detect a broken connection.

    VAR
      local_tracer: dft$inquiry_tracer,
      ignore_queue_request_status: dft$queue_request_status,
      inquiry_message: dft$inquiry_message,
      p_cpu_queue_entry: ^dft$cpu_queue_entry,
      p_driver_queue_entry: ^dft$driver_queue_entry;

    dfp$fetch_queue_entry (p_queue_interface_table, queue_index,
         queue_entry_index, p_driver_queue_entry, p_cpu_queue_entry);

    CASE p_cpu_queue_entry^.transaction_state OF
    = dfc$request_queued =
      { Check if transaction state can be upgraded to request_sent.
      IF (NOT p_driver_queue_entry^.flags.driver_action) AND
         (NOT p_driver_queue_entry^.flags.subsystem_action) AND
         (NOT p_driver_queue_entry^.flags.process_response) THEN
        p_cpu_queue_entry^.transaction_state := dfc$request_sent;
        RETURN;
      IFEND;
    = dfc$media_error, dfc$message_content_error =
      { Transaction state dfc$media_error is set on error response for client, or on an
      { inquiry message response from the server with a server transaction state of
      { dfc$media_error. This transaction state means the PP driver detected hardware
      { failure.
      { Transaction state dfc$message_content_error is set on an inquiry message
      { response from the server. This transaction state means the server task
      { detected some error or inconsistency in the the content of the command buffer
      { received from the client (possibly due to an undetected hardware error).
      { Attempt to queue the request for retransmission.
      dfp$retransmit_request (p_queue_interface_table, queue_index,
          queue_entry_index, p_cpu_queue_entry, p_driver_queue_entry);
      RETURN;

    ELSE
      ;
    CASEND;

    IF p_cpu_queue_entry^.request_timeout_count <= p_queue_interface_table^.queue_directory.
       cpu_queue_pva_directory [queue_index].p_cpu_queue^.queue_header.
       maximum_request_timeout_count THEN

      CASE p_cpu_queue_entry^.transaction_state OF
      = dfc$request_sent, dfc$server_sent_response, dfc$server_waiting_request,
        dfc$server_must_read_page_data, dfc$server_received_request =
        dfp$form_inquiry_tracer (p_cpu_queue_entry^.transaction_count,
            p_cpu_queue_entry^.retransmission_count, local_tracer);
        inquiry_message.inquiry_tracer := local_tracer;
        inquiry_message.transaction_state := p_cpu_queue_entry^.transaction_state;
        dfp$queue_inquiry_request (p_queue_interface_table, queue_index, queue_entry_index,
            inquiry_message, ignore_queue_request_status);
      ELSE
        { Do Nothing.
      CASEND;

    ELSE { Maximum Timeouts.
      dfp$retransmit_request (p_queue_interface_table, queue_index,
          queue_entry_index, p_cpu_queue_entry, p_driver_queue_entry);
    IFEND;

  PROCEND dfp$process_request_timeout;

?? TITLE := '    [XDCL] dfp$retransmit_request', EJECT ??
  PROCEDURE [XDCL] dfp$retransmit_request
    (    p_queue_interface_table: ^dft$queue_interface_table;
         queue_index: dft$queue_index;
         queue_entry_index: dft$queue_entry_index;
         p_cpu_queue_entry: ^dft$cpu_queue_entry;
         p_driver_queue_entry: ^dft$driver_queue_entry);

{ This procedure is called to retransmit a request on behalf of the client.
{ The request timeout count is reset to zero, and the retransmission count
{ is incremented both in the cpu_queue_entry and in the request buffer header.
{ If the retransmitted request cannot be the queue entry's values which were
{ changed are restored to there previous value.

    VAR
      driver_queue_flags: dft$queue_entry_flags,
      m_status: syt$monitor_status,
      p_buffer_header: ^dft$buffer_header,
      p_command_buffer: dft$p_command_buffer,
      qr_status: dft$queue_request_status;

    IF p_cpu_queue_entry^.retransmission_count < p_queue_interface_table^.queue_directory.
       cpu_queue_pva_directory [queue_index].p_cpu_queue^.queue_header.
       maximum_retransmission_count THEN

      p_command_buffer := p_cpu_queue_entry^.p_send_buffer;
      RESET p_command_buffer;
      NEXT p_buffer_header IN p_command_buffer;

      p_cpu_queue_entry^.retransmission_count := p_cpu_queue_entry^.retransmission_count + 1;
      p_buffer_header^.retransmission_count := p_cpu_queue_entry^.retransmission_count;
      driver_queue_flags := p_driver_queue_entry^.flags;
      p_driver_queue_entry^.flags := p_cpu_queue_entry^.copied_queue_entry_flags;

      dfp$queue_request (p_queue_interface_table, queue_index, queue_entry_index, qr_status);
      IF qr_status <> dfc$qrs_entry_queued THEN
        { Attempt to restore values changed for retransmission.
        { Backoff retransmission count. Transaction state remains as it was.
        { dfp$process_request_timeout will call this process on next timeout.

        IF dfv$file_server_debug_enabled THEN
          dpp$display_error ('DF - UNABLE TO QUEUE RETRANSMITTED REQUEST FOR -');
          display_integer_monitor ('     Queue Index ', queue_index);
          display_integer_monitor ('     Queue Entry ', queue_entry_index);
          display_integer_monitor ('     Transaction No. ', p_cpu_queue_entry^.transaction_count);
          display_integer_monitor ('     Retransmission No. ', p_cpu_queue_entry^.retransmission_count);
        IFEND;

        p_cpu_queue_entry^.retransmission_count := p_cpu_queue_entry^.retransmission_count - 1;
        p_buffer_header^.retransmission_count := p_cpu_queue_entry^.retransmission_count;
        p_driver_queue_entry^.flags := driver_queue_flags;

      ELSE
        IF dfv$file_server_debug_enabled THEN
          dpp$display_error ('DF - RETRANSMITTED REQUEST FOR -');
          display_integer_monitor ('     Queue Index ', queue_index);
          display_integer_monitor ('     Queue Entry ', queue_entry_index);
          display_integer_monitor ('     Transaction No. ', p_cpu_queue_entry^.transaction_count);
          display_integer_monitor ('     Retransmission No. ', p_cpu_queue_entry^.retransmission_count);
        IFEND;
      IFEND;

    IFEND;

  PROCEND dfp$retransmit_request;
?? TITLE := '    display_error_log_response', EJECT ??
  PROCEDURE display_error_log_response
    (    p_fs_pp_response: ^dft$fs_pp_response;
         p_fs_error_log_response: ^dft$fs_error_log_response;
         channel_number: 0 .. 0ff(16);
         iou_number: dst$iou_number);

{
{   This procedure intended for debug use.
{   The queue_entry_index and queue_index may not be valid depending on
{   depending on when the driver detected the error.

    VAR
      queue_entry_index: INTEGER,
      queue_index: INTEGER;


    queue_index := p_fs_pp_response^.queue_index;
    queue_entry_index := p_fs_pp_response^.queue_entry_index;

    dpp$display_error ('DF - ERROR LOG RESPONSE PROCESSOR - ');
    display_integer_monitor ('  QUEUE INDEX', queue_index);
    display_integer_monitor ('  QUEUE ENTRY INDEX ' , queue_entry_index);
    IF p_fs_error_log_response^.flags.unrecovered_error THEN
      dpp$display_error ('    UNRECOVERED ERROR ');
    ELSE
      dpp$display_error ('    RECOVERED ERROR ');
    IFEND;
    display_integer_monitor ('    ERROR CONDITION = ', p_fs_error_log_response^.error_condition);
    display_integer_monitor ('    IOU = ', iou_number);
    display_integer_monitor ('    CHANNEL = ', channel_number);
    display_integer_monitor ('    RETRY COUNT = ', p_fs_error_log_response^.retry_count);
    display_integer_monitor ('    LAST CH FUNCTION = ', p_fs_error_log_response^.last_ch_function);
    display_integer_monitor ('    ESM LSP FUNCTION = ', p_fs_error_log_response^.esm_lsp_function);
    display_integer_monitor ('    ESM LSP STATUS = ', p_fs_error_log_response^.esm_lsp_status);
    display_integer_monitor ('    ESM ADDRESS = ', p_fs_error_log_response^.esm_address);
    display_integer_monitor ('    RESIDUAL BYTE COUNT = ', p_fs_error_log_response^.residual_byte_count);
    display_integer_monitor ('    TRANSFER BYTE COUNT = ', p_fs_error_log_response^.transfer_byte_count);
    IF p_fs_error_log_response^.flags.C170_dma_adapter AND
       p_fs_error_log_response^.flags.executing_adapter_io THEN
      display_integer_monitor ('    ADAPTER CONTROL REGISTER = ',
            p_fs_error_log_response^.adapter_control_register);
      display_integer_monitor ('    ADAPTER ERROR STATUS = ',
            p_fs_error_log_response^.adapter_error_status);
      display_integer_monitor ('    ADAPTER OP STATUS REGISTER = ',
            p_fs_error_log_response^.adapter_op_status_register);
      IF p_fs_error_log_response^.flags.adapter_t_register_loaded THEN
        display_integer_monitor ('    ADAPTER T REG BYTE COUNT = ',
              p_fs_error_log_response^.adapter_t_register.byte_count);
        display_integer_monitor ('    ADAPTER T REG CM ADDRESS = ',
              p_fs_error_log_response^.adapter_t_register.cm_address);
        display_integer_monitor ('    INITIAL ADAPTER T REG BYTE COUNT = ',
              p_fs_error_log_response^.initial_adapter_t_register.byte_count);
        display_integer_monitor ('    INITIAL ADAPTER T REG CM ADDRESS = ',
              p_fs_error_log_response^.initial_adapter_t_register.cm_address);
      ELSE
        dpp$display_error ('    ERROR PRIOR TO FIRST T REG LOAD.');
      IFEND;
    ELSE
      dpp$display_error ('    ERROR DURING NON ADAPTER IO.');
    IFEND;

  PROCEND display_error_log_response;
MODEND dfm$process_server_response;
