?? RIGHT := 110 ??
*copyc osd$default_pragmats
?? TITLE := 'NOS/VE Subsystem IO' ??
?? NEWTITLE := '  Module Header', EJECT ??
MODULE iom$subsystem_io_completion_tbl;
{
{   PURPOSE: This module contains the procedures used to access
{            the subsystem io completion table.
{
{   Design: An io completion table is allocated, upon demand, for each job.
{           The table is allocated in a job fixed segment and is a
{           fixed size.  A pointer in each job fixed segment is used to
{           associate the job with its io completion table.
{
?? TITLE := '  Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc iot$io_completion_table
*copyc cmt$io_completion_queue_index
*copyc cmt$scan_variable
*copyc oss$job_fixed
*copyc oss$mainframe_pageable
*copyc oss$mainframe_wired
*copyc ost$global_task_id
*copyc ost$status
*copyc ost$signature_lock_status
*copyc ioe$st_errors
?? POP ??
?? TITLE := 'XREF Procedures', EJECT ??
*copyc cmp$unlock_the_rma_list
*copyc cmt$element_name
*copyc iop$set_status_abnormal
*copyc jmt$system_supplied_name
*copyc jmt$user_supplied_name
*copyc osp$clear_job_signature_lock
*copyc osp$test_signature_lock
*copyc osp$set_job_signature_lock
*copyc osp$initialize_signature_lock
*copyc osp$set_signature_lock
*copyc osp$clear_signature_lock
*copyc osp$test_sig_lock
*copyc osp$system_error
*copyc pmp$get_job_names
*copyc pmp$get_executing_task_gtid
?? TITLE := 'XREF Variables', EJECT ??
*copyc cmv$subsys_io_scan_character
*copyc osv$job_fixed_heap
*copyc osv$mainframe_wired_heap
*copyc osv$mainframe_wired_cb_heap
*copyc osv$mainframe_wired_heap
?? TITLE := '  XDCL Variables', EJECT ??
*copyc cmd$io_completion_table
*copyc cmd$default_ioct_entry
      VAR
        cmv$ioct_serial_lock: [XDCL, #GATE, oss$mainframe_pageable]
                  ost$signature_lock,
        cmv$foreign_interface_down: [XDCL, #GATE, oss$mainframe_pageable] boolean,
        cmv$downed_foreign_element: [XDCL, #GATE, oss$mainframe_pageable] cmt$element_name,
        cmv$foreign_down_time: [XDCL, #GATE, oss$mainframe_pageable] integer,
        cmv$throwaway_count: [XDCL, #GATE, oss$mainframe_pageable] integer :=0,
        cmv$subsys_io_responses_p: [#GATE, XDCL, STATIC, oss$job_fixed]
                          ^cmt$subsys_io_response_area := NIL,
        cmv$subsys_io_scan_variable: [#GATE, XDCL, STATIC, oss$job_fixed]
                          cmt$scan_variable := $cmt$scan_character_set [];

?? TITLE := '  create_io_completion_table', EJECT ??

  PROCEDURE create_io_completion_table (VAR able_to_create_table: boolean);

    VAR
      io_completion_table_p: ^cmt$io_completion_table,
      table_index: cmt$io_completion_queue_index,
      local_status: ost$status;

    ALLOCATE io_completion_table_p IN osv$job_fixed_heap^;

    ALLOCATE cmv$subsys_io_responses_p:[cmc$max_subsystem_io_requests]
             IN osv$mainframe_wired_cb_heap^;

    FOR table_index := 1 TO cmc$max_subsystem_io_requests DO
      io_completion_table_p^.header.entries_available (table_index, 1) := 'A';
      cmv$subsys_io_responses_p^ (table_index, 1) := 'N';
      io_completion_table_p^.entries [table_index] := cmv$default_ioct_entry;
      io_completion_table_p^.entries [table_index].entry_index := table_index;
    FOREND;

    io_completion_table_p^.header.available_entries := cmc$max_subsystem_io_requests;
    io_completion_table_p^.header.entries_in_use := 0;
    io_completion_table_p^.header.recovery_action_required := 0;
    osp$initialize_signature_lock (io_completion_table_p^.header.table_lock, local_status);
    IF NOT local_status.normal THEN
      FREE io_completion_table_p IN osv$job_fixed_heap^;
    IFEND;
    osp$initialize_signature_lock (cmv$ioct_serial_lock, local_status);
    IF NOT local_status.normal THEN
      FREE io_completion_table_p IN osv$job_fixed_heap^;
    IFEND;

    cmv$throwaway_count := 0;

    cmv$subsys_io_scan_variable := $cmt$scan_character_set [cmv$subsys_io_scan_character];

    io_completion_table_p^.header.responses_available := cmv$subsys_io_responses_p;

    cmv$io_completion_table_p := io_completion_table_p;

    able_to_create_table := (io_completion_table_p <> NIL);

  PROCEND create_io_completion_table;

?? TITLE := '  get_io_completion_table_address', EJECT ??


  PROCEDURE [INLINE] get_io_completion_table_address (
              VAR io_completion_table_p: ^cmt$io_completion_table);

    io_completion_table_p := cmv$io_completion_table_p;

  PROCEND get_io_completion_table_address;

?? TITLE := '  [XDCL, #GATE] cmp$add_jioct_entry_avail_queue', EJECT ??

*copyc cmh$add_ssiot_entry_avail_queue

  PROCEDURE [XDCL, #GATE] cmp$add_ssiot_entry_avail_queue (VAR job_io_completion_queue_index:
    cmt$io_completion_queue_index);

    VAR
      io_completion_table_entry_p: ^cmt$io_completion_table_entry,
      io_completion_table_entry_index: cmt$io_completion_queue_index,
      wired_request_p: ^cmt$wired_unit_queue_request,
      io_completion_table_p: ^cmt$io_completion_table,
      local_status: ost$status;

    get_io_completion_table_address (io_completion_table_p);

    cmp$get_io_completion_tbl_entry (job_io_completion_queue_index, io_completion_table_entry_p);


    osp$set_job_signature_lock (io_completion_table_p^.header.table_lock);
      io_completion_table_entry_index := io_completion_table_entry_p^.entry_index;
      wired_request_p := io_completion_table_entry_p^.wired_unit_queue_request_p;
      io_completion_table_entry_p^ := cmv$default_ioct_entry;
      io_completion_table_entry_p^.entry_index := io_completion_table_entry_index;
      io_completion_table_entry_p^.wired_unit_queue_request_p := wired_request_p;
      io_completion_table_p^.header.entries_available (io_completion_table_entry_index ,1) := 'A';
      io_completion_table_p^.header.entries_in_use := io_completion_table_p^.header.entries_in_use - 1;

      osp$clear_job_signature_lock (io_completion_table_p^.header.table_lock);

    job_io_completion_queue_index := 0;

  PROCEND cmp$add_ssiot_entry_avail_queue;
?? TITLE := '  [XDCL, #GATE] cmp$ssiot_recovery_condition', EJECT ??

*copyc cmh$ssiot_recovery_condition

    PROCEDURE [XDCL, #GATE] cmp$ssiot_recovery_condition (
           VAR status: ost$status);

       VAR
         io_completion_table_p: ^cmt$io_completion_table;

      status.normal := TRUE;

      get_io_completion_table_address (io_completion_table_p);
      IF io_completion_table_p <> NIL THEN
         osp$set_job_signature_lock (io_completion_table_p^.header.table_lock);
         IF io_completion_table_p^.header.recovery_action_required > 0 THEN
              iop$set_status_abnormal (ioe$ssiot_recovery_required,
                   'Recovery action required on outstanding io requests - IOMSSIOCT',
                    status);
         IFEND;
           osp$clear_job_signature_lock (io_completion_table_p^.header.table_lock);
      IFEND;

    PROCEND cmp$ssiot_recovery_condition;
?? TITLE := '  [XDCL, #GATE] cmp$ssiot_recovery_complete', EJECT ??

*copyc cmh$ssiot_recovery_complete

    PROCEDURE [XDCL, #GATE] cmp$ssiot_recovery_complete (
           VAR status: ost$status);

       VAR
         io_index: cmt$io_completion_queue_index,
         number_of_io_entries: cmt$io_completion_queue_index,
         global_task_id: ost$global_task_id,
         io_completion_table_entry_p: ^cmt$io_completion_table_entry,
         io_completion_table_p: ^cmt$io_completion_table;

      status.normal := TRUE;

      pmp$get_executing_task_gtid (global_task_id);

      get_io_completion_table_address (io_completion_table_p);
      IF io_completion_table_p <> NIL THEN
         osp$set_job_signature_lock (io_completion_table_p^.header.table_lock);
         IF io_completion_table_p^.header.recovery_action_required > 0 THEN
            cmp$get_number_of_io_entries (number_of_io_entries);
            /search_for_task_io/
            FOR io_index := 1 TO number_of_io_entries DO
              cmp$get_io_completion_tbl_entry (io_index, io_completion_table_entry_p);
              IF NOT io_completion_table_entry_p^.available THEN
                  IF io_completion_table_entry_p^.global_task_id = global_task_id THEN
                    iop$set_status_abnormal (ioe$ssiot_recovery_required,
                       'Recovery action required on outstanding io requests - IOMSSIOCT',
                       status);
                    EXIT /search_for_task_io/;
                  IFEND;
              IFEND;
            FOREND /search_for_task_io/;
         IFEND;
         osp$clear_job_signature_lock (io_completion_table_p^.header.table_lock);
      IFEND;

    PROCEND cmp$ssiot_recovery_complete;
?? TITLE := '  [XDCL, #GATE] cmp$destroy_io_completion_tb_r1', EJECT ??

*copyc cmh$destroy_io_completion_tb_r1

  PROCEDURE [XDCL, #GATE] cmp$destroy_io_completion_tb_r1 (VAR status: ost$status);

    VAR
      table_index: cmt$io_completion_queue_index,
      wired_heap_p: ^ost$heap,
      io_completion_table_p: ^cmt$io_completion_table;

    status.normal := TRUE;

    get_io_completion_table_address (io_completion_table_p);
    IF io_completion_table_p = NIL THEN
      RETURN;
    IFEND;

    IF io_completion_table_p^.header.entries_in_use <> 0 THEN
      iop$set_status_abnormal (ioe$io_completion_table_error,
        'Trying to destroy io completion table with outstanding io - IOMSSIOCT', status);
    IFEND;

    wired_heap_p := osv$mainframe_wired_cb_heap;

    FOR table_index := 1 TO cmc$max_subsystem_io_requests DO
       IF io_completion_table_p^.entries [table_index].wired_unit_queue_request_p <> NIL THEN
          FREE io_completion_table_p^.entries [table_index].wired_unit_queue_request_p^.
               wired_pp_response_p IN wired_heap_p^;
          FREE io_completion_table_p^.entries [table_index].wired_unit_queue_request_p^.
               wired_io_request_p IN wired_heap_p^;
          FREE io_completion_table_p^.entries [table_index].wired_unit_queue_request_p^.
               wired_data_command_descript_p IN wired_heap_p^;
          FREE io_completion_table_p^.entries [table_index].wired_unit_queue_request_p^.
               wired_command_heap_p IN wired_heap_p^;
          FREE io_completion_table_p^.entries [table_index].wired_unit_queue_request_p^.
               monitor_request_block_p IN wired_heap_p^;
          FREE io_completion_table_p^.entries [table_index].wired_unit_queue_request_p IN wired_heap_p^;
       IFEND;
    FOREND;

{   FREE io_completion_table_p IN osv$job_fixed_heap^;
{   cmv$io_completion_table_p := io_completion_table_p;

    FREE cmv$subsys_io_responses_p IN osv$mainframe_wired_cb_heap^;

  PROCEND cmp$destroy_io_completion_tb_r1;
?? TITLE := '  [XDCL, #GATE] cmp$ssiot_recovery_processing', EJECT ??

*copyc cmh$ssiot_recovery_processing

    PROCEDURE [XDCL, #GATE] cmp$ssiot_recovery_processing (
           VAR status: ost$status);

       VAR
         clear_table_lock: boolean,
         lock_status: ost$signature_lock_status,
         io_completion_queue_index: cmt$io_completion_queue_index,
         number_of_io_entries: cmt$io_completion_queue_index,
         io_completion_table_entry_p: ^cmt$io_completion_table_entry,
         io_completion_table_p: ^cmt$io_completion_table;

      status.normal := TRUE;

      clear_table_lock := FALSE;

      get_io_completion_table_address (io_completion_table_p);
      IF io_completion_table_p <> NIL THEN
         osp$test_sig_lock (io_completion_table_p^.header.table_lock,
                            lock_status);
         IF lock_status <> osc$sls_locked_by_current_task THEN
            osp$set_job_signature_lock (io_completion_table_p^.header.table_lock);
            clear_table_lock := TRUE;
         IFEND;
         cmp$get_number_of_io_entries (number_of_io_entries);
         FOR io_completion_queue_index := 1 to number_of_io_entries DO
           cmp$get_io_completion_tbl_entry (io_completion_queue_index,
                              io_completion_table_entry_p);
           IF NOT io_completion_table_entry_p^.available THEN
              IF (io_completion_table_entry_p^.io_status = cmc$subsystem_io_started) OR
                 (io_completion_table_entry_p^.io_status = cmc$subsystem_io_completing) THEN
                 io_completion_table_p^.header.recovery_action_required :=
                       io_completion_table_p^.header.recovery_action_required + 1;
                 io_completion_table_entry_p^.io_status :=
                       cmc$subsystem_io_term_by_rec;
              IFEND;
           IFEND;
                 io_completion_table_entry_p^.wired_unit_queue_request_p := NIL;
         FOREND;
    ALLOCATE cmv$subsys_io_responses_p:[cmc$max_subsystem_io_requests]
             IN osv$mainframe_wired_cb_heap^;



         IF clear_table_lock THEN
           osp$clear_job_signature_lock (io_completion_table_p^.header.table_lock);
         IFEND;
      IFEND;

    PROCEND cmp$ssiot_recovery_processing;
?? TITLE := '  [XDCL, #GATE] cmp$get_io_completion_tbl_entry', EJECT ??

*copyc cmh$get_io_completion_tbl_entry

  PROCEDURE [INLINE] cmp$get_io_completion_tbl_entry (io_completion_queue_index:
    cmt$io_completion_queue_index;
    VAR io_completion_table_entry_p: ^cmt$io_completion_table_entry);

    VAR
      io_completion_table_p: ^cmt$io_completion_table;

    io_completion_table_entry_p := NIL;

    get_io_completion_table_address (io_completion_table_p);

    io_completion_table_entry_p := ^io_completion_table_p^.entries [io_completion_queue_index];

  PROCEND cmp$get_io_completion_tbl_entry;
?? TITLE := '  [XDCL, #GATE] cmp$get_number_of_io_entries', EJECT ??

*copyc cmh$get_number_of_io_entries

  PROCEDURE [INLINE] cmp$get_number_of_io_entries (VAR number_of_entries: cmt$io_completion_queue_index);

    number_of_entries := UPPERBOUND (cmv$io_completion_table_p^.entries);

  PROCEND cmp$get_number_of_io_entries;

?? TITLE := '  [XDCL, #GATE] cmp$get_ssiot_entry_avail_queue', EJECT ??

*copyc cmh$get_ssiot_entry_avail_queue

  PROCEDURE [XDCL, #GATE] cmp$get_ssiot_entry_avail_queue (VAR job_io_completion_queue_index:
    cmt$io_completion_queue_index);

    VAR
      io_completion_table_p: ^cmt$io_completion_table,
      global_task_id: ost$global_task_id,
      able_to_create_table: boolean,
      available_scan_variable: cmt$scan_variable,
      available_table_entry_p: ^cmt$io_completion_table_entry,
      available_entry_found: boolean,
      user_supplied_name: jmt$user_supplied_name,
      system_supplied_name: jmt$system_supplied_name,
      scan_index: integer,
      local_status: ost$status;

    job_io_completion_queue_index := 0;
    available_scan_variable := $cmt$scan_character_set ['A'];

    IF cmv$io_completion_table_p = NIL THEN
      create_io_completion_table (able_to_create_table);
      IF NOT able_to_create_table THEN
        iop$set_status_abnormal (ioe$io_completion_table_error,
          'Unable to create io completion table - IOMSSIOCT', local_status);
        RETURN;
      IFEND;
    IFEND;

    pmp$get_executing_task_gtid (global_task_id);
    pmp$get_job_names (user_supplied_name, system_supplied_name, local_status);
    get_io_completion_table_address (io_completion_table_p);

    osp$set_job_signature_lock (io_completion_table_p^.header.table_lock);

      #scan (available_scan_variable, io_completion_table_p^.header.entries_available,
             scan_index, available_entry_found);

        IF available_entry_found  THEN
          job_io_completion_queue_index := scan_index;
          io_completion_table_p^.header.entries_in_use := io_completion_table_p^.header.entries_in_use + 1;
          io_completion_table_p^.header.entries_available (job_io_completion_queue_index, 1) := 'N';
          cmp$get_io_completion_tbl_entry (job_io_completion_queue_index, available_table_entry_p);
          available_table_entry_p^.available := FALSE;
          available_table_entry_p^.global_task_id := global_task_id;
          available_table_entry_p^.job_name := system_supplied_name;
        ELSE
          iop$set_status_abnormal (ioe$io_completion_table_error,
            'available ssiot entry not free - IOMSSIOCT', local_status);
        IFEND;

      osp$clear_job_signature_lock (io_completion_table_p^.header.table_lock);

  PROCEND cmp$get_ssiot_entry_avail_queue;
?? TITLE := '  [XDCL, #GATE] cmp$ssiot_end_handler', EJECT ??

   PROCEDURE [XDCL, #GATE] cmp$ssiot_end_handler (termination_status: ost$status;
                      VAR status: ost$status);

      VAR
        lock_status: ost$signature_lock_status,
        number_of_io_entries: cmt$io_completion_queue_index,
        io_completion_queue_index: cmt$io_completion_queue_index,
        io_completion_table_entry_p: ^cmt$io_completion_table_entry,
        termination_with_outstanding_io: boolean,
        global_task_id: ost$global_task_id,
        io_completion_table_p: ^cmt$io_completion_table;

      status.normal := TRUE;

      termination_with_outstanding_io := FALSE;

      pmp$get_executing_task_gtid (global_task_id);

      get_io_completion_table_address (io_completion_table_p);
      IF io_completion_table_p <> NIL THEN
         osp$test_sig_lock (io_completion_table_p^.header.table_lock,
                            lock_status);
         IF lock_status <> osc$sls_locked_by_current_task THEN
           osp$set_job_signature_lock (io_completion_table_p^.header.table_lock);
         IFEND;

         cmp$get_number_of_io_entries (number_of_io_entries);

         /search_io_table/
         FOR io_completion_queue_index := 1 to number_of_io_entries DO
           cmp$get_io_completion_tbl_entry (io_completion_queue_index,
                              io_completion_table_entry_p);
           IF NOT io_completion_table_entry_p^.available THEN
              termination_with_outstanding_io :=
                 (io_completion_table_entry_p^.global_task_id = global_task_id);
                 IF termination_with_outstanding_io THEN
                    EXIT /search_io_table/;
                 IFEND;
           IFEND;
         FOREND /search_io_table/;

         osp$clear_job_signature_lock (io_completion_table_p^.header.table_lock);


    IFEND;

PROCEND cmp$ssiot_end_handler;
  ?? TITLE := '  [XDCL, #GATE] cmp$store_ssiot_entry_info', EJECT ??

*copyc cmh$store_ssiot_entry_info

  PROCEDURE [XDCL, #GATE] cmp$store_ssiot_entry_info (io_completion_queue_index:
    cmt$io_completion_queue_index;
        entry_information_p: ^cmt$ssiot_entry_information;
    VAR status: ost$status);

    VAR
      io_completion_table_entry_p: ^cmt$io_completion_table_entry,
      index: integer;

    status.normal := TRUE;

    cmp$get_io_completion_tbl_entry (io_completion_queue_index, io_completion_table_entry_p);
    IF io_completion_table_entry_p^.available THEN
      iop$set_status_abnormal (ioe$io_completion_table_error,
        'Trying to store information in available ssiot entry - IOMSSIOCT', status);
      RETURN;
    IFEND;



    FOR index := LOWERBOUND (entry_information_p^) TO UPPERBOUND (entry_information_p^) DO
      CASE entry_information_p^ [index].keyword OF

      = cmc$ssiote_io_status =
        io_completion_table_entry_p^.io_status := entry_information_p^ [index].io_status;

      = cmc$ssiote_null_entry =
        ;

      = cmc$ssiote_request =
        io_completion_table_entry_p^.io_request_type.kind :=
                                entry_information_p^ [index].io_type;
        io_completion_table_entry_p^.io_request_type.element_name :=
                                entry_information_p^ [index].element_name;

      = cmc$ssiote_request_created =
        io_completion_table_entry_p^.time_request_created :=
                    entry_information_p^ [index].time_request_created;

      = cmc$ssiote_request_id =
        io_completion_table_entry_p^.request_identification := entry_information_p^ [index].request_id;
        io_completion_table_entry_p^.subsystem_response_p :=
                    entry_information_p^ [index].subsystem_response_p;
        io_completion_table_entry_p^.data_command_descriptors_p :=
                    entry_information_p^ [index].data_command_descriptors_p;

      = cmc$ssiote_wait_for_io_complete =
        io_completion_table_entry_p^.io_request_type.wait_for_io_completion :=
                              entry_information_p^ [index].wait_for_io_completion;

      = cmc$ssiote_wired_request =
        io_completion_table_entry_p^.wired_unit_queue_request_p :=
                                entry_information_p^ [index].wired_request_p;

      ELSE
        iop$set_status_abnormal (ioe$io_completion_table_error,
          'Attempt to store unsupported ssiot entry field - IOMSSIOCT', status);
        RETURN;
      CASEND;

    FOREND;


  PROCEND cmp$store_ssiot_entry_info;

?? OLDTITLE ??


?? TITLE := '  [XDCL, #GATE] cmp$ssiot_termination_cleanup', EJECT ??


  PROCEDURE [XDCL, #GATE] cmp$ssiot_termination (VAR status: ost$status);

    VAR
      table_index: cmt$io_completion_queue_index,
      wired_heap_p: ^ost$heap,
      count: integer,
      limit: integer,
      io_completion_table_p: ^cmt$io_completion_table,
      total_entries: integer,
      queue_index: cmt$io_completion_queue_index;


    status.normal := TRUE;
    get_io_completion_table_address (io_completion_table_p);
    IF io_completion_table_p = NIL THEN
      RETURN;
    IFEND;

    IF io_completion_table_p^.header.entries_in_use = 0 THEN
      RETURN;
    ELSE
      total_entries := io_completion_table_p^.header.entries_in_use;
    IFEND;

    wired_heap_p := osv$mainframe_wired_cb_heap;

    limit := io_completion_table_p^.header.available_entries;
     count := 0;
     table_index := 1;

    WHILE  count < total_entries  DO
       IF (io_completion_table_p^.entries [table_index].wired_unit_queue_request_p <> NIL) AND
         (NOT io_completion_table_p^.entries [table_index].available) THEN
        queue_index := io_completion_table_p^.entries[table_index].request_identification.system_supplied;
        io_completion_table_p^.entries [table_index].io_status := cmc$subsystem_cleanup_req;
        iop$unlock_the_rma_list (queue_index,status);
          IF NOT status.normal THEN
{            RETURN;
{ Even if status is bad try to Free the table space
          IFEND;

          FREE io_completion_table_p^.entries [table_index].wired_unit_queue_request_p^.
               wired_pp_response_p IN wired_heap_p^;
          FREE io_completion_table_p^.entries [table_index].wired_unit_queue_request_p^.
               wired_io_request_p IN wired_heap_p^;
          FREE io_completion_table_p^.entries [table_index].wired_unit_queue_request_p^.
               wired_data_command_descript_p IN wired_heap_p^;
          FREE io_completion_table_p^.entries [table_index].wired_unit_queue_request_p^.
               wired_command_heap_p IN wired_heap_p^;
          FREE io_completion_table_p^.entries [table_index].wired_unit_queue_request_p^.
               monitor_request_block_p IN wired_heap_p^;
          FREE io_completion_table_p^.entries [table_index].wired_unit_queue_request_p IN wired_heap_p^;
       IFEND;
       count := count + 1;
       table_index := table_index + 1;
    WHILEND;

  cmv$io_completion_table_p := io_completion_table_p;

  IF cmv$subsys_io_responses_p <> NIL THEN
    FREE cmv$subsys_io_responses_p IN osv$mainframe_wired_cb_heap^;
  IFEND;

  PROCEND cmp$ssiot_termination;



 PROCEDURE [XDCL] iop$unlock_the_rma_list (job_io_completion_queue_index:
        cmt$io_completion_queue_index;
    VAR status: ost$status);


  status.normal := TRUE;

  cmp$unlock_the_rma_list (job_io_completion_queue_index, status);

 PROCEND iop$unlock_the_rma_list;




 PROCEDURE [XDCL, #GATE] cmp$check_foreign_io (system_job_name:
  jmt$system_supplied_name;
  user_job_name: jmt$user_supplied_name;
 VAR match: boolean);


 VAR
   number_of_entries: cmt$io_completion_queue_index,
   io_completion_table_p: ^cmt$io_completion_table,
   completion_queue_index: cmt$io_completion_queue_index,
   completion_table_entry: ^cmt$io_completion_table_entry;

   match := FALSE;


{Special case archive for now.
               IF user_job_name (1,8) = '$_CSS__$' THEN
                  match := true;
                   RETURN;
               IFEND;


  get_io_completion_table_address (io_completion_table_p);
    IF io_completion_table_p = NIL THEN
      RETURN;
    IFEND;


   cmp$get_number_of_io_entries (number_of_entries);

   FOR  completion_queue_index := 1 TO number_of_entries DO
     cmp$get_io_completion_tbl_entry (completion_queue_index,
       completion_table_entry);
        IF NOT completion_table_entry^.available THEN
           IF completion_table_entry^.job_name = system_job_name THEN
              match := TRUE;
              RETURN;


           IFEND;
        IFEND;
   FOREND;



 PROCEND cmp$check_foreign_io;

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

PROCEDURE [XDCL, #GATE] cmp$set_ioct_serial_lock
          (VAR status: ost$status);

        status.normal := TRUE;
        osp$set_signature_lock (cmv$ioct_serial_lock, osc$wait, status);
PROCEND cmp$set_ioct_serial_lock;

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

PROCEDURE  [XDCL, #GATE] cmp$clear_ioct_serial_lock
           (VAR status: ost$status);

        status.normal := TRUE;
        osp$clear_signature_lock (cmv$ioct_serial_lock, status);

PROCEND cmp$clear_ioct_serial_lock;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$update_error_count' , EJECT ??

PROCEDURE [XDCL, #GATE] cmp$update_error_count
          (VAR status: ost$status);

         status.normal := TRUE;
         cmv$throwaway_count := cmv$throwaway_count + 1;
PROCEND cmp$update_error_count;

?? NEWTITLE := 'cmp$test_ioct_serial_lock', EJECT ??

PROCEDURE  [XDCL, #GATE] cmp$test_and_clear_ioct_lock
           (VAR status: ost$status);

        VAR
          lock_status: ost$signature_lock_status;

        status.normal := TRUE;
        osp$test_signature_lock (cmv$ioct_serial_lock, lock_status);
        IF lock_status = osc$sls_locked_by_current_task THEN
        osp$clear_signature_lock (cmv$ioct_serial_lock, status);
        IFEND;


PROCEND cmp$test_and_clear_ioct_lock;

?? NEWTITLE := 'cmp$down_foreign_io', EJECT ??


  PROCEDURE [XDCL, #GATE] cmp$down_foreign_io (request_id: cmt$subsystem_io_request_id;
                                            VAR status: ost$status);

    VAR
      element_name: cmt$element_name,
      job_io_completion_queue_index: cmt$io_completion_queue_index,
      io_completion_table_entry_p: ^cmt$io_completion_table_entry,
      logical_pp_number: iot$pp_number;



      status.normal := TRUE;

      job_io_completion_queue_index := request_id.system_supplied;

      cmp$get_io_completion_tbl_entry (job_io_completion_queue_index, io_completion_table_entry_p);

      element_name := io_completion_table_entry_p^.io_request_type.element_name;

      cmv$downed_foreign_element := element_name;
      cmv$foreign_interface_down := TRUE;
      cmv$foreign_down_time := #free_running_clock (0);

PROCEND cmp$down_foreign_io;


PROCEDURE [XDCL, #GATE] cmp$enable_foreign_io (VAR status: ost$status);

      status.normal := TRUE;

      cmv$downed_foreign_element := osc$null_name;
      cmv$foreign_interface_down := FALSE;
      cmv$foreign_down_time := 0;

PROCEND cmp$enable_foreign_io;



MODEND iom$subsystem_io_completion_tbl;
