
  PROCEDURE [INLINE] cmp$request_channels
    (    request_type: dst$resource_request_types;
         element_definition: cmt$element_definition;
         mainframe_id: pmt$mainframe_id;
     VAR status: ost$status);

?? PUSH (LISTEXT := ON) ??

    { PURPOSE:
    {   This inline procedure looks at all the upline connections of certain
    {   types of element and releases or acquires all channels connected to
    {   the element only if the channel state is OFF.
    { NOTE:
    {   This routine can only be called from ring 3 or below.

    VAR
      element_descriptor: cmt$element_descriptor,
      element_reservation: cmt$element_reservation,
      channel_definition: cmt$data_channel_definition,
      channel_index: integer,
      channel: cmt$physical_channel,
      iou_number: dst$iou_number,
      dummy_physical_pp: dst$iou_resource,
      peripheral_index: integer;

    status.normal := TRUE;
    IF (request_type <> dsc$rrt_get_channel) AND (request_type <> dsc$rrt_return_channel) THEN
      RETURN;
    IFEND;

    element_descriptor.element_type := cmc$data_channel_element;
    element_descriptor.channel_descriptor.use_logical_identification := TRUE;
    CASE element_definition.element_type OF
    = cmc$controller_element =

      { Release all channels connected to controller to the real state system.

      FOR channel_index := LOWERVALUE (cmt$controller_port_number)
            TO UPPERVALUE (cmt$controller_port_number) DO
        IF element_definition.controller.connection.port [channel_index].configured AND
              (element_definition.controller.connection.port [channel_index].upline_connection_type =
              cmc$data_channel_element) THEN
          IF element_definition.controller.connection.port [channel_index].mainframe_ownership =
                mainframe_id THEN
            element_descriptor.channel_descriptor.name :=
                  element_definition.controller.connection.port [channel_index].element_name;
            element_descriptor.channel_descriptor.iou :=
                  element_definition.controller.connection.port [channel_index].iou;
            cmp$search_peripheral_table (element_descriptor, element_reservation, FALSE,
                  peripheral_index, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
            IF cmv$peripheral_element_table.pointer^ [peripheral_index].element_status.state = cmc$off THEN
              cmp$get_channel_def (element_descriptor.channel_descriptor, channel_definition, status);
              IF NOT status.normal THEN
                RETURN;
              IFEND;
              channel.number := channel_definition.number;
              channel.concurrent := channel_definition.concurrent;
              channel.port := channel_definition.port;
              cmp$convert_iou_name (channel_definition.iou, iou_number, status);
              IF NOT status.normal THEN
                RETURN;
              IFEND;
              IF request_type = dsc$rrt_return_channel THEN
                cmp$release_channel_resource (channel, iou_number, status);
              ELSEIF request_type = dsc$rrt_get_channel THEN
                cmp$acquire_resources (request_type, channel, iou_number, 0, 0, FALSE, FALSE,
                      FALSE, dummy_physical_pp, status);
              IFEND;
              IF NOT status.normal THEN
                RETURN;
              IFEND;
            IFEND;
          IFEND;
        IFEND;
      FOREND;

    = cmc$communications_element =
      FOR channel_index := LOWERVALUE (cmt$communications_port_number)
            TO UPPERVALUE (cmt$communications_port_number) DO
        IF element_definition.communications_element.connection.port [channel_index].configured AND
              (element_definition.communications_element.connection.port [channel_index].
              upline_connection_type = cmc$data_channel_element) THEN
          IF element_definition.communications_element.connection.port [channel_index].mainframe_ownership =
                mainframe_id THEN
            element_descriptor.channel_descriptor.name :=
                  element_definition.communications_element.connection.port [channel_index].element_name;
            element_descriptor.channel_descriptor.iou :=
                  element_definition.communications_element.connection.port [channel_index].iou;
            cmp$search_peripheral_table (element_descriptor, element_reservation, FALSE, peripheral_index,
                  status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
            IF cmv$peripheral_element_table.pointer^ [peripheral_index].element_status.state = cmc$off THEN
              cmp$get_channel_def (element_descriptor.channel_descriptor, channel_definition, status);
              IF NOT status.normal THEN
                RETURN;
              IFEND;
              channel.number := channel_definition.number;
              channel.concurrent := channel_definition.concurrent;
              channel.port := channel_definition.port;
              cmp$convert_iou_name (channel_definition.iou, iou_number, status);
              IF NOT status.normal THEN
                RETURN;
              IFEND;
              IF request_type = dsc$rrt_return_channel THEN
                cmp$release_channel_resource (channel, iou_number, status);
              ELSEIF request_type = dsc$rrt_get_channel THEN
                cmp$acquire_resources (request_type, channel, iou_number, 0, 0, FALSE, FALSE, FALSE,
                      dummy_physical_pp, status);
              IFEND;
              IF NOT status.normal THEN
                RETURN;
              IFEND;
            IFEND;
          IFEND;
        IFEND;
      FOREND;

    = cmc$storage_device_element =
      FOR channel_index := LOWERVALUE (cmt$data_storage_port_number) TO
            UPPERVALUE (cmt$data_storage_port_number) DO
        IF element_definition.storage_device.connection.port [channel_index].configured AND
              (element_definition.storage_device.connection.port [channel_index].upline_connection_type =
              cmc$data_channel_element) THEN
          IF element_definition.storage_device.connection.port [channel_index].mainframe_ownership =
                mainframe_id THEN
            element_descriptor.channel_descriptor.name :=
                  element_definition.storage_device.connection.port [channel_index].element_name;
            element_descriptor.channel_descriptor.iou :=
                  element_definition.storage_device.connection.port [channel_index].iou;
            cmp$search_peripheral_table (element_descriptor, element_reservation, FALSE,
                  peripheral_index, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
            IF cmv$peripheral_element_table.pointer^ [peripheral_index].element_status.state = cmc$off THEN
              cmp$get_channel_def (element_descriptor.channel_descriptor, channel_definition, status);
              IF NOT status.normal THEN
                RETURN;
              IFEND;
              channel.number := channel_definition.number;
              channel.concurrent := channel_definition.concurrent;
              channel.port := channel_definition.port;
              cmp$convert_iou_name (channel_definition.iou, iou_number, status);
              IF NOT status.normal THEN
                RETURN;
              IFEND;
              IF request_type = dsc$rrt_return_channel THEN
                cmp$release_channel_resource (channel, iou_number, status);
              ELSEIF request_type = dsc$rrt_get_channel THEN
                cmp$acquire_resources (request_type, channel, iou_number, 0, 0, FALSE, FALSE, FALSE,
                      dummy_physical_pp, status);
              IFEND;
              IF NOT status.normal THEN
                RETURN;
              IFEND;
            IFEND;
          IFEND;
        IFEND;
      FOREND;

    ELSE
    CASEND;

  PROCEND cmp$request_channels;

*copyc cmp$acquire_resources
*copyc cmp$convert_iou_name
*copyc cmp$get_channel_def
*copyc cmp$release_channel_resource
*copyc cmt$element_definition
*copyc ost$status
?? POP ??
