Trailing-Edge
-
PDP-10 Archives
-
TOPS-20_V6.1_DECnetSrc_7-23-85
-
mcb/nmx/nmxdle.bli
There is 1 other file named nmxdle.bli in the archive. Click here to see a list.
module NMXDLE ( ! Direct Line Access Processor
ident = 'X01090'
) =
begin
!
! COPYRIGHT (c) 1980, 1981, 1982
! DIGITAL EQUIPMENT CORPORATION
! Maynard, Massachusetts
!
! This software is furnished under a license and may be used
! and copied only in accordance with the terms of such license
! and with the inclusion of the above copyright notice. This
! software or any other copies thereof may not be provided or
! otherwise made available to any other person. No title to
! and ownership of the software is hereby transferred.
!
! The information in this software is subject to change
! without notice and should not be construed as a commitment
! by DIGITAL EQUIPMENT CORPORATION.
!
! DIGITAL assumes no responsibility for the use or reliability
! of its software on equipment which is not supplied by
! DIGITAL.
!
!++
!
! FACILITY: MCB Network Management
!
! ABSTRACT:
!
! This module provides access to the line
! protocol level for LOOP LINE/CIRCUIT or
! LOAD/DUMP Network Management Operations.
!
! ENVIRONMENT: MCB V3.0
!
! AUTHOR: Scott G. Robinson CREATION DATE: 12-OCT-80
!
! MODIFIED BY:
!
! 01 - Update to MCB V3.2 Naming Conventions
! 02 - Implement MCB DLL interface
! 03 - Code compression
! 04 - Fix a dot bug Al Peckham found
! 05 - Change line/circuit references to common link block
! 06 - Add support for data link watcher.
! Alan D. Peckham, 14-Apr-82
! 07 - Complete rework of NM support.
! 08 - Fix return of LUNBLK in DLXCCP.
! 09 - Disallow DLX_OPEN when NMX$FLG_maintenance_allowed is not on.
!--
!++
! The DLX Support Routines use the following state machine:
!
! Routine DLXIOP:
!
! OPEN
!
! |Validate LUN, Assign Entity| failed
! |Allocate LUN_BLOCK |------------> Deassign Entity, Deallocate
! | LUN_BLOCK, fail IOP
! |
! |Send Stop to Entity Owner |
! |
! | CCP/STP (DLXCCP state DLX_STOP_OWNER)
! |
! |Request Entity to Provider |
! |
! | CCP/STR (DLXCCP state DLX_REQUEST_ENTITY)
! |
! | | Failed ---> Start Owner then Backout
! !Enter Maint to Provider |
! |
! | XCP/x (DLXXCP state DLX_ENTER_MAINT)
! |
! | | Failed --> Release Entity then Backout
! |Complete IOP Successfully |
!
!
! CLOSE
!
! |Validate LUN, LUN_BLOCK | Failed --> fail IOP
! |Return all RCP CCBs |
! |Fail RCV IOPs |
! |Stop Protocol |
! |
! | XCP/x (DLXCCP state DLX_STOP_PROTOCOL)
! |
! |Release Entity |
! |
! | CCP/STP (DLXCCP state DLX_RELEASE_ENTITY)
! |
! |Start Owner |
! |
! | CCP/STR (DLXCCP state DLX_START_OWNER)
! |
! |Deassign Entity |
! |Deallocate LUN_BLOCK |
! |Unlock LUN |
! |Complete IOP |
!
!
! TRANSMIT
!
! |Validate LUN, LUN_BLOCK | Failed --> fail IOP
! |Allocate CCB |
! |
! |Transmit Buffer |
! |
! | XCP/x (DLXXCP state DLX_TRANSMIT)
! |
! |Deallocate CCB |
! |Complete IOP based on C.STS|
!
!
! RECEIVE
!
! |Validate LUN, LUN_BLOCK |
! |Queue RCV IOP |
! |Try to match IOPs with RCPs|
!
!
! DLXRCP
!
! |Validate LUN_BLOCK | failed --> crash
! |Queue RCP CCB |
! |Try to match RCVs with RCPs|
!
!
! DLXAST
!
! |Validate LUN_BLOCK | failed --> return CCB
! |Set appropriate Error Code |
! |Try to complete a RCV IOP |
! !Return CCB |
!
!--
!
! INCLUDE FILES:
!
library 'XPORTX';
library 'MCBLIB';
library 'NMXPAR';
library 'NMXLIB';
require 'DLLLIB';
require 'DLXPAR';
!
! TABLE OF CONTENTS:
!
forward routine
DLXAST : MCB_DB_CCB_MOD novalue,
DLXCCP : MCB_DB_CCB novalue,
DLXCON : NMX$LKG_UCB_IOP novalue, ! Process IOP Connect
DLXCTL : MCB_DB_CCB_MOD novalue,
DLXDSC : NMX$LKG_UCB_IOP novalue, ! Process IOP Disconnect
DLXRCP : MCB_DB_CCB_MOD novalue,
DLXRCV : NMX$LKG_UCB_IOP novalue, ! Process IOP Receive
DLXXCP : MCB_DB_CCB_MOD novalue,
DLXXMT : NMX$LKG_UCB_IOP novalue, ! Process IOP Transmit
ALLOCATE_LUNBLK, ! Allocate LUNBLK and initialize
EXTRACT_LUNBLK, ! Extract a LUNBLK by ID
FIND_LUNBLK, ! Find a LUNBLK by ID
TRY_SOME_RCVS : novalue; ! Try matching IOPs with Buffers
!
! Link STATE values
!
literal
LINK_ON = 0,
LINK_OFF = 1,
LINK_SERVICE = 2,
LINK_CLEARED = 3;
!
! Link SUBSTATE values
!
literal
LINK_NO_SUBSTATE = -1,
LINK_STARTING = 0,
LINK_REFLECTING = 1,
LINK_LOOPING = 2,
LINK_LOADING = 3,
LINK_DUMPING = 4,
LINK_TRIGGERING = 5,
LINK_AUTOSERVICE = 6,
LINK_AUTOLOADING = 7,
LINK_AUTODUMPING = 8,
LINK_AUTOTRIGGERING = 9,
LINK_SYNCHRONIZING = 10,
LINK_FAILED = 11;
!
! Link SERVICE values
!
literal
LINK_ENABLED = 0,
LINK_DISABLED = 1;
!
! External routines
!
external
MCB$GAW_PROCESS_DATA_BASE : vector [2];
global routine DLXAST (NMXDB, CCB, FCM) : MCB_DB_CCB_MOD novalue = ! Process Asynchronous notifications
!++
! FUNCTIONAL DESCRIPTION:
!
!
!
! FORMAL PARAMETERS:
!
! None
!
! IMPLICIT INPUTS:
!
! None
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! None
!--
begin
map
NMXDB : ref NMXDB_BLOCK,
CCB : ref block field (C_FIELDS);
local
LUNBLK : ref DLX_LUN_BLOCK;
!
! Find our LUN_BLOCK
!
if (LUNBLK = FIND_LUNBLK (.CCB [C_LIN])) eql 0
then
SIGNAL_STOP (NMX$_ICP, .CCB, 0)
else
if (.LUNBLK [LUN_STATE] eql LUN_OPENED) and (.LUNBLK [LUN_RCV_ERROR] eql 0)
then
begin
selectone .FCM of
set
[DLL$K_PERSISTENT_ERROR] :
LUNBLK [LUN_RCV_ERROR] = (selectone .CCB [C_STS] of
set
[DLL$_START_RECEIVED] : IE$EOT;
[DLL$_MAINTENANCE_RECEIVED] : 0;
[otherwise] : IE$BBE;
tes);
[otherwise] : ! What about using state notifications ?
;
tes;
TRY_SOME_RCVS (.LUNBLK);
end;
$MCB_RETURN_CCB (.CCB);
end; !of DLXAST
global routine DLXCCP (NMXDB, CCB) : MCB_DB_CCB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine implements the state machine for Direct Line Access
! functions OPEN and CLOSE. It ensures an orderly transition between
! NMX and an Entity's Owner.
!
! FORMAL PARAMETERS:
!
! NMXDB - NMX process Data Base
! CCB - the CCB which Dispatched us
!
! IMPLICIT INPUTS:
!
! None
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! None
!--
begin
map
NMXDB : ref NMXDB_BLOCK,
CCB : ref DLX_CCB_BLOCK;
bind
LUN_BLOCK = .CCB [C_DLX_LUNBLK] : DLX_LUN_BLOCK,
ENTBLK = .LUN_BLOCK [LUN_ENTITY_ADDRESS] : block field (NMX_GENERAL_FIELDS, NMX_LINK_FIELDS,
NMX_CIRCUIT_FIELDS, NMX_LINE_FIELDS);
!
! Dispatch upon current state
!
MAP$ (.LUN_BLOCK [LUN_ENTITY_BIAS]);
case .CCB [C_DLX_STATE] from DLX_STATE_LOW to DLX_STATE_HIGH of
set
[DLX_STOP_OWNER] :
begin
CCB [C_DLX_STATE] = DLX_REQUEST_ENTITY;
$DLL_REQUEST_CIRCUIT ((.CCB), .ENTBLK [GENERAL_PROVIDER_PIX], .LUN_BLOCK [LUN_ID]);
end;
[DLX_REQUEST_ENTITY] :
begin
if .CCB [C_STS]
then
begin
CCB [C_DLX_STATE] = DLX_ENTER_MAINT;
$DLL_ENTER_MAINTENANCE ((.CCB), .ENTBLK [GENERAL_PROVIDER_PIX]);
end
else
begin
LUN_BLOCK [LUN_ERROR_CODE] = IE$CNR;
CCB [C_DLX_STATE] = DLX_START_OWNER;
CCB [C_FNC] = FC_CTL;
CCB [C_MOD] = FM_STR;
CCB [C_DLX_EID] = .ENTBLK [GENERAL_OWNER_ID];
$MCB_SCHEDULE_CCB (.CCB);
end;
end;
[DLX_RELEASE_ENTITY] :
begin
CCB [C_DLX_STATE] = DLX_START_OWNER;
CCB [C_FNC] = FC_CTL;
CCB [C_MOD] = FM_STR;
CCB [C_DLX_EID] = .ENTBLK [GENERAL_OWNER_ID];
$MCB_SCHEDULE_CCB (.CCB);
end;
[DLX_START_OWNER] :
begin
ENTBLK [LINK_LUN_BLOCK] = 0;
ENTBLK [LINK_USER_ID] = .ENTBLK [GENERAL_OWNER_ID];
begin
local
IOP : ref NMX_IOP_BLOCK;
IOP = .CCB [C_DLX_IOP];
(.IOP [I_LN2]) = 0;
EXTRACT_LUNBLK (.LUN_BLOCK [LUN_ID]);
$NMX_RETURN_RSX_IOP (.IOP, .LUN_BLOCK [LUN_ERROR_CODE], 0);
end;
$MCB_RETURN_DSR (DLX_LUN_ALLOCATION, .CCB [C_DLX_LUNBLK]);
$MCB_RETURN_CCB (.CCB);
end;
[inrange, outrange] :
SIGNAL_STOP (NMX$_ICP, .CCB, .CCB [C_DLX_STATE]);
tes;
end; !of DLXCCP
global routine DLXCON (UCB, IOP) : NMX$LKG_UCB_IOP novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! Process RSX I/O Packets associated with
! Direct Circuit/Line Access functions.
!
! FORMAL PARAMETERS:
!
! IOP - the RSX IOP
!
! IMPLICIT INPUTS:
!
! Misc NMXDB data base items
!
! IMPLICIT OUTPUTS:
!
! Misc NMXDB data base items
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! None
!--
begin
map
IOP : ref NMX_IOP_BLOCK;
local
NMXDB : ref NMXDB_BLOCK;
$MCB_RSX_TO_MCB (.UCB, NMXDB);
!+
! OPEN MCB Entity:
!
! Basic algorithm is:
!
! DLXIOP: Validate 2nd LUN word is 0
! Verify acceptable Network Management service state
! Allocate the Logical Unit Table
! Assign the Entity
! Stop the current Owner
! DLXCCP: Identify Entity Link
! DLXCCP: Initialize Maintenance Mode
! DLXXCP: Complete the IOP
!-
begin
local
CCB : ref DLX_CCB_BLOCK,
ERROR_CODE,
LUNBLK : ref DLX_LUN_BLOCK,
ENTBLK : ref block field (NMX_GENERAL_FIELDS, NMX_LINK_FIELDS, NMX_CIRCUIT_FIELDS, NMX_LINE_FIELDS);
if .(.IOP [I_LN2]) neq 0
then
begin
local
UCB;
$MCB_MCB_TO_RSX (.NMXDB, UCB);
IOFIN$ (.UCB, .IOP, IE$ALN, 0);
return
end;
if not $NMX_GET_NMX_CCB (.IOP, CCB)
then
return
else
!
! The IOP was successfully converted to a CCB format. This
! was done to allow ease of ENTITY lookup. The NMPAR block
! will be thrown away and the CCB reformatted for DLX usage.
!
begin
begin
map
CCB : ref NMX_CCB_BLOCK;
bind
NMPAR = CCB [C_NM_NMPAR] : ref NMX_NMPAR_BLOCK;
ERROR_CODE = IE$BDV;
if ((ENTBLK = (selectone .IOP [I_NM_ENTITY] of
set
[NMX$ENT_ckt] : $NMX_MAP_ENTITY_ID (.IOP [I_NM_ENTITY], byt$ptr (NMPAR [NMX_NMPAR_ENTITY]));
[NMX$ENT_lin] : $NMX_MAP_ENTITY_ID (.IOP [I_NM_ENTITY], byt$ptr (NMPAR [NMX_NMPAR_ENTITY]));
[otherwise] : 0;
tes)) neqa 0) and
(.ENTBLK [GENERAL_NAME_LENGTH] neq 0)
then
ERROR_CODE = (selectone true of
set
[.ENTBLK [LINK_LUN_BLOCK] neq 0]: IE$DAA;
[.ENTBLK [GENERAL_OWNER_ID] eql 0]: IE$BDV;
[.ENTBLK [GENERAL_PROVIDER_ID] eql 0]: IE$BDV;
[.ENTBLK [LINK_STATE] eql LINK_OFF] : IE$DAA;
[(.ENTBLK [GENERAL_SYSTEM_FLAGS] and NMX$FLG_maintenance_allowed) eql 0]: IE$PRI;
[otherwise]: IS$SUC;
tes);
$MCB_RETURN_DSR (NMX_NMPAR_ALLOCATION, .CCB [C_NM_NMPAR]); ! Return Allocated Storage
end;
!
! If the Entity is available and known try to assign it with a LUN_BLOCK
!
if .ERROR_CODE eql IS$SUC
then
begin ! Successful, try to get LUNBLK
if (LUNBLK = ALLOCATE_LUNBLK (.ENTBLK)) eql 0
then
begin
local
UCB;
$MCB_RETURN_CCB (.CCB); ! Return CCB
$MCB_MCB_TO_RSX (.NMXDB, UCB);
IOFIN$ (.UCB, .IOP, IE$NDR, 0);
return;
end;
%(change state ?)%
ENTBLK [LINK_LUN_BLOCK] = .LUNBLK;
(.IOP [I_LN2]) = .LUNBLK;
CCB [C_DLX_EID] = .ENTBLK [GENERAL_OWNER_ID];
CCB [C_FNC] = FC_CTL;
CCB [C_MOD] = FM_STP;
CCB [C_DLX_STATE] = DLX_STOP_OWNER;
CCB [C_DLX_IOP] = .IOP;
CCB [C_DLX_LUNBLK] = .LUNBLK;
$MCB_SCHEDULE_CCB (.CCB);
$MCB_MCB_TO_RSX (.NMXDB);
end
else
begin ! Unsuccessful, just return resources and leave
local
UCB;
$MCB_RETURN_CCB (.CCB); ! Return CCB
$MCB_MCB_TO_RSX (.NMXDB, UCB);
IOFIN$ (.UCB, .IOP, .ERROR_CODE, 0);
end;
end;
end;
end; !of DLXCON
global routine DLXCTL (NMXDB, CCB, FCM) : MCB_DB_CCB_MOD novalue = !Process CTLs
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine fields CTL/NM requests when DLX has a CIRCUIT/LINE
! assigned.
!
! FORMAL PARAMETERS:
!
! NMXDB - NMX process Data Base
! CCB - the CCB which Dispatched us
! FCM - the contents of C.MOD
!
! IMPLICIT INPUTS:
!
! None
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! None
!--
begin
map
NMXDB : ref NMXDB_BLOCK,
CCB : ref NMX_CCB_BLOCK;
!
! Validate this is a Network Management Control Request. If not
! hold the show otherwise process it.
!
if .FCM neq FM_NM then SIGNAL_STOP (NMX$_IFM, .CCB);
case .CCB [C_NM_FUNC] from NMX$FNC_lo to NMX$FNC_hi of
set
[NMX$FNC_ret, NMX$FNC_sho] : ! Shows complete with nothing
begin
CCB [C_CNT] = 0;
CCB [C_STS] = $NM$_SUC;
end;
[NMX$FNC_set, NMX$FNC_clr, NMX$FNC_zro, NMX$FNC_szc] :
! Modifications can't be done now
CCB [C_STS] = $NM$ERR_CWS;
[inrange, outrange] : ! Other items are bugs
CCB [C_STS] = $NM$ERR_UFO;
tes;
!
! Complete the CCB
!
CCB [C_FNC] = FC_CCP;
$MCB_SCHEDULE_CCB (.CCB);
end; !of DLXCTL
global routine DLXDSC (UCB, IOP) : NMX$LKG_UCB_IOP novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! Process RSX I/O Packets associated with
! Direct Circuit/Line Access functions.
!
! FORMAL PARAMETERS:
!
! IOP - the RSX IOP
!
! IMPLICIT INPUTS:
!
! Misc NMXDB data base items
!
! IMPLICIT OUTPUTS:
!
! Misc NMXDB data base items
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! None
!--
begin
map
IOP : ref NMX_IOP_BLOCK;
local
NMXDB : ref NMXDB_BLOCK;
$MCB_RSX_TO_MCB (.UCB, NMXDB);
!+
! CLOSE MCB Entity:
!
! Basic Algorithm is:
!
! DLXIOP: Validate 2nd LUN word <> 0
! Return all RCPs
! Fail outstanding RCVs
! Stop Protocol on Entity
! DLXXCP: Release Entity Link
! DLXCCP: Start the original Owner
! DLXCCP: Deassign the Entity
! Complete the IOP
!-
begin
local
LUNBLK : ref DLX_LUN_BLOCK;
if (LUNBLK = .(.IOP [I_LN2])) eql 0
then
begin
local
UCB;
$MCB_MCB_TO_RSX (.NMXDB, UCB);
IOFIN$ (.UCB, .IOP, IE$NLN, 0);
end
else
begin
local
NMXDB : ref NMXDB_BLOCK,
RCPCCB : ref block field (C_FIELDS),
RCVIOP : ref NMX_IOP_BLOCK,
CCB : ref DLX_CCB_BLOCK;
bind
ENTBLK = LUNBLK [LUN_ENTITY_ADDRESS] : ref NMX_GENERAL_BLOCK;
if not $MCB_GET_CCB (CCB)
then
begin
local
UCB;
$MCB_MCB_TO_RSX (.NMXDB, UCB);
IOFIN$ (.UCB, .IOP, IE$NDR, 0);
return;
end;
LUNBLK [LUN_ERROR_CODE] = IS$SUC;
LUNBLK [LUN_STATE] = LUN_CLOSING;
while $MCB_DEQUEUE_CCB (LUNBLK [LUN_RCPS], RCPCCB) do
begin
RCPCCB [C_FNC] = FC_RCE;
$MCB_SCHEDULE_CCB (.RCPCCB);
end;
MAP$ (.LUNBLK [LUN_ENTITY_BIAS]);
CCB [C_DLX_STATE] = DLX_STOP_PROTOCOL;
CCB [C_DLX_IOP] = .IOP;
CCB [C_DLX_LUNBLK] = .LUNBLK;
$DLL_STOP ((.CCB), .ENTBLK [GENERAL_PROVIDER_PIX]);
begin
local
UCB;
$MCB_MCB_TO_RSX (.NMXDB,UCB);
while $NMX_DEQUEUE (LUNBLK [LUN_RCVS], RCVIOP) do
IOFIN$ (.UCB, .RCVIOP, IE$ABO, 0);
end;
end;
end;
end; !of DLXDSC
global routine DLXRCP (NMXDB, CCB, FCM) : MCB_DB_CCB_MOD novalue = ! Process Receives
!++
! FUNCTIONAL DESCRIPTION:
!
! Data from an OPENED MCB line is dispatched to here. It is passed
! on to the user if previous RECEIVEs exist otherwise we queue the
! data CCB.
!
! FORMAL PARAMETERS:
!
! NMXDB - NMX Process Data Base
! CCB - the CCB which dispatched us
! FCM - the FCM from the CCB
!
! IMPLICIT INPUTS:
!
! Misc NMXDB items
!
! IMPLICIT OUTPUTS:
!
! Misc NMXDB items
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! None
!--
begin
map
NMXDB : ref NMXDB_BLOCK,
CCB : ref block field (C_FIELDS);
local
LUNBLK : ref DLX_LUN_BLOCK;
!
! Intercept service slave requests
!
! if SERVICE_SLAVE_REQUEST (.CCB) then return;
!
! If there is a LUN_BLOCK then give to user
!
if (LUNBLK = FIND_LUNBLK (.CCB [C_LIN])) neq 0
then
if .LUNBLK [LUN_STATE] eql LUN_OPENED
then
begin
$MCB_QUEUE_CCB (LUNBLK [LUN_RCPS], .CCB);
TRY_SOME_RCVS (.LUNBLK);
return;
end;
!
! No takers - throw the message away
!
CCB [C_FNC] = FC_RCE;
$MCB_SCHEDULE_CCB (.CCB);
end; !of NMXRCP
global routine DLXRCV (UCB, IOP) : NMX$LKG_UCB_IOP novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! Process RSX I/O Packets associated with
! Direct Circuit/Line Access functions.
!
! FORMAL PARAMETERS:
!
! IOP - the RSX IOP
!
! IMPLICIT INPUTS:
!
! Misc NMXDB data base items
!
! IMPLICIT OUTPUTS:
!
! Misc NMXDB data base items
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! None
!--
begin
map
IOP : ref NMX_IOP_BLOCK;
local
NMXDB : ref NMXDB_BLOCK;
$MCB_RSX_TO_MCB (.UCB, NMXDB);
!+
! RECEIVE a Data Buffer:
!
! Basic Algorithm is:
!
! DLXIOP: Validate 2nd LUN word <> 0
! Validate LUT State is Running
! Queue RCV IOP
! Try to Complete RCV IOPs
!-
begin
local
LUNBLK : ref DLX_LUN_BLOCK;
if (LUNBLK = .(.IOP [I_LN2])) eql 0
then
begin
local
UCB;
$MCB_MCB_TO_RSX (.NMXDB, UCB);
IOFIN$ (.UCB, .IOP, IE$NLN, 0);
return;
end
else
begin
local
NMXDB : ref NMXDB_BLOCK;
if .LUNBLK [LUN_STATE] neq LUN_OPENED
then
begin
local
UCB;
$MCB_MCB_TO_RSX (.NMXDB, UCB);
IOFIN$ (.UCB, .IOP, IE$NLN, 0);
return;
end;
if .IOP [I_NMX_CNT] eql 0
then
begin
local
UCB;
$MCB_MCB_TO_RSX (.NMXDB, UCB);
IOFIN$ (.UCB, .IOP, IE$SPC, 0);
return;
end;
if .IOP [I_NMX_ENTITY] eql 0
then
begin
local
CKTBLK : ref NMX_CIRCUIT_BLOCK,
SAVE_MAP;
SMAP$ (SAVE_MAP);
MAP$ (.LUNBLK [LUN_ENTITY_BIAS]);
CKTBLK = .LUNBLK [LUN_ENTITY_ADDRESS];
IOP [I_NMX_ENTITY] = .CKTBLK [CIRCUIT_SERVICE_TIMER];
MAP$ (.SAVE_MAP);
end;
$NMX_ENQUEUE (LUNBLK [LUN_RCVS], .IOP);
TRY_SOME_RCVS (.LUNBLK);
$MCB_MCB_TO_RSX (.NMXDB);
end;
end;
end; !of DLXRCV
global routine DLXXCP (NMXDB, CCB, FCM) : MCB_DB_CCB_MOD novalue = ! Process Transmit Completes
!++
! FUNCTIONAL DESCRIPTION:
!
! Transmit Completion involves returning the CCB and IOP.
!
! FORMAL PARAMETERS:
!
! NMXDB - the NMX Process Data Base
! CCB - the CCB which dispatched us
! FCM - the functions modifier (ignored)
!
! IMPLICIT INPUTS:
!
! Misc CCB and NMXDB fields
!
! IMPLICIT OUTPUTS:
!
! The IOP is returned to the user.
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! None
!--
begin
map
NMXDB : ref NMXDB_BLOCK,
CCB : ref DLX_CCB_BLOCK;
bind
LUNBLK = CCB [C_DLX_LUNBLK] : ref DLX_LUN_BLOCK,
ENTITY_BLOCK = LUNBLK [LUN_ENTITY_ADDRESS] : ref block field (NMX_CIRCUIT_FIELDS, NMX_LINE_FIELDS,
NMX_LINK_FIELDS, NMX_GENERAL_FIELDS);
!
! Dispatch based upon State
!
MAP$ (.LUNBLK [LUN_ENTITY_BIAS]);
case .CCB [C_DLX_STATE] from DLX_STATE_LOW to DLX_STATE_HIGH of
set
[DLX_TRANSMIT] :
begin
LUNBLK [LUN_XMTS] = .LUNBLK [LUN_XMTS] - 1;
$NMX_RETURN_RSX_IOP (.CCB [C_DLX_IOP], (if .CCB [C_STS] then IS$SUC else IE$SRE), 0);
$MCB_RETURN_CCB (.CCB); ! Return the CCB
end;
[DLX_ENTER_MAINT] :
if .CCB [C_STS]
then
begin
LUNBLK [LUN_STATE] = LUN_OPENED;
LUNBLK [LUN_ERROR_CODE] = 0;
ENTITY_BLOCK [LINK_USER_ID] = .NMXDB [NMX_NMX_PIX]^8 or .LUNBLK [LUN_ID];
$NMX_RETURN_RSX_IOP (.CCB [C_DLX_IOP], IS$SUC, 0);
$MCB_RETURN_CCB (.CCB); ! Return the CCB
end
else
begin
LUNBLK [LUN_ERROR_CODE] = IE$ISQ;
CCB [C_DLX_STATE] = DLX_RELEASE_ENTITY;
$DLL_RELEASE_CIRCUIT ((.CCB), .ENTITY_BLOCK [GENERAL_PROVIDER_PIX]);
end;
[DLX_STOP_PROTOCOL] :
begin
CCB [C_DLX_STATE] = DLX_RELEASE_ENTITY;
$DLL_RELEASE_CIRCUIT ((.CCB), .ENTITY_BLOCK [GENERAL_PROVIDER_PIX]);
end;
[inrange, outrange] :
SIGNAL_STOP (NMX$_ICP, .CCB, .CCB [C_DLX_STATE]);
tes;
end; !of DLXXCP
global routine DLXXMT (UCB, IOP) : NMX$LKG_UCB_IOP novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! Process RSX I/O Packets associated with
! Direct Circuit/Line Access functions.
!
! FORMAL PARAMETERS:
!
! IOP - the RSX IOP
!
! IMPLICIT INPUTS:
!
! Misc NMXDB data base items
!
! IMPLICIT OUTPUTS:
!
! Misc NMXDB data base items
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! None
!--
begin
map
IOP : ref NMX_IOP_BLOCK;
local
NMXDB : ref NMXDB_BLOCK;
$MCB_RSX_TO_MCB (.UCB, NMXDB);
!+
! TRANSMIT a Buffer:
!
! Basic Algorithm is:
!
! DLXIOP: Validate 2nd LUN word <> 0
! Validate LUT State is Running
! Count Transmits to DLL
! Transmit Buffer
! DLXXCP: Decrement Transmits to DLL
! Complete IOP
!-
begin
local
LUNBLK : ref DLX_LUN_BLOCK;
if (LUNBLK = .(.IOP [I_LN2])) eql 0
then
begin
local
UCB;
$MCB_MCB_TO_RSX (.NMXDB, UCB);
IOFIN$ (.UCB, .IOP, IE$NLN, 0);
end
else
begin
if .LUNBLK [LUN_STATE] neq LUN_OPENED
then
begin
local
UCB;
$MCB_MCB_TO_RSX (.NMXDB, UCB);
IOFIN$ (.UCB, .IOP, IE$NLN, 0);
return;
end;
if .IOP [I_NMX_CNT] eql 0
then
begin
local
UCB;
$MCB_MCB_TO_RSX (.NMXDB, UCB);
IOFIN$ (.UCB, .IOP, IE$SPC, 0);
return;
end;
MAP$ (.LUNBLK [LUN_ENTITY_BIAS]);
begin
local
NMXDB : ref NMXDB_BLOCK,
CCB : ref DLX_CCB_BLOCK;
bind
ENTBLK = LUNBLK [LUN_ENTITY_ADDRESS] : ref NMX_GENERAL_BLOCK;
if not $MCB_GET_CCB (CCB)
then
begin
local
UCB;
$MCB_MCB_TO_RSX (.NMXDB, UCB);
IOFIN$ (.UCB, .IOP, IE$NDR, 0);
return
end;
LUNBLK [LUN_XMTS] = .LUNBLK [LUN_XMTS] + 1;
CCB [C_BIAS] = .IOP [I_NMX_BIAS];
CCB [C_ADDR] = .IOP [I_NMX_ADDR];
CCB [C_CNT] = .IOP [I_NMX_CNT];
CCB [C_DLX_STATE] = DLX_TRANSMIT;
CCB [C_DLX_IOP] = .IOP;
CCB [C_DLX_LUNBLK] = .LUNBLK;
$DLL_TRANSMIT ((.CCB), .ENTBLK [GENERAL_PROVIDER_PIX]);
end;
$MCB_MCB_TO_RSX (.NMXDB);
end;
end;
end; !of DLXXMT
routine FIND_LUNBLK (LUNID) = ! Find a LUNBLK with LUNID
!++
! FUNCTIONAL DESCRIPTION:
!
!
!
! FORMAL PARAMETERS:
!
! None
!
! IMPLICIT INPUTS:
!
! None
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! Must be called in MCB mode
!--
begin
external
MCB$GAW_PROCESS_DATA_BASE : vector [2];
bind
NMXDB = MCB$GAW_PROCESS_DATA_BASE [1] : ref NMXDB_BLOCK;
local
LUNBLK : ref DLX_LUN_BLOCK;
!
! Search LUN Queue for block with matching LUN_ID
!
LUNBLK = NMXDB [NMX_LUN_QUEUE];
while (LUNBLK = .LUNBLK [LUN_LINK]) nequ 0 do
if .LUNBLK [LUN_ID] eqlu .LUNID<0, 8> then exitloop;
.LUNBLK
end; !of FIND_LUNBLK
routine ALLOCATE_LUNBLK (ENTITY) = ! Allocate a LUNBLK and initialize it
!++
! FUNCTIONAL DESCRIPTION:
!
!
!
! FORMAL PARAMETERS:
!
! None
!
! IMPLICIT INPUTS:
!
! None
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! Must be called in MCB mode
!--
begin
external
MCB$GAW_PROCESS_DATA_BASE : vector [2];
bind
NMXDB = MCB$GAW_PROCESS_DATA_BASE [1] : ref NMXDB_BLOCK;
local
LUNBLK : ref DLX_LUN_BLOCK;
!
! Allocate and Initialize the LUN_BLOCK
!
if $MCB_GET_DSR (DLX_LUN_ALLOCATION, LUNBLK)
then
begin !LUN_BLOCK Allocation Success
$NMX_ENQUEUE (NMXDB [NMX_LUN_QUEUE], .LUNBLK);
LUNBLK [LUN_ENTITY_ADDRESS] = .ENTITY;
SMAP$ (LUNBLK [LUN_ENTITY_BIAS]);
LUNBLK [LUN_ID] = .NMXDB [NMX_NEXT_LUN_ID];
NMXDB [NMX_NEXT_LUN_ID] = .NMXDB [NMX_NEXT_LUN_ID] + 1;
LUNBLK [LUN_STATE] = LUN_OPENING;
$NMX_QUEUE_INITIALIZE (LUNBLK [LUN_RCVS]);
$NMX_QUEUE_INITIALIZE (LUNBLK [LUN_RCPS]);
LUNBLK [LUN_XMTS] = 0;
LUNBLK [LUN_RCV_ERROR] = 0;
LUNBLK [LUN_ERROR_CODE] = IS$SUC;
.LUNBLK
end
else
0
end; !of ALLOCATE_LUNBLK
routine EXTRACT_LUNBLK (LUNID) = ! Extract a LUNBLK with LUNID
!++
! FUNCTIONAL DESCRIPTION:
!
!
!
! FORMAL PARAMETERS:
!
! None
!
! IMPLICIT INPUTS:
!
! None
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! Must be called in MCB mode
!--
begin
external
MCB$GAW_PROCESS_DATA_BASE : vector [2];
bind
NMXDB = MCB$GAW_PROCESS_DATA_BASE [1] : ref NMXDB_BLOCK;
local
LUNBLK : ref DLX_LUN_BLOCK,
PREBLK : ref DLX_LUN_BLOCK;
!
! Search LUN Queue for block with matching LUN_ID
!
LUNBLK = NMXDB [NMX_LUN_QUEUE];
PREBLK = .LUNBLK;
while (LUNBLK = .LUNBLK [LUN_LINK]) nequ 0 do
begin
if .LUNBLK [LUN_ID] eqlu .LUNID<0, 8>
then
begin
if (PREBLK [LUN_LINK] = .LUNBLK [LUN_LINK]) eql 0
then
NMXDB [$sub_field (NMX_LUN_QUEUE, Q_TAIL)] = .PREBLK;
exitloop;
end;
PREBLK = .LUNBLK;
end;
!
.LUNBLK
end; !of EXTRACT_LUNBLK
routine TRY_SOME_RCVS (LUNBLK) : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! TRY_SOME_RCVS tries to give some receives from the RCPS Queue to
! an RSX task.
!
! FORMAL PARAMETERS:
!
! None
!
! IMPLICIT INPUTS:
!
! LUNBLK RCP and IOP Queues
!
! IMPLICIT OUTPUTS:
!
! LUNBLK RCP and IOP Queues
!
! COMPLETION CODES:
!
! None
!
! SIDE EFFECTS:
!
! This routine must be called in MCB mode!
!--
begin
map
LUNBLK : ref DLX_LUN_BLOCK;
bind
NMXDB = MCB$GAW_PROCESS_DATA_BASE [1] : ref NMXDB_BLOCK,
RCVQ = LUNBLK [LUN_RCVS] : vector,
RCPQ = LUNBLK [LUN_RCPS] : vector;
!
! Check first for error completions
!
while true do
begin
local
AMOUNT,
ERROR_CODE,
IOP : ref NMX_IOP_BLOCK;
if (IOP = .RCVQ [0]) eqla 0 then exitloop;
if .LUNBLK [LUN_RCV_ERROR] eql 0
then
begin
local
CCB : ref block field (C_FIELDS);
if (CCB = .RCPQ [0]) eqla 0 then exitloop;
ERROR_CODE = IS$SUC;
AMOUNT = .CCB [C_CNT];
!
! Check if there is too much data
!
if .AMOUNT gtru .IOP [I_NMX_CNT]
then
begin
ERROR_CODE = IE$DAO;
AMOUNT = .IOP [I_NMX_CNT];
end;
begin ! Copy data to user buffer.
local
CURRENT_MAP;
SMAP$ (CURRENT_MAP);
MAP$ (.CCB [C_BIAS]);
$MCB_MOVE_BUFFER_TO_BUFFER (.AMOUNT, .CCB [C_ADDR],
((.IOP [I_NMX_BIAS]), (.IOP [I_NMX_ADDR])));
MAP$ (.CURRENT_MAP);
end;
!
! Complete IOP and return resources
!
$MCB_DEQUEUE_CCB (RCPQ, CCB); ! Dequeue RCPQ
CCB [C_FNC] = FC_RCE;
$MCB_SCHEDULE_CCB (.CCB);
end
else
begin
ERROR_CODE = .LUNBLK [LUN_RCV_ERROR];
AMOUNT = 0;
LUNBLK [LUN_RCV_ERROR] = 0;
end;
$NMX_DEQUEUE (RCVQ, IOP);
$NMX_RETURN_RSX_IOP (.IOP, .ERROR_CODE, .AMOUNT);
end;
end; !of TRY_SOME_RCVS
end
eludom
! Local Modes:
! Comment Column:36
! Comment Start:!
! Mode:BLISS
! Auto Save Mode:2
! End: