MODULE dmm$tape_reservation_113;
*copyc osd$default_pragmats
?? PUSH (LIST := ON) ??
?? NEWTITLE := 'Resource Management: Perform mainframe tape unit scheduling',
      EJECT ??
?? NEWTITLE := 'Global variables declared by this module', EJECT ??
{ System tape table pointer.

  VAR
    dmv$p_system_tape_table: [XDCL, #GATE, STATIC,
          oss$mainframe_pageable] ^dmt$system_tape_table := NIL;

{ System tape table lock.

  VAR
    dmv$system_tape_table_lock: [XDCL, STATIC, oss$mainframe_pageable]
          ost$signature_lock := [0];

{  There is no signature lock for dmv$p_tape_reservations^ table because
{  it is always accessed at the same time as dmv$p_system_tape_table^ in
{  which case dmv$system_tape_table_lock must be set.

  VAR
    dmv$p_tape_reservations: [XDCL, #GATE, STATIC,
          oss$mainframe_pageable] ^dmt$tape_reservations := NIL;

?? OLDTITLE ??
?? NEWTITLE := 'Global variables referenced by this module', EJECT ??
*copyc cmv$logical_unit_table
*copyc iov$number_of_tape_units
*copyc iov$tusl_lock
*copyc iov$tusl_p
*copyc osv$mainframe_pageable_heap
*copyc oss$mainframe_pageable
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
*copyc rmc$highest_unit_type
*copyc rmt$tape_unit_types
?? OLDTITLE ??
?? NEWTITLE := 'External procedures referenced by this module', EJECT ??
*copyc cmp$get_element_name_via_lun
*copyc iop$ready_waiting_tape_tasks
*copyc osp$append_status_parameter
*copyc osp$clear_mainframe_sig_lock
*copyc osp$set_status_abnormal
*copyc osp$test_set_main_sig_lock
*copyc osp$test_sig_lock
*copyc pmp$get_job_names
?? PUSH (LIST := OFF) ??
*copyc dmt$system_tape_table
*copyc dme$tape_errors
*copyc dmt$tape_reservations
*copyc iot$no_of_tape_units
*copyc ost$signature_lock
*copyc rmc$maximum_density
*copyc rmt$tape_class
*copyc rmt$tape_reservation
?? POP ??

?? OLDTITLE ??
?? NEWTITLE := 'clear_mainframe_sig_lock', EJECT ??

  PROCEDURE clear_mainframe_sig_lock
    (VAR lock: ost$signature_lock);

    VAR
      lock_status: ost$signature_lock_status,
      locked: boolean;

      osp$test_sig_lock (lock, lock_status);
      IF lock_status = osc$sls_locked_by_current_task THEN
        osp$clear_mainframe_sig_lock  (lock);
      IFEND;

  PROCEND clear_mainframe_sig_lock;

?? OLDTITLE ??
?? NEWTITLE := 'set_mainframe_sig_lock', EJECT ??

  PROCEDURE set_mainframe_sig_lock
    (    lock_string: string ( * <= osc$max_string_size);
     VAR lock: ost$signature_lock;
     VAR status: ost$status);

    VAR
      local_status: ost$status,
      lock_status: ost$signature_lock_status,
      locked: boolean;

      status.normal := TRUE;

      osp$test_sig_lock (lock, lock_status);
      IF lock_status = osc$sls_locked_by_current_task THEN
        osp$clear_mainframe_sig_lock (lock);
      ELSEIF lock_status = osc$sls_locked_by_another_task THEN
        osp$set_status_abnormal (rmc$resource_management_id, dme$unable_to_lock_tape_table, lock_string,
              status);
      IFEND;

      IF status.normal THEN
        osp$test_set_main_sig_lock (lock, locked);
        IF NOT locked THEN
          osp$set_status_abnormal (rmc$resource_management_id, dme$unable_to_lock_tape_table, lock_string,
                status);
        IFEND;
      IFEND;

  PROCEND set_mainframe_sig_lock;

?? OLDTITLE ??
?? NEWTITLE := 'dmp$acquire_tape_resources', EJECT ??

  PROCEDURE [XDCL, #GATE] dmp$acquire_tape_resource
    (    reservation: rmt$tape_reservation;
     VAR reserve_complete: boolean;
     VAR status: ost$status);

    VAR
      density: rmt$density,
      stt: ^dmt$system_tape_table,
      units_needed: integer,
      ut: rmt$tape_unit_types;

    reserve_complete := FALSE;

    set_mainframe_sig_lock ('DMV$SYSTEM_TAPE_TABLE_LOCK', dmv$system_tape_table_lock, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  /acquire_tape_resource/
    BEGIN
      IF (dmv$p_system_tape_table = NIL) THEN
        dmp$create_stt (status);
        IF NOT status.normal THEN
          EXIT /acquire_tape_resource/;
        IFEND;
      IFEND;

{ Create local copy of the system_tape_table.

      PUSH stt;
      stt^ := dmv$p_system_tape_table^;

{ Determine if configuration limits exceeded.

      IF (reservation [rmc$800] > stt^ [rmc$hd_pe].defined_tape) OR
            (reservation [rmc$1600] > (stt^ [rmc$hd_pe].defined_tape + stt^ [rmc$pe_ge].defined_tape)) OR
            (reservation [rmc$6250] > stt^ [rmc$pe_ge].defined_tape) OR
            (reservation [rmc$38000] > stt^ [rmc$cartridge].defined_tape) OR
            ((reservation [rmc$800] + reservation [rmc$1600] + reservation [rmc$6250]) >
            (stt^ [rmc$hd_pe].defined_tape + stt^ [rmc$pe_ge].defined_tape)) THEN
        osp$set_status_abnormal (rmc$resource_management_id, dme$tape_configuration_exceeded, '', status);
        EXIT /acquire_tape_resource/;
      ELSEIF (reservation [rmc$800] > stt^ [rmc$hd_pe].number_on) OR
            (reservation [rmc$1600] > (stt^ [rmc$hd_pe].number_on + stt^ [rmc$pe_ge].number_on)) OR
            (reservation [rmc$6250] > stt^ [rmc$pe_ge].number_on) OR
            (reservation [rmc$38000] > stt^ [rmc$cartridge].number_on) OR
            ((reservation [rmc$800] + reservation [rmc$1600] + reservation [rmc$6250]) >
            (stt^ [rmc$hd_pe].number_on + stt^ [rmc$pe_ge].number_on)) THEN
        osp$set_status_abnormal (rmc$resource_management_id, dme$not_enough_in_on_state, '', status);
        EXIT /acquire_tape_resource/;
      IFEND;

      FOR density := rmc$800 TO rmc$maximum_density DO
        IF reservation [density] > 0 THEN
          CASE density OF

          = rmc$800 =
            IF reservation [density] <= (stt^ [rmc$hd_pe].number_on - stt^ [rmc$hd_pe].
                  lower_density_reserved - stt^ [rmc$hd_pe].higher_density_reserved) THEN
              { reserve possible
              stt^ [rmc$hd_pe].lower_density_reserved :=
                    stt^ [rmc$hd_pe].lower_density_reserved + reservation [density];
            ELSE { determine if 1600 reserves can be moved to other unit type
              IF stt^ [rmc$hd_pe].higher_density_reserved = 0 THEN
                EXIT /acquire_tape_resource/;
              ELSE
                units_needed := reservation [density] - (stt^ [rmc$hd_pe].number_on -
                      stt^ [rmc$hd_pe].lower_density_reserved - stt^ [rmc$hd_pe].higher_density_reserved);
                IF units_needed <= stt^ [rmc$pe_ge].number_on - stt^ [rmc$pe_ge].lower_density_reserved -
                      stt^ [rmc$pe_ge].higher_density_reserved THEN
                  stt^ [rmc$hd_pe].higher_density_reserved :=
                        stt^ [rmc$hd_pe].higher_density_reserved - units_needed;
                  stt^ [rmc$pe_ge].lower_density_reserved :=
                        stt^ [rmc$pe_ge].lower_density_reserved + units_needed;
                  stt^ [rmc$hd_pe].lower_density_reserved :=
                        stt^ [rmc$hd_pe].lower_density_reserved + reservation [density];
                ELSE
                  EXIT /acquire_tape_resource/;
                IFEND;
              IFEND;
            IFEND;

          = rmc$1600 =
            IF reservation [density] <= (stt^ [rmc$hd_pe].number_on - stt^ [rmc$hd_pe].
                  lower_density_reserved - stt^ [rmc$hd_pe].higher_density_reserved) +
                  (stt^ [rmc$pe_ge].number_on - stt^ [rmc$pe_ge].lower_density_reserved -
                  stt^ [rmc$pe_ge].higher_density_reserved) THEN { reserve possible
              IF reservation [density] <= (stt^ [rmc$hd_pe].number_on -
                    stt^ [rmc$hd_pe].lower_density_reserved - stt^ [rmc$hd_pe].higher_density_reserved) THEN
                stt^ [rmc$hd_pe].higher_density_reserved :=
                      stt^ [rmc$hd_pe].higher_density_reserved + reservation [density];
              ELSE
                units_needed := reservation [density] - (stt^ [rmc$hd_pe].number_on -
                      stt^ [rmc$hd_pe].lower_density_reserved - stt^ [rmc$hd_pe].higher_density_reserved);
                stt^ [rmc$hd_pe].higher_density_reserved :=
                      stt^ [rmc$hd_pe].higher_density_reserved + reservation [density] - units_needed;
                stt^ [rmc$pe_ge].lower_density_reserved :=
                      stt^ [rmc$pe_ge].lower_density_reserved + units_needed;
              IFEND;
            ELSE
              EXIT /acquire_tape_resource/;
            IFEND;

          = rmc$6250 =
            IF reservation [density] <= (stt^ [rmc$pe_ge].number_on -
                  stt^ [rmc$pe_ge].lower_density_reserved - stt^ [rmc$pe_ge].higher_density_reserved) THEN
              stt^ [rmc$pe_ge].higher_density_reserved :=
                    stt^ [rmc$pe_ge].higher_density_reserved + reservation [density];
            ELSE { determine if 1600 reserves can be moved to other unit type
              IF stt^ [rmc$pe_ge].lower_density_reserved = 0 THEN
                { none to move, reserve cannot be done
                EXIT /acquire_tape_resource/;
              ELSE
                units_needed := reservation [density] - (stt^ [rmc$pe_ge].number_on -
                      stt^ [rmc$pe_ge].lower_density_reserved - stt^ [rmc$pe_ge].higher_density_reserved);
                IF units_needed <= stt^ [rmc$hd_pe].number_on - stt^ [rmc$hd_pe].lower_density_reserved -
                      stt^ [rmc$hd_pe].higher_density_reserved THEN
                  stt^ [rmc$pe_ge].lower_density_reserved :=
                        stt^ [rmc$pe_ge].lower_density_reserved - units_needed;
                  stt^ [rmc$hd_pe].higher_density_reserved :=
                        stt^ [rmc$hd_pe].higher_density_reserved + units_needed;
                  stt^ [rmc$pe_ge].higher_density_reserved :=
                        stt^ [rmc$pe_ge].higher_density_reserved + reservation [density];
                ELSE
                  EXIT /acquire_tape_resource/;
                IFEND;
              IFEND;
            IFEND;

          = rmc$38000 =
            IF reservation [density] <= (stt^ [rmc$cartridge].number_on -
                  stt^ [rmc$cartridge].lower_density_reserved) THEN
              stt^ [rmc$cartridge].lower_density_reserved :=
                    stt^ [rmc$cartridge].lower_density_reserved + reservation [density];
            ELSE
              EXIT /acquire_tape_resource/;
            IFEND;
          ELSE
          CASEND;
        IFEND;
      FOREND;

{ Log the reservations for the VED TAPE_RESERVATION display.

      FOR density := rmc$800 TO rmc$maximum_density DO
        IF reservation [density] > 0 THEN
          dmp$log_tape_reservation (density, reservation [density], status);
          IF NOT status.normal THEN
            EXIT /acquire_tape_resource/;
          IFEND;
        IFEND;
      FOREND;

{ Update real system_tape table from local copy and clear table lock.

      reserve_complete := TRUE;
      dmv$p_system_tape_table^ := stt^;
    END /acquire_tape_resource/;

    clear_mainframe_sig_lock (dmv$system_tape_table_lock);

  PROCEND dmp$acquire_tape_resource;

?? OLDTITLE ??
?? NEWTITLE := 'dmp$convert_unit_type', EJECT ??

  PROCEDURE dmp$convert_unit_type
    (    io_unit_type: iot$unit_type;
     VAR dm_unit_type: rmt$tape_unit_types);

    CASE io_unit_type OF
    = ioc$dt_mt679_2, ioc$dt_mt679_3, ioc$dt_mt679_4 =
      dm_unit_type := rmc$hd_pe;

    = ioc$dt_mt679_5, ioc$dt_mt679_6, ioc$dt_mt679_7, ioc$dt_mt639_1,
          ioc$dt_mt698_3x =
      dm_unit_type := rmc$pe_ge;

    = ioc$dt_mt5682_1x =
      dm_unit_type := rmc$cartridge;
    ELSE
    CASEND;

  PROCEND dmp$convert_unit_type;

?? OLDTITLE ??
?? NEWTITLE := 'dmp$create_stt', EJECT ??

  PROCEDURE [XDCL] dmp$create_stt
    (VAR status: ost$status);

    VAR
      dt: rmt$tape_unit_types,
      ut: iot$logical_unit;

    status.normal := TRUE;

    ALLOCATE dmv$p_system_tape_table IN osv$mainframe_pageable_heap^;

{ Initialize system tape table.

    FOR dt := rmc$hd_pe TO rmc$highest_unit_type DO
      dmv$p_system_tape_table^ [dt].defined_tape := 0;
      dmv$p_system_tape_table^ [dt].number_on := 0;
      dmv$p_system_tape_table^ [dt].lower_density_reserved := 0;
      dmv$p_system_tape_table^ [dt].higher_density_reserved := 0;
    FOREND;

{ Count the number of tape units configured and ON.

    FOR ut := LOWERBOUND (cmv$logical_unit_table^) TO UPPERBOUND (cmv$logical_unit_table^) DO
      IF ((cmv$logical_unit_table^ [ut].unit_interface_table <> NIL) AND
            ((cmv$logical_unit_table^ [ut].unit_interface_table^.unit_type >= ioc$dt_mt679_5) AND
            (cmv$logical_unit_table^ [ut].unit_interface_table^.unit_type <= ioc$highest_tape_unit))) THEN
        dmp$convert_unit_type (cmv$logical_unit_table^ [ut].unit_interface_table^.unit_type, dt);
        dmv$p_system_tape_table^ [dt].defined_tape := dmv$p_system_tape_table^ [dt].defined_tape + 1;
        IF cmv$logical_unit_table^ [ut].configured THEN
          IF cmv$logical_unit_table^ [ut].status.assignable_device AND
                (cmv$logical_unit_table^ [ut].element_capability <> $cmt$element_capabilities []) AND
                (cmv$logical_unit_table^ [ut].element_capability <>
                $cmt$element_capabilities [cmc$concurrent_maintenance, cmc$dedicated_maintenance]) THEN
            dmv$p_system_tape_table^ [dt].number_on := dmv$p_system_tape_table^ [dt].number_on + 1;
          IFEND;
        IFEND;
      IFEND;
    FOREND;

  PROCEND dmp$create_stt;

?? OLDTITLE ??
?? NEWTITLE := 'dmp$log_tape_release', EJECT ??

  PROCEDURE dmp$log_tape_release
    (    density: rmt$supported_tape_densities;
         release_count: integer;
     VAR status: ost$status);

    VAR
      found: boolean,
      jsn: jmt$system_supplied_name,
      qrn: jmt$user_supplied_name,
      reserved: integer,
      unit: integer;

    pmp$get_job_names (qrn, jsn, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF (dmv$p_tape_reservations = NIL) THEN
      osp$set_status_abnormal (rmc$resource_management_id, dme$reserve_not_effected, '', status);
      RETURN;
    IFEND;

    found := FALSE;

  /main/
    FOR unit := LOWERBOUND (dmv$p_tape_reservations^) TO UPPERBOUND (dmv$p_tape_reservations^) DO
      IF NOT dmv$p_tape_reservations^ [unit].available AND
            (dmv$p_tape_reservations^ [unit].jsn = jsn) THEN
        dmv$p_tape_reservations^ [unit].unit_type [density] :=
              dmv$p_tape_reservations^ [unit].unit_type [density] - release_count;
        found := TRUE;
        EXIT /main/;
      IFEND;
    FOREND /main/;

    IF NOT found THEN
      osp$set_status_abnormal (rmc$resource_management_id, dme$unable_to_log_release, '', status);
      RETURN;
    IFEND;

    reserved := dmv$p_tape_reservations^ [unit].unit_type [rmc$800] +
          dmv$p_tape_reservations^ [unit].unit_type [rmc$1600] +
          dmv$p_tape_reservations^ [unit].unit_type [rmc$6250] +
          dmv$p_tape_reservations^ [unit].unit_type [rmc$38000];

    IF (reserved < 1) THEN
      dmv$p_tape_reservations^ [unit].available := TRUE;
    IFEND;

  PROCEND dmp$log_tape_release;

?? OLDTITLE ??
?? NEWTITLE := 'dmp$log_tape_reservation', EJECT ??

  PROCEDURE dmp$log_tape_reservation
    (    density: rmt$supported_tape_densities;
         reserve_count: integer;
     VAR status: ost$status);

    VAR
      found: boolean,
      jsn: jmt$system_supplied_name,
      qrn: jmt$user_supplied_name,
      reserved: integer,
      unit: integer;

    pmp$get_job_names (qrn, jsn, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF (dmv$p_tape_reservations = NIL) THEN

      ALLOCATE dmv$p_tape_reservations: [1 .. iov$number_of_tape_units + 1] IN
            osv$mainframe_pageable_heap^;

      FOR unit := LOWERBOUND (dmv$p_tape_reservations^) TO UPPERBOUND (dmv$p_tape_reservations^) DO
        dmv$p_tape_reservations^ [unit].available := TRUE;
        dmv$p_tape_reservations^ [unit].jsn := jmc$full_system_supplied_name;
        dmv$p_tape_reservations^ [unit].unit_type [rmc$800] := 0;
        dmv$p_tape_reservations^ [unit].unit_type [rmc$1600] := 0;
        dmv$p_tape_reservations^ [unit].unit_type [rmc$6250] := 0;
        dmv$p_tape_reservations^ [unit].unit_type [rmc$38000] := 0;
      FOREND;
    IFEND;

    found := FALSE;

{ See if an entry already exists for this job.

  /main/
    BEGIN
      FOR unit := LOWERBOUND (dmv$p_tape_reservations^) TO UPPERBOUND (dmv$p_tape_reservations^) DO
        IF (NOT dmv$p_tape_reservations^ [unit].available) AND
              (dmv$p_tape_reservations^ [unit].jsn = jsn) THEN
          dmv$p_tape_reservations^ [unit].unit_type [density] :=
                dmv$p_tape_reservations^ [unit].unit_type [density] + reserve_count;
          found := TRUE;
          EXIT /main/;
        IFEND;
      FOREND;

      FOR unit := LOWERBOUND (dmv$p_tape_reservations^) TO UPPERBOUND (dmv$p_tape_reservations^) DO
        IF dmv$p_tape_reservations^ [unit].available THEN
          dmv$p_tape_reservations^ [unit].available := FALSE;
          dmv$p_tape_reservations^ [unit].jsn := jsn;
          dmv$p_tape_reservations^ [unit].unit_type [density] := reserve_count;
          found := TRUE;
          EXIT /main/;
        IFEND;
      FOREND;
    END /main/;

    IF NOT found THEN
      osp$set_status_abnormal (rmc$resource_management_id, dme$unable_to_log_reservation, '', status);
      RETURN;
    IFEND;

  PROCEND dmp$log_tape_reservation;

?? OLDTITLE ??
?? NEWTITLE := 'dmp$return_tape_resource', EJECT ??

  PROCEDURE [XDCL, #GATE] dmp$return_tape_resource
    (    reservation: rmt$tape_reservation;
     VAR status: ost$status);

    VAR
      density: rmt$density,
      extra_units: integer;

    IF (dmv$p_system_tape_table = NIL) THEN
      osp$set_status_abnormal (rmc$resource_management_id, dme$reserve_not_effected, '', status);
      RETURN;
    IFEND;

    set_mainframe_sig_lock ('DMV$SYSTEM_TAPE_TABLE_LOCK', dmv$system_tape_table_lock, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  /return_tape_resource/
    BEGIN

{ Remove reservations from the VED TAPE_RESERVATIONS display.

      FOR density := rmc$800 TO rmc$maximum_density DO
        IF reservation [density] > 0 THEN
          dmp$log_tape_release (density, reservation [density], status);
          IF NOT status.normal THEN
            EXIT /return_tape_resource/;
          IFEND;
        IFEND;
      FOREND;

      FOR density := rmc$800 TO rmc$maximum_density DO
        IF (reservation [density] > 0) THEN

          CASE density OF
          = rmc$800 =
            dmv$p_system_tape_table^ [rmc$hd_pe].lower_density_reserved :=
                  dmv$p_system_tape_table^ [rmc$hd_pe].lower_density_reserved - reservation [density];

          = rmc$1600 =
            IF reservation [density] <= dmv$p_system_tape_table^ [rmc$hd_pe].higher_density_reserved THEN
              dmv$p_system_tape_table^ [rmc$hd_pe].higher_density_reserved :=
                    dmv$p_system_tape_table^ [rmc$hd_pe].higher_density_reserved - reservation [density];
            ELSE
              extra_units := reservation [density] - dmv$p_system_tape_table^ [rmc$hd_pe].
                    higher_density_reserved;
              dmv$p_system_tape_table^ [rmc$hd_pe].higher_density_reserved := 0;
              dmv$p_system_tape_table^ [rmc$pe_ge].lower_density_reserved :=
                    dmv$p_system_tape_table^ [rmc$pe_ge].lower_density_reserved - extra_units;
            IFEND;

          = rmc$6250 =
            dmv$p_system_tape_table^ [rmc$pe_ge].higher_density_reserved :=
                  dmv$p_system_tape_table^ [rmc$pe_ge].higher_density_reserved - reservation [density];

          = rmc$38000 =
            dmv$p_system_tape_table^ [rmc$cartridge].lower_density_reserved :=
                  dmv$p_system_tape_table^ [rmc$cartridge].lower_density_reserved - reservation [density];

          ELSE
          CASEND;
        IFEND;
      FOREND;
    END /return_tape_resource/;

    clear_mainframe_sig_lock (dmv$system_tape_table_lock);

  PROCEND dmp$return_tape_resource;

?? OLDTITLE ??
?? NEWTITLE := 'dmp$update_stt', EJECT ??

  PROCEDURE [XDCL, #GATE] dmp$update_stt
    (    lun: iot$logical_unit;
         old_state: cmt$element_state;
         new_state: cmt$element_state;
     VAR status: ost$status);

    VAR
      dt: rmt$tape_unit_types,
      element_name: ost$name,
      i: iot$no_of_tape_units;

    PROCEDURE update_the_tusl_entry
      (VAR status: ost$status);

      cmp$get_element_name_via_lun (lun, element_name, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

    /update_tusl_entry/
      FOR i := LOWERBOUND (iov$tusl_p^) TO UPPERBOUND (iov$tusl_p^) DO
        IF iov$tusl_p^ [i].element_name = element_name THEN
          set_mainframe_sig_lock ('IOV$TUSL_LOCK', iov$tusl_lock, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

          set_mainframe_sig_lock ('TUSL_ENTRY_LOCK', iov$tusl_p^ [i].lock, status);
          IF NOT status.normal THEN
            clear_mainframe_sig_lock (iov$tusl_lock);
            RETURN;
          IFEND;

          iov$tusl_p^ [i].tape_unit_state := new_state;
          IF new_state <> cmc$on THEN
            iov$tusl_p^ [i].evsn := rmc$unspecified_vsn;
            iov$tusl_p^ [i].rvsn := rmc$unspecified_vsn;
            iov$tusl_p^ [i].ssn := jmc$blank_system_supplied_name;
            iov$tusl_p^ [i].assignment_state := ioc$not_assigned;
            iov$tusl_p^ [i].unit_ready := FALSE;
            iov$tusl_p^ [i].read_error := FALSE;
            iov$tusl_p^ [i].detected_tape_characteristics.label_type := amc$labelled;
            iov$tusl_p^ [i].detected_tape_characteristics.character_set := amc$ascii;
            iov$tusl_p^ [i].detected_tape_characteristics.write_ring := FALSE;
            iov$tusl_p^ [i].detected_tape_characteristics.density := rmc$200;
          ELSE
            iop$ready_waiting_tape_tasks (iov$tusl_p^ [i].unit_type);
          IFEND;

          clear_mainframe_sig_lock (iov$tusl_p^ [i].lock);
          clear_mainframe_sig_lock (iov$tusl_lock);
          EXIT /update_tusl_entry/;
        IFEND;
      FOREND /update_tusl_entry/;

    PROCEND update_the_tusl_entry;

    set_mainframe_sig_lock ('DMV$SYSTEM_TAPE_TABLE_LOCK', dmv$system_tape_table_lock, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  /update_stt/
    BEGIN
      IF (dmv$p_system_tape_table = NIL) THEN
        dmp$create_stt (status);
        update_the_tusl_entry(status);
        EXIT /update_stt/;
      ELSE
        IF old_state = new_state THEN
          EXIT /update_stt/;
        IFEND;

        update_the_tusl_entry(status);
        dmp$convert_unit_type (cmv$logical_unit_table^ [lun].unit_interface_table^.unit_type, dt);
        IF ((old_state = cmc$off) OR (old_state = cmc$down)) AND (new_state = cmc$on) THEN
          dmv$p_system_tape_table^ [dt].number_on := dmv$p_system_tape_table^ [dt].number_on + 1;
        ELSEIF old_state = cmc$on THEN
          dmv$p_system_tape_table^ [dt].number_on := dmv$p_system_tape_table^ [dt].number_on - 1;
        IFEND;
      IFEND;
    END /update_stt/;

    clear_mainframe_sig_lock (dmv$system_tape_table_lock);

  PROCEND dmp$update_stt;

?? OLDTITLE ??
?? NEWTITLE := 'dmp$validate_tape_density', EJECT ??

  PROCEDURE [XDCL, #GATE] dmp$validate_tape_density
    (    density: rmt$density;
     VAR status: ost$status);

    set_mainframe_sig_lock ('DMV$SYSTEM_TAPE_TABLE_LOCK', dmv$system_tape_table_lock, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  /validate_tape_density/
    BEGIN

      IF (dmv$p_system_tape_table = NIL) THEN
        dmp$create_stt (status);
        IF NOT status.normal THEN
          EXIT /validate_tape_density/;
        IFEND;
      IFEND;

      CASE density OF

      = rmc$200 =
        osp$set_status_abnormal (rmc$resource_management_id, dme$density_not_supported, '200', status);

      = rmc$556 =
        osp$set_status_abnormal (rmc$resource_management_id, dme$density_not_supported, '556', status);

      = rmc$800 =
        IF dmv$p_system_tape_table^ [rmc$hd_pe].defined_tape = 0 THEN
          osp$set_status_abnormal (rmc$resource_management_id, dme$unit_type_not_configured, '800', status);
        IFEND;

      = rmc$1600 =
        IF (dmv$p_system_tape_table^ [rmc$hd_pe].defined_tape +
              dmv$p_system_tape_table^ [rmc$pe_ge].defined_tape = 0) THEN
          osp$set_status_abnormal (rmc$resource_management_id, dme$unit_type_not_configured, '1600', status);
        IFEND;

      = rmc$6250 =
        IF dmv$p_system_tape_table^ [rmc$pe_ge].defined_tape = 0 THEN
          osp$set_status_abnormal (rmc$resource_management_id, dme$unit_type_not_configured, '6250', status);
        IFEND;

      = rmc$38000 =
        IF dmv$p_system_tape_table^ [rmc$cartridge].defined_tape = 0 THEN
          osp$set_status_abnormal (rmc$resource_management_id, dme$unit_type_not_configured, '38000', status);
        IFEND;

      ELSE
      CASEND;

    END /validate_tape_density/;

    clear_mainframe_sig_lock (dmv$system_tape_table_lock);

  PROCEND dmp$validate_tape_density;
?? OLDTITLE ??

MODEND dmm$tape_reservation_113;

