MODULE iom$mass_storage_io;
?? RIGHT := 110 ??

{Purpose: Support the Mass Storage IO request in system core.

?? NEWTITLE := 'Global Declarations Referenced By This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc syc$monitor_request_codes
*copyc ioe$st_errors
*copyc dmt$ms_logical_device_address
*copyc iot$completion_status
*copyc iot$io_function
*copyc iot$rb_device_io
*copyc ost$hardware_subranges
*copyc ost$status
?? POP ??
*copyc i#call_monitor
*copyc mmp$wait_io_completion
*copyc osp$append_status_integer
*copyc osp$set_status_condition
*copyc pmp$delay
*copyc osv$mainframe_wired_cb_heap
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] IOP$MASS_STORAGE_IO', EJECT ??

  PROCEDURE [XDCL, #GATE] iop$mass_storage_io
    (    pva: ^cell;
         length: ost$byte_count;
         io_function: iot$io_function;
         device_address: dmt$ms_logical_device_address;
         wait_completion: boolean;
     VAR p_completion_status: ^iot$completion_status;
     VAR status: ost$status);

    VAR
      completion_status_p: ^iot$completion_status,
      request_block: iot$rb_device_io,
      wait: boolean;

    status.normal := TRUE;

  /process_request/
    BEGIN
      IF wait_completion THEN
        ALLOCATE completion_status_p IN osv$mainframe_wired_cb_heap^;
      IFEND;

    /queue_request/
      WHILE TRUE DO
        status.normal := TRUE;
        request_block.request_code := syc$rc_device_io;
        request_block.pva := pva;
        request_block.length := length;
        request_block.io_function := io_function;
        request_block.device_address := device_address;
        IF wait_completion THEN
          request_block.completion := completion_status_p;
        ELSE
          request_block.completion := p_completion_status;
        IFEND;
        request_block.completion^ := 0;

        i#call_monitor (#LOC (request_block), #SIZE (request_block));
        IF request_block.status.normal = TRUE THEN
          EXIT /queue_request/; {----->
        ELSEIF request_block.status.condition = ioe$unit_disabled THEN
          osp$set_status_condition (request_block.status.condition, status);
          EXIT /process_request/; {----->
        IFEND;
      WHILEND /queue_request/;

      wait := wait_completion;

    /wait_for_completion/
      WHILE wait DO
        IF pva <> NIL THEN
          mmp$wait_io_completion (pva, status);
        ELSE
          pmp$delay (1, status);
        IFEND;
        IF status.normal = FALSE THEN
          EXIT /process_request/; {----->
        IFEND;
        IF request_block.completion^ <> 0 THEN
          EXIT /wait_for_completion/; {----->
        IFEND;
      WHILEND /wait_for_completion/;

      IF (request_block.completion^ <> 1) AND wait_completion THEN
        osp$set_status_condition (ioe$unrecovered_disk_error, status);
        osp$append_status_integer (osc$status_parameter_delimiter, device_address.logical_unit_number, 10,
              FALSE, status);
      IFEND;
    END /process_request/;

    IF wait_completion THEN
      FREE completion_status_p IN osv$mainframe_wired_cb_heap^;
    IFEND;

  PROCEND iop$mass_storage_io;
?? OLDTITLE ??
MODEND iom$mass_storage_io;
