Trailing-Edge
-
PDP-10 Archives
-
BB-P363B-SM_1985
-
mcb/nml/nmunet.b16
There are no other files named nmunet.b16 in the archive.
! <BRANDT.DEVELOPMENT>NMUNET.B16.1 21-Oct-82 14:39:37, Edit by BRANDT
!
! Ident 09.
! Rework code in ASSIGN_A_LUN to compress code size.
!
! <BRANDT.DEVELOPMENT>NMUNET.B16.1 21-Oct-82 9:00:17, Edit by BRANDT
!
! Ident 08.
! In NMU$NETWORK_OPEN, for source_links having no node name, convert
! the node number to an ASCII string and use that for the name.
! Remove code from ident 5.
! And finally some simple code compression so we can task build.
!
! <BRANDT.DEVELOPMENT>NMUNET.B16.1 14-Sep-82 14:22:34, Edit by BRANDT
!
! Ident 07.
! In NMU$NETWORK_OPEN set the error detail field of a response
! message for RSX error codes other than IE$NRJ. Thus "rejected
! by object" will no longer be a catch all error.
!
! <BRANDT.DEVELOPMENT>NMUNET.B16.1 9-Sep-82 17:00:17, Edit by BRANDT
!
! Ident 06.
! Change FAIL_TYPE mappings for reject codes 0 and 5.
!
! <BRANDT.DEVELOPMENT>NMUNET.B16.1 9-Sep-82 15:30:17, Edit by BRANDT
!
! Ident 05.
! In NMU$NETWORK_OPEN make a check for source_links to verify that
! a node name is supplied.
!
!NET:<PECKHAM.DEVELOPMENT>NMUNET.B16.3 25-Jun-82 19:39:37, Edit by PECKHAM
!
! Ident 04.
! Add global symbols UN$USER, UN$PASSWORD, UN$ACCOUNT for access control
! (they are filled in by NMLEVT with data from NMX).
! In NMU$NETWORK_VALIDATE, check the connect accounting data
! against the strings supplied in the above.
!
!NET:<PECKHAM.DEVELOPMENT>NMUNET.B16.3 23-Mar-82 08:25:40, Edit by PECKHAM
!
! Ident 03.
! Make response pointers optional in NMU$NETWORK_OPEN.
!
!NET:<PECKHAM.DEVELOPMENT>NMUNET.B16.3 3-Mar-82 08:37:38, Edit by PECKHAM
!
! Ident 02.
! Revise to accomodate fix in SCX X1(42).
! After receiving NT$DSC/ABO/ABT, insure that an ABO is done.
!
!NET:<PECKHAM.DEVELOPMENT>NMUNET.B16.2 23-Jan-82 20:47:26, Edit by PECKHAM
!
! Ident 01.
! Fix call to NMU$SCHED_WAIT to include timeout value.
!
module NMUNET ( ! Task to task network communications
ident = 'X01.09'
) =
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: LSG DECnet Network Management
!
! Abstract: This module provides a "generic" interface to DECnet
! task to task communications.
!
! As perceived by the user of these interfaces, there are
! two types of link ends: TARGET and SOURCE. A TARGET task
! (sometimes known as a SERVER) waits for another task to
! issue a connect to it. A SOURCE task issues a connect to
! the task it wishes to communicate with. Thus the major
! difference between the ends of a link is the link
! connection operation.
!
! Environment: TOPS10/TOPS20 user mode, MCB RSX task level
!
! Author: Scott G. Robinson, Creation Date: 26-JAN-81
!
! From NMUNET.B36 by Steven M. Jenness
!
! Modified by:
!
! 02 - Fix Maximum Logical Links and Error Detail on Server Rejects
! 03 - Install Limit Protection code on ch$copy and ch$moves
! 04 - Remove Synchronization Race Condition on LSB_CONNECTED
! 05 - Ensure no conflicts on simultaneous Transmits and Receives
! 06 - Prevent Queue Interlocks from deadlocking non-Interrupt processing
! 07 - Conform to Node_ID format in CONN_BLK
! 08 - Support Assignment of DLX Luns
! 09 - Have NETWORK_OPEN build a response message on error.
! 10 - Add a response code -2 to NETWORK_OPEN, to mean "don't retry".
!
!--
!<BLF/SYNONYM $FIELD=FIELD>
!<BLF/SYNONYM %unquote =>
!<BLF/PAGE>
!
! Include files
!
library 'NMULIB'; ! All required definitions
!
! Global routines
!
forward routine
NMU$NETWORK_UTILITIES; ! Define global entry points
!
! Local routines
!
forward routine
DECLARE_NETWORK_EVENT : novalue, ! Declare a Network Event
GND_AST : VANILLA_INTERRUPT_LINKAGE, ! Network Mailbox Interrupt Service
PROCESS_MAILBOX_ENTRY : novalue, ! Process a Mailbox Entry
IQ_SCAN, ! Scanning routine for info queue
ASSIGN_A_LUN; ! Assign a LUN for Network Usage
!
! Global Items
!
global literal !These are used in the NML
LUN$NM = NMU$_NM_DEVICE_LUN,
EFN$NM = NMU$_NM_DEVICE_FLAG,
LUN$NS = NMU$_NETWORK_LUN,
EFN$NS = NMU$_NETWORK_FLAG;
!
! Own variables
!
literal
NODE_ID_LENGTH = 9;
bind
FAIL_TYPE = uplit
! Failure code Reject/object code
! ------------ ------------------
( 10, ! 0
4, ! 1
2, ! 2
11, ! 3
7, ! 4
6, ! 5
9, ! 6
12, ! 7
15, ! 8
14, ! 9
rep 22 of (15), ! 10-31
4, ! 32
9, ! 33
8, ! 34
15, ! 35
8, ! 36
15, ! 37
10, ! 38
3, ! 39
15, ! 40
15, ! 41
15, ! 42
8): vector; ! 43
bind
RETRY_CODE = uplit
! Return code Reject/object code
! ----------- ------------------
( -2, ! 0
-1, ! 1
-2, ! 2
-2, ! 3
-2, ! 4
-2, ! 5
-1, ! 6
-2, ! 7
-1, ! 8
-2, ! 9
rep 22 of (-2), ! 10-31
-1, ! 32
-1, ! 33
-2, ! 34
-2, ! 35
-2, ! 36
-2, ! 37
-1, ! 38
-2, ! 39
-2, ! 40
-2, ! 41
-2, ! 42
-2): vector; ! 43
own
LOCAL_NODE : block [ch$allocation (NODE_ID_LENGTH, 8)], ! Local node id
NEXT_LINK_ID, ! Link identification sequence
INFO_QUEUE : Q_HEADER, ! Queue of all link info blocks
NETWORK_LUNS : VECTOR [NMU$_NETWORK_MAX_LUNS]; ! LUN Assignment Vector
global
UN$USER : block [ch$allocation (1 + 16, 8)],
UN$PASSWORD : block [ch$allocation (1 + 8, 8)],
UN$ACCOUNT : block [ch$allocation (1 + 16, 8)];
!
! Structures
!
! All contained in NMUNTS
!
! Local Macros
!
macro
WAIT_FOR_NETWORK (LNKINFO, WHILE_COND) =
begin
bind
LNKSTS = LNKINFO[LINK_STATUS] : LINK_STATUS_BLOCK;
while (WHILE_COND) do
NMU$SCHED_WAIT(LNKINFO[LINK_EVENT], 0)
end %;
!
! External routines
!
external routine
NMU$QUEUE_MANAGER, ! Queue management routines
NMU$MEMORY_MANAGER, ! Memory management routines
NMU$SCHED_MANAGER; ! Scheduler interface
global routine %unquote NMU$NETWORK_INITIALIZE : novalue =
!++
! Functional description:
!
! This routine initializes the network system interface.
!
! Formal parameters: none
!
! Routine value: none
! Side effects:
!
! The local node id is retrieved for NMU$NETWORK_LOCAL.
!
!--
begin
own
NETWORK_STATUS : $NETWORK_STATUS_BLOCK,
OPN_DIR : OPNW$ (NMU$_NETWORK_LUN, NMU$_NETWORK_FLAG, NETWORK_STATUS,, <NMU$_NETWORK_MAX_LUNS>),
GLN_DIR : GLNW$ (NMU$_NETWORK_LUN, NMU$_NETWORK_FLAG, NETWORK_STATUS,,
<LOCAL_NODE, NODE_ID_LENGTH, 1>);
!
! Interrupt Service Routine for SPA$ Initialization
!
routine SPA_AST NETWORK_INTERRUPT_ROUTINE =
begin
map
NETWORK_STATUS_BLOCK : ref $NETWORK_STATUS_BLOCK;
bind
NUMBER_OF_ENTRIES = NETWORK_STATUS_BLOCK [NETSB$IO_COUNT];
!
! See if we were successful and if so process a few entries
! from the mailbox.
!
if .NETWORK_STATUS_BLOCK [NETSB$ERR] eql IS$SUC
then
until .NUMBER_OF_ENTRIES eql 0 do
begin
PROCESS_MAILBOX_ENTRY ();
NUMBER_OF_ENTRIES = .NUMBER_OF_ENTRIES - 1;
end;
!
end; !of SPA_AST
!
! Reset Network queues
!
NMU$QUEUE_RESET (INFO_QUEUE);
!
! Reset Internal Link IDs
!
NEXT_LINK_ID = 1;
!
! Assign the network LUNS and make them available for assignment
!
INCR LUN_NUMBER from NMU$_NETWORK_LUN to NMU$_NETWORK_LUN + NMU$_NETWORK_MAX_LUNS do
begin
ALUN$S (.LUN_NUMBER, %ASCII'NS', 0);
NETWORK_LUNS [.LUN_NUMBER - NMU$_NETWORK_LUN] = 0;
end;
!
! Assign the NM: device to its' LUN
!
ALUN$S (NMU$_NM_DEVICE_LUN, %ASCII'NM', 0);
!
! Assign the NM: DLX device to its' LUNS
!
ALUN$S (NMU$_DL0_DEVICE_LUN, %ASCII'NM', 0);
ALUN$S (NMU$_DL1_DEVICE_LUN, %ASCII'NM', 0);
!
! Identify us to the network
!
dir$ (OPN_DIR);
!
! We are now known to the network; Get local node information and
! construct local node information.
!
dir$ (GLN_DIR);
!
! Startup Mailbox Interrupt Service
!
SPA$S (NMU$_NETWORK_LUN,, NETWORK_STATUS, SPA_AST, <GND_AST>);
!
end; ! End of NMU$NETWORK_INITIALIZE
global routine %unquote NMU$NETWORK_OPEN (TYPE, CONN_BLK, RESPONSE_PTR,
RESPONSE_LEN, RESPONSE_CODE) =
!++
! Functional description:
!
! This routine opens a logical link. It blocks the running
! task until a successful connect is made or the link connection
! is aborted for some explicit reason.
!
! TARGET_LINK: When this routine returns it will have filled
! in the connect block fields: OPTIONAL_DATA,
! USER, ACCOUNT and PASSWORD. The link must
! still be accepted or rejected.
!
! SOURCE_LINK: When this routine returns it will have filled
! in the connect block fields: OPTIONAL_DATA,
! REJECT_REASON.
!
! Formal parameters:
!
! .TYPE Link type to open (SOURCE_LINK, TARGET_LINK).
! .CONN_BLK Address of a link connect block.
! .RESPONSE_PTR Pointer to a response buffer
! if 0, no response is built.
! .RESPONSE_LEN Address of a value which on input contains the
! maximum length of the response buffer, and on
! output contains the actual length (if any).
! .RESPONSE_CODE NICE error code to put into response message
! (usually LCF or MCF).
!
! Routine value:
!
! gtr 0 Link id to be used in all future link references.
! lss 0 DECnet link failure indication.
!
! Side effects: none
!
!--
begin
map
CONN_BLK : ref CONNECT_BLOCK;
local
LINK_INFO : ref LINK_INFO_BLOCK,
TEMP_PTR;
!
! The interrupt service routine for SOURCE_LINK connects.
!
routine CON_AST NETWORK_INTERRUPT_ROUTINE =
begin
map
NETWORK_STATUS_BLOCK : ref $NETWORK_STATUS_BLOCK;
local
LINK_INFO : ref LINK_INFO_BLOCK;
!
! Find our LINK_INFO block
!
if (LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .NETWORK_STATUS_BLOCK [NETSB$LINK_ID], IQ_SCAN)) neq 0
then
!
! Update status to reflect connect complete
!
begin
bind
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK;
if .NETWORK_STATUS_BLOCK [NETSB$ERR] eql IS$SUC
then
begin
LNKSTS [LSB_CONNECTED] = 1;
LNKSTS [LSB_CLOSED] = 0;
end;
LNKSTS [LSB_CCWAIT] = 0;
!
! Startup waiting process
!
DECLARE_NETWORK_EVENT (.LINK_INFO);
end;
end; ! of CON_AST
!
! Main OPEN Processing
!
LINK_INFO = NMU$MEMORY_GET (LINK_INFO_BLOCK_ALLOCATION);
LINK_INFO [LINK_ID] = (NEXT_LINK_ID = .NEXT_LINK_ID + 1);
if .NEXT_LINK_ID lss 0 then NEXT_LINK_ID = 1;
NMU$SCHED_EVENT (LINK_INFO [LINK_EVENT], $true);
LINK_INFO [LINK_TYPE] = .TYPE;
!
! All LINK_INFO_BLOCKs go into the INFO_QUEUE.
!
NMU$QUEUE_INSERT (INFO_QUEUE, LINK_INFO [LINK_QUEUE]);
begin
bind
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK,
CONB = LINK_INFO [LINK_CONB] : RSX$_CONB_BLOCK,
GNDB = LINK_INFO [LINK_GNDB] : RSX$_GNDB_BLOCK,
LNKSB = LINK_INFO [LINK_LINK_SB] : $NETWORK_STATUS_BLOCK,
INSB = LINK_INFO [LINK_IN_SB] : $NETWORK_STATUS_BLOCK,
OUTSB = LINK_INFO [LINK_OUT_SB] : $NETWORK_STATUS_BLOCK;
!
! Setup other LINK_IDs for AST Routines
!
LNKSB [NETSB$LINK_ID] = .LINK_INFO [LINK_ID];
INSB [NETSB$LINK_ID] = .LINK_INFO [LINK_ID];
OUTSB [NETSB$LINK_ID] = .LINK_INFO [LINK_ID];
!
! Format appropriate blocks for SOURCE and TARGET Links.
!
LNKSTS [LSB_CONNECTED] = 0;
if .TYPE eql TARGET_LINK
then
begin ! TARGET_LINK Open
!
! Construct GNDB from CONN_BLK information. The GNDB is used to
! match incoming connects in PROCESS_MAILBOX_ENTRY.
!
GNDB [GNDB_DEST_OBJECT] = .CONN_BLK [CB_OBJECT];
GNDB [GNDB_DEST_FORMAT] = 0; !Format 0 Descriptor
if .CONN_BLK [CB_DESCRIPTOR_LENGTH] GTR 0
then
begin !Format 1 Descriptor
GNDB [GNDB_DEST_FORMAT] = 1;
GNDB [GNDB_D1_LENGTH] = .CONN_BLK [CB_DESCRIPTOR_LENGTH];
ch$move (.CONN_BLK [CB_DESCRIPTOR_LENGTH], .CONN_BLK [CB_DESCRIPTOR],
ch$ptr (GNDB [GNDB_D1_TASK_NAME]));
end;
!
! Flag we are waiting for a connect and that we are a server.
! We then wait for the incoming connect to happen.
!
LNKSTS [LSB_SERVER] = 1;
LNKSTS [LSB_CIWAIT] = 1;
LNKSTS [LSB_CCWAIT] = 0;
end
else
begin ! SOURCE Open
ch$copy (minu (ch$rchar (ch$plus (.CONN_BLK [CB_HOST], 2)), 6), ch$plus (.CONN_BLK [CB_HOST], 3),
%C' ', 6, ch$ptr (CONB [CONB_NODE_NAME]));
if (ch$rchar (ch$plus (.CONN_BLK [CB_HOST], 2)) eql 0)
then ! If no node name,
begin ! use node number as name
linkage CBDSG = JSR (register=0,register=1,register=2;
register=0) : nopreserve (1,2);
external routine $CBDSG : CBDSG novalue;
local TEMP_PTR;
TEMP_PTR = .CONN_BLK [CB_HOST]; ! Pointer to node number
$CBDSG (CONB [CONB_NODE_NAME], ! ASCII output to here
GETW(TEMP_PTR), ! Value to convert
0; ! Zero suppress
TEMP_PTR); ! For updated pointer
end;
CONB [CONB_FORMAT] = 0;
CONB [CONB_OBJECT] = .CONN_BLK [CB_OBJECT];
if .CONN_BLK [CB_DESCRIPTOR_LENGTH] gtr 0
then
begin !Descriptor Format 1
CONB [CONB_FORMAT] = 1;
CONB [CONB_1_LENGTH] = .CONN_BLK [CB_DESCRIPTOR_LENGTH];
ch$move (.CONB [CONB_1_LENGTH], .CONN_BLK [CB_DESCRIPTOR], ch$ptr (CONB [CONB_1_TASK_NAME]));
end;
CONB [CONB_USER_LENGTH] = .CONN_BLK [CB_USERID_LENGTH];
ch$move (.CONB [CONB_USER_LENGTH], .CONN_BLK [CB_USERID], ch$ptr (CONB [CONB_USER_ID]));
CONB [CONB_PASSWORD_LENGTH] = .CONN_BLK [CB_PASSWORD_LENGTH];
ch$move (.CONB [CONB_PASSWORD_LENGTH], .CONN_BLK [CB_PASSWORD], ch$ptr (CONB [CONB_PASSWORD]));
CONB [CONB_ACCOUNT_LENGTH] = .CONN_BLK [CB_ACCOUNT_LENGTH];
ch$move (.CONB [CONB_ACCOUNT_LENGTH], .CONN_BLK [CB_ACCOUNT], ch$ptr (CONB [CONB_ACCOUNT]));
if ASSIGN_A_LUN (.LINK_INFO) lss 0
then
return $false
else
begin
LNKSTS [LSB_CCWAIT] = 1;
LNKSTS [LSB_CIWAIT] = 0;
LNKSTS [LSB_SERVER] = 0;
TEMP_PTR = .CONN_BLK [CB_DATA];
CONN_BLK [CB_DATA] = ch$ptr (CONN_BLK [CB_DATA_BUFFER]);
CON$S (.LINK_INFO [LINK_LUN],, LINK_INFO [LINK_LINK_SB], CON_AST,
<LINK_INFO [LINK_CONB],
RSX$_CONB_ALLOCATION, (if .CONN_BLK [CB_DATA_LENGTH] eql 0 then 0 else .TEMP_PTR),
.CONN_BLK [CB_DATA_LENGTH], .CONN_BLK [CB_DATA], 16>);
end;
end;
!
! Wait for the link to become valid or an error is detected
!
WAIT_FOR_NETWORK (LINK_INFO, (.LNKSTS [LSB_CIWAIT] or .LNKSTS [LSB_CCWAIT]));
!
! We have had some activity on the logical link which has removed us from
! waiting.
!
begin
bind
NETSTS = LINK_INFO [LINK_LINK_SB] : $NETWORK_STATUS_BLOCK;
if .NETSTS [NETSB$ERR] eql IS$SUC
then
begin
CONN_BLK [CB_DATA_LENGTH] = .NETSTS [NETSB$CNT]; !SOURCE_LINK
if .LINK_INFO [LINK_TYPE] eql TARGET_LINK
then
begin !TARGET_LINK Processing
bind
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK,
GNDB = LINK_INFO [LINK_GNDB] : RSX$_GNDB_BLOCK;
local
TEMP_PTR,
TEMP_PTR1,
TEMP_LEN;
LNKSTS [LSB_CCWAIT] = 1;
CONN_BLK [CB_HOST] = ch$ptr (CONN_BLK [CB_HOST_BUFFER]);
TEMP_PTR1 = .CONN_BLK [CB_HOST];
PUTB (0, TEMP_PTR1);
PUTB (0, TEMP_PTR1);
TEMP_PTR = ch$find_ch (6, ch$ptr (GNDB [GNDB_SOURCE_NODE_NAME]), %c' ');
TEMP_LEN = (if ch$fail (.TEMP_PTR) then 6 else ch$diff (.TEMP_PTR,
ch$ptr (GNDB [GNDB_SOURCE_NODE_NAME])));
CONN_BLK [CB_HOST_LENGTH] = minu (.TEMP_LEN, 6) + 3;
PUTB (.TEMP_LEN, TEMP_PTR1);
ch$copy (minu (.TEMP_LEN, 6), ch$ptr (GNDB [GNDB_SOURCE_NODE_NAME]), 0, 6, .TEMP_PTR1);
CONN_BLK [CB_TASK] = ch$ptr (CONN_BLK [CB_TASK_BUFFER]);
case .GNDB [GNDB_SOURCE_FORMAT] from 0 to 2 of
set
[0] : !Format 0 Descriptor
begin
CONN_BLK [CB_TASK_LENGTH] = 0;
end;
[1] : !Format 1 Descriptor
begin
CONN_BLK [CB_TASK_LENGTH] = .GNDB [GNDB_S1_LENGTH];
ch$copy (minu (.GNDB [GNDB_S1_LENGTH], 16), ch$ptr (GNDB [GNDB_S1_TASK_NAME]), 0, 17,
.CONN_BLK [CB_TASK]);
end;
[2] : !Format 2 Descriptor
begin
CONN_BLK [CB_TASK_LENGTH] = .GNDB [GNDB_S2_LENGTH];
ch$copy (minu (.GNDB [GNDB_S2_LENGTH], 16), ch$ptr (GNDB [GNDB_S2_TASK_NAME]), 0, 17,
.CONN_BLK [CB_TASK]);
end;
tes;
CONN_BLK [CB_USERID] = ch$ptr (CONN_BLK [CB_USERID_BUFFER]);
CONN_BLK [CB_USERID_LENGTH] = .GNDB [GNDB_SOURCE_TASK_LENGTH];
ch$copy (minu (.GNDB [GNDB_SOURCE_TASK_LENGTH], 16), ch$ptr (GNDB [GNDB_SOURCE_TASK_ID]), 0, 17,
.CONN_BLK [CB_USERID]);
CONN_BLK [CB_PASSWORD] = ch$ptr (CONN_BLK [CB_PASSWORD_BUFFER]);
CONN_BLK [CB_PASSWORD_LENGTH] = .GNDB [GNDB_SOURCE_PASSWORD_LENGTH];
ch$copy (minu (.GNDB [GNDB_SOURCE_PASSWORD_LENGTH], 8), ch$ptr (GNDB [GNDB_SOURCE_PASSWORD]), 0,
9, .CONN_BLK [CB_PASSWORD]);
CONN_BLK [CB_ACCOUNT] = ch$ptr (CONN_BLK [CB_ACCOUNT_BUFFER]);
CONN_BLK [CB_ACCOUNT_LENGTH] = .GNDB [GNDB_SOURCE_ACCOUNT_LENGTH];
ch$copy (minu (.GNDB [GNDB_SOURCE_ACCOUNT_LENGTH], 16), ch$ptr (GNDB [GNDB_SOURCE_ACCOUNT]), 0,
17, .CONN_BLK [CB_ACCOUNT]);
CONN_BLK [CB_DATA] = ch$ptr (CONN_BLK [CB_DATA_BUFFER]);
CONN_BLK [CB_DATA_LENGTH] = .GNDB [GNDB_OPTIONAL_LENGTH];
ch$copy (minu (.GNDB [GNDB_OPTIONAL_LENGTH], 16), ch$ptr (GNDB [GNDB_OPTIONAL_DATA]), 0, 17,
.CONN_BLK [CB_DATA]);
end;
.LINK_INFO [LINK_ID]
end
else
begin !Link Connect Unsuccessful
!
! Source links can still return optional data so ensure count is correct.
!
CONN_BLK [CB_REJECT_CODE] = 0;
if .LINK_INFO [LINK_TYPE] eql SOURCE_LINK
then
begin
CONN_BLK [CB_DATA_LENGTH] = .NETSTS [NETSB$CNT];
if .NETSTS [NETSB$ERR] eql IE$NRJ
then
begin
CONN_BLK [CB_REJECT_CODE] = .NETSTS [NETSB$CNT];
CONN_BLK [CB_DATA_LENGTH] = 0;
end
end;
!
! Build a response message
!
if .RESPONSE_PTR neq 0
then
.RESPONSE_LEN = $RESPONSE (.RESPONSE_PTR, .RESPONSE_CODE,
(selectone .NETSTS [NETSB$ERR] of ! Error detail
set
[IE$ABO]: 15; ! Abort by management
[IE$URJ]: 5; ! Rejected by object
[IE$BAD]: 8; ! Access Control Rejected
[IE$SPC,
IE$RSU]: 4; ! Network resources
[IE$NNT]: 3; ! Node unreachable
[IS$DAO]: 9; ! Object too busy
[IE$NRJ]: .FAIL_TYPE [.CONN_BLK[CB_REJECT_CODE]];
[otherwise]: 10; ! No response from object
tes));
!
! Return LINK_INFO Resources
!
NETWORK_LUNS [.LINK_INFO [LINK_LUN] - NMU$_NETWORK_LUN] = 0;
NMU$QUEUE_EXTRACT (INFO_QUEUE, .LINK_INFO);
NMU$MEMORY_RELEASE (.LINK_INFO, LINK_INFO_BLOCK_ALLOCATION);
-1
end
end
end
end; ! End of NMU$NETWORK_OPEN
global routine %unquote NMU$NETWORK_ACCEPT (LINK_IDENTIFIER, DATA_LEN, DATA_PTR) =
!++
! Functional description:
!
! This routine accepts the connection to a TARGET link
! end. The link was initially opened by a call to the
! NMU$NETWORK_TARGET routine.
!
! Formal parameters: none
!
! .LINK_IDENTIFIER Link id for the target link end.
! .DATA_LEN Length of optional accept data
! .DATA_PTR Pointer to optional accept data
!
! Routine value:
!
! $true - Accept Done
! $false - Accept Not Done
!
! Side effects: none
!
!--
begin
local
LINK_INFO : ref LINK_INFO_BLOCK;
!
! Routine to process ACC$ ASTs
!
routine ACC_AST NETWORK_INTERRUPT_ROUTINE =
begin
map
NETWORK_STATUS_BLOCK : ref $NETWORK_STATUS_BLOCK;
local
LINK_INFO : ref LINK_INFO_BLOCK;
!
! Find our LINK_INFO block
!
if (LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .NETWORK_STATUS_BLOCK [NETSB$LINK_ID], IQ_SCAN)) neq 0
then
!
! Update status to reflect connect complete
!
begin
bind
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK;
if .NETWORK_STATUS_BLOCK [NETSB$ERR] eql IS$SUC
then
begin
LNKSTS [LSB_CONNECTED] = 1;
LNKSTS [LSB_CLOSED] = 0;
end;
LNKSTS [LSB_CCWAIT] = 0;
!
! Startup waiting process
!
DECLARE_NETWORK_EVENT (.LINK_INFO);
end;
end; ! of ACC_AST
!
! Main Accept Processing
!
if (INTERRUPT_OFF; LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .LINK_IDENTIFIER, IQ_SCAN); INTERRUPT_ON;
.LINK_INFO) neq 0
then
begin
bind
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK,
NETSTS = LINK_INFO [LINK_LINK_SB] : $NETWORK_STATUS_BLOCK;
ACC$S (.LINK_INFO [LINK_LUN],, LINK_INFO [LINK_LINK_SB], ACC_AST,
<LINK_INFO [LINK_GNDB],
RSX$_GNDB_ALLOCATION, (if .DATA_LEN eql 0 then 0 else .DATA_PTR), .DATA_LEN>);
WAIT_FOR_NETWORK (LINK_INFO, (.LNKSTS [LSB_CCWAIT]));
if (.LNKSTS [LSB_CONNECTED])
then
$true
else
begin
if .NETSTS [NETSB$ERR] neq IS$SUC then NMU$NETWORK_REJECT (.LINK_IDENTIFIER, 0, 0);
$false
end
end
else
$false
!
end; ! End of NMU$NETWORK_ACCEPT
global routine %unquote NMU$NETWORK_REJECT (LINK_IDENTIFIER, REASON, DATA_LEN, DATA_PTR) =
!++
! Functional description:
!
! This routine rejects the connection to a TARGET link
! end. The link was initially opened by a call to the
! NMU$NETWORK_TARGET routine.
!
! Formal parameters: none
!
! .LINK_IDENTIFIER Link id for the target link end.
! .REASON Reason code for rejection
! .DATA_LEN Length of optional reject data
! .DATA_PTR Pointer to optional reject data
!
! Routine value:
!
! $true - Reject Done
! $false - Reject Not Done
!
! Side effects: none
!
!--
begin
local
LINK_INFO : ref LINK_INFO_BLOCK;
!
! Routine to process REJ$ ASTs
!
routine REJ_AST NETWORK_INTERRUPT_ROUTINE =
begin
map
NETWORK_STATUS_BLOCK : ref $NETWORK_STATUS_BLOCK;
local
LINK_INFO : ref LINK_INFO_BLOCK;
!
! Find our LINK_INFO block
!
if (LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .NETWORK_STATUS_BLOCK [NETSB$LINK_ID], IQ_SCAN)) neq 0
then
!
! Update status to reflect connect complete
!
begin
bind
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK;
LNKSTS [LSB_CLOSED] = 1;
LNKSTS [LSB_CONNECTED] = 0;
LNKSTS [LSB_CCWAIT] = 0;
!
! Startup waiting process
!
DECLARE_NETWORK_EVENT (.LINK_INFO);
end;
end; ! of REJ_AST
!
! Main Reject Processing
!
if (INTERRUPT_OFF; LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .LINK_IDENTIFIER, IQ_SCAN); INTERRUPT_ON;
.LINK_INFO) neq 0
then
begin
REJ$S (NMU$_NETWORK_LUN,, LINK_INFO [LINK_LINK_SB], REJ_AST,
<LINK_INFO [LINK_GNDB],
RSX$_GNDB_ALLOCATION, (if .DATA_LEN eql 0 then 0 else .DATA_PTR), .DATA_LEN>);
WAIT_FOR_NETWORK (LINK_INFO, (.LNKSTS [LSB_CCWAIT]));
$true
end
else
$false
!
end; ! End of NMU$NETWORK_REJECT
global routine %unquote NMU$NETWORK_READ (LINK_IDENTIFIER, BUFFER_SIZE, BUFFER) =
!++
! Functional description:
!
! This routine reads data from the specified logical link into
! the supplied buffer. This calls blocks until either data is
! available or the link is disco<<nnected.
!
! Formal parameters:
!
! .LINK_IDENTIFIER Link identifier.
! .BUFFER Address of buffer to read data into.
! .BUFFER_SIZE Number of 8 bit bytes available in buffer.
!
! Routine value:
!
! Number of bytes read in (0 = link error)
!
! Side effects: none
!
!--
begin
local
LINK_INFO : ref LINK_INFO_BLOCK;
!
! Interrupt Service Routine for Receives
!
routine REC_AST NETWORK_INTERRUPT_ROUTINE =
begin
map
NETWORK_STATUS_BLOCK : ref $NETWORK_STATUS_BLOCK;
local
LINK_INFO : ref LINK_INFO_BLOCK;
!
! Find our LINK_INFO block
!
if (LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .NETWORK_STATUS_BLOCK [NETSB$LINK_ID], IQ_SCAN)) neq 0
then
!
! Update status to reflect receive complete
!
begin
LINK_INFO [LINK_INPUT_IN_PROGRESS] = 0;
!
! Startup waiting process
!
DECLARE_NETWORK_EVENT (.LINK_INFO);
end;
end; ! of REC_AST
!
! Main Receive Processing
!
if (INTERRUPT_OFF; LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .LINK_IDENTIFIER, IQ_SCAN); INTERRUPT_ON;
.LINK_INFO) neq 0
then
begin
bind
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK;
if not .LNKSTS [LSB_CONNECTED]
then
0
else
begin
LINK_INFO [LINK_INPUT_IN_PROGRESS] = 1;
REC$S (.LINK_INFO [LINK_LUN],, LINK_INFO [LINK_IN_SB], REC_AST, <.BUFFER, .BUFFER_SIZE>);
!
! Wait for data buffer to be received
!
WAIT_FOR_NETWORK (LINK_INFO, (.LINK_INFO [LINK_INPUT_IN_PROGRESS]));
!
! Return Error Indication if any
!
begin
bind
LNKIOSB = LINK_INFO [LINK_IN_SB] : $NETWORK_STATUS_BLOCK;
if .LNKIOSB [NETSB$ERR] neq IS$SUC then 0 else .LNKIOSB [NETSB$IO_COUNT]
end
end
end
else
0
end; ! End of NMU$NETWORK_READ
global routine %unquote NMU$NETWORK_WRITE (LINK_IDENTIFIER, EOM_FLAG, BUFFER_SIZE, BUFFER) =
!++
! Functional description:
!
! This routine writes data to the specified logical link from
! the supplied buffer.
!
! Formal parameters:
!
! .LINK_IDENTIFIER Link identifier.
! .EOM_FLAG Flag to indicate end of message.
! .BUFFER Address of buffer to write data from.
! .BUFFER_SIZE Number of 8 bit bytes of data in buffer.
!
! Routine value:
!
! $true Write succeeded
! $false Write failed, link disconnected.
!
! Side effects: none
!
!--
begin
local
LINK_INFO : ref LINK_INFO_BLOCK;
!
! Interrupt Service Routine for Transmits
!
routine SND_AST NETWORK_INTERRUPT_ROUTINE =
begin
map
NETWORK_STATUS_BLOCK : ref $NETWORK_STATUS_BLOCK;
local
LINK_INFO : ref LINK_INFO_BLOCK;
!
! Find our LINK_INFO block
!
if (LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .NETWORK_STATUS_BLOCK [NETSB$LINK_ID], IQ_SCAN)) neq 0
then
!
! Update status to reflect transmit complete
!
begin
LINK_INFO [LINK_OUTPUT_IN_PROGRESS] = 0;
!
! Startup waiting process
!
DECLARE_NETWORK_EVENT (.LINK_INFO);
end;
end; ! of SND_AST
!
! Main Send Processing
!
if (INTERRUPT_OFF; LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .LINK_IDENTIFIER, IQ_SCAN); INTERRUPT_ON;
.LINK_INFO) neq 0
then
begin
bind
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK;
if not .LNKSTS [LSB_CONNECTED]
then
$false
else
begin
if not .EOM_FLAG
then
return $false
else
begin
bind
NETSTS = LINK_INFO [LINK_OUT_SB] : $NETWORK_STATUS_BLOCK;
LINK_INFO [LINK_OUTPUT_IN_PROGRESS] = 1;
SND$S (.LINK_INFO [LINK_LUN],, LINK_INFO [LINK_OUT_SB], SND_AST, <.BUFFER, .BUFFER_SIZE>);
!
! Wait for data buffer to be transmitted
!
WAIT_FOR_NETWORK (LINK_INFO, (.LINK_INFO [LINK_OUTPUT_IN_PROGRESS]));
if .NETSTS [NETSB$ERR] neq IS$SUC then $false else $true
end
end
end
else
$false
end; ! End of NMU$NETWORK_WRITE
global routine %unquote NMU$NETWORK_ABORT (LINK_IDENTIFIER, REASON, DATA_LEN, DATA_PTR) =
!++
! Functional description:
!
!
! Formal parameters:
!
! .LINK_IDENTIFIER Identifier of link to abort
! .REASON Reason code to aborting link
! .DATA_LEN Length of optional abort data
! .DATA_PTR Pointer to optional abort data
!
! Routine value:
!
! $true - Abort has been done
! $false - Abort could not be done
!
! Side effects: none
!
!--
begin
local
LINK_INFO : ref LINK_INFO_BLOCK;
!
! Interrupt Service Routine for Aborts
!
routine ABT_AST NETWORK_INTERRUPT_ROUTINE =
begin
map
NETWORK_STATUS_BLOCK : ref $NETWORK_STATUS_BLOCK;
local
LINK_INFO : ref LINK_INFO_BLOCK;
!
! Find our LINK_INFO block
!
if (LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .NETWORK_STATUS_BLOCK [NETSB$LINK_ID], IQ_SCAN)) neq 0
then
!
! Update status to reflect disconnect complete
!
begin
bind
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK;
LNKSTS [LSB_ABORTED] = 1;
LNKSTS [LSB_CLOSED] = 1;
LNKSTS [LSB_CCWAIT] = 0;
LNKSTS [LSB_CIWAIT] = 0;
LNKSTS [LSB_CONNECTED] = 0;
!
! Startup waiting process
!
DECLARE_NETWORK_EVENT (.LINK_INFO);
end;
end; ! of ABT_AST
!
! Main Processing for Aborts
!
if (INTERRUPT_OFF; LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .LINK_IDENTIFIER, IQ_SCAN); INTERRUPT_ON;
.LINK_INFO) neq 0
then
begin
bind
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK;
if not .LNKSTS [LSB_CLOSED]
then
begin
ABT$S (.LINK_INFO [LINK_LUN],, LINK_INFO [LINK_LINK_SB], ABT_AST,
<(if .DATA_LEN eql 0 then 0 else .DATA_PTR), .DATA_LEN>);
WAIT_FOR_NETWORK (LINK_INFO, ( not .LNKSTS [LSB_ABORTED]));
end;
NETWORK_LUNS [.LINK_INFO [LINK_LUN] - NMU$_NETWORK_LUN] = 0;
NMU$QUEUE_EXTRACT (INFO_QUEUE, .LINK_INFO);
NMU$MEMORY_RELEASE (.LINK_INFO, LINK_INFO_BLOCK_ALLOCATION);
$true
end
else
$false
end; ! End of NMU$NETWORK_ABORT
global routine %unquote NMU$NETWORK_CLOSE (LINK_IDENTIFIER, DATA_LEN, DATA_PTR) =
!++
! Functional description:
!
!
! Formal parameters:
!
! .LINK_IDENTIFIER Identifier of link to close
! .DATA_LEN Length of optional close data
! .DATA_PTR Pointer to optional close data
!
! Routine value:
!
! $true - Close Completed
! $false - Close could not be done
!
! Side effects: none
!
!--
begin
local
LINK_INFO : ref LINK_INFO_BLOCK;
!
! Interrupt Service Routine for Disconnects
!
routine DSC_AST NETWORK_INTERRUPT_ROUTINE =
begin
map
NETWORK_STATUS_BLOCK : ref $NETWORK_STATUS_BLOCK;
local
LINK_INFO : ref LINK_INFO_BLOCK;
!
! Find our LINK_INFO block
!
if (LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .NETWORK_STATUS_BLOCK [NETSB$LINK_ID], IQ_SCAN)) neq 0
then
!
! Update status to reflect disconnect complete
!
begin
bind
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK;
LNKSTS [LSB_CLOSED] = 1;
LNKSTS [LSB_CCWAIT] = 0;
LNKSTS [LSB_CIWAIT] = 0;
LNKSTS [LSB_CONNECTED] = 0;
!
! Startup waiting process
!
DECLARE_NETWORK_EVENT (.LINK_INFO);
end;
end; ! of DSC_AST
!
! Main Processing for Disconnects
!
if (INTERRUPT_OFF; LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .LINK_IDENTIFIER, IQ_SCAN); INTERRUPT_ON;
.LINK_INFO) neq 0
then
begin
bind
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK;
if not .LNKSTS [LSB_CLOSED]
then
begin
DSC$S (.LINK_INFO [LINK_LUN],, LINK_INFO [LINK_LINK_SB], DSC_AST,
<(if .DATA_LEN eql 0 then 0 else .DATA_PTR), .DATA_LEN>);
WAIT_FOR_NETWORK (LINK_INFO, ( not .LNKSTS [LSB_CLOSED]));
end;
NETWORK_LUNS [.LINK_INFO [LINK_LUN] - NMU$_NETWORK_LUN] = 0;
NMU$QUEUE_EXTRACT (INFO_QUEUE, .LINK_INFO);
NMU$MEMORY_RELEASE (.LINK_INFO, LINK_INFO_BLOCK_ALLOCATION);
$true
end
else
$false
end; ! End of NMU$NETWORK_CLOSE
global routine %unquote NMU$NETWORK_STATUS (LINK_IDENTIFIER, STS_BLK) =
!++
! Functional description:
!
! This routine supplies the status of a logical link.
!
! Formal parameters:
!
! .LINK_IDENTIFIER Link identifier.
! .STS_BLK Address of status block.
!
! Routine value:
!
! $true - Link Status Available
! $false - Link Status Unavailable
!
! Side effects: none
!
!--
begin
local
LINK_INFO : ref LINK_INFO_BLOCK;
if (INTERRUPT_OFF; LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .LINK_IDENTIFIER, IQ_SCAN); INTERRUPT_ON;
.LINK_INFO) neq 0
then
begin
bind
LNKSTS = LINK_INFO [LINK_STATUS] : vector [1];
.STS_BLK = .LNKSTS [0];
$true
end
else
$false
end; ! End of NMU$NETWORK_STATUS
global routine %unquote NMU$NETWORK_VALIDATE (CONN_BLK) =
!++
! Functional description:
!
!
! Formal parameters:
!
! .CONN_BLK Address of a link connect block.
!
! Routine value:
!
! 0 - Unprivledged user
! 1 - Privledged user
!
! Side effects: none
!
!--
begin
map
CONN_BLK : ref CONNECT_BLOCK;
local
CNT,
PTR;
PTR = ch$ptr (UN$USER,, 8);
if (CNT = ch$rchar_a (PTR)) neq 0
then
begin
if .CONN_BLK [CB_USERID_LENGTH] neq .CNT then return 0;
if ch$neq (.CNT, .CONN_BLK [CB_USERID], .CNT, .PTR, 0) then return 0;
end;
PTR = ch$ptr (UN$PASSWORD,, 8);
if (CNT = ch$rchar_a (PTR)) neq 0
then
begin
if .CONN_BLK [CB_PASSWORD_LENGTH] neq .CNT then return 0;
if ch$neq (.CNT, .CONN_BLK [CB_PASSWORD], .CNT, .PTR, 0) then return 0;
end;
PTR = ch$ptr (UN$ACCOUNT,, 8);
if (CNT = ch$rchar_a (PTR)) neq 0
then
begin
if .CONN_BLK [CB_ACCOUNT_LENGTH] neq .CNT then return 0;
if ch$neq (.CNT, .CONN_BLK [CB_ACCOUNT], .CNT, .PTR, 0) then return 0;
end;
1
end; ! End of NMU$NETWORK_VALIDATE
global routine %unquote NMU$NETWORK_LOCAL =
!++
! Functional description:
!
! This routine returns a pointer to the local node
! name string.
!
! Formal parameters: none
!
! Routine value:
!
! Byte pointer to node name string.
!
! Side effects: none
!
!--
begin
ch$ptr (LOCAL_NODE,, 8)
end; ! End of NMU$NETWORK_LOCAL
!<BLF/PAGE>
routine DECLARE_NETWORK_EVENT (LINK_INFO) : novalue =
!++
! Functional description:
!
! This routine flags a network event and wakes up the scheduler.
!
! Formal parameters:
!
! .LINK_INFO is the LINK_INFO_BLOCK for this event
!
! Routine value: none
!
! Side effects: none
!
!--
begin
map
LINK_INFO : ref LINK_INFO_BLOCK;
NMU$SCHED_FLAG (LINK_INFO [LINK_EVENT]);
PROCESS_WAKE;
end; ! of DECLARE_NETWORK_EVENT
!<BLF/PAGE>
!++
! routine GND_AST VANILLA_INTERRUPT_ROUTINE
! routine PROCESS_MAILBOX_ENTRY
!
! Functional description:
!
! These routines process various asynchronous network events signaled
! via the "Network Mailbox".
! GND_AST is entered when asynchronous events are available.
! PROCESS_MAILBOX_ENTRY is the main processing code for the events.
!
! Formal parameters:
!
! $RSX_AST_PARAMETERS - Not Touched
!
! Routine value: none
!
! Side effects: none
!
!--
routine GND_AST VANILLA_INTERRUPT_ROUTINE =
begin
PROCESS_MAILBOX_ENTRY ();
end; !of GND_AST
routine PROCESS_MAILBOX_ENTRY : novalue =
!++
! Functional description:
!
!
! Formal parameters:
!
!
! Routine value: none
!
! Side effects: none
!
!--
begin
own
GND_SB : $NETWORK_STATUS_BLOCK,
REJ_BUF : vector [3, byte] initial (byte (-21, 9, 0)),
GND_BUF : RSX$_GNDB_BLOCK,
GND_DIR : GNDW$ (NMU$_NETWORK_LUN, NMU$_NETWORK_FLAG, GND_SB,, <GND_BUF, RSX$_GNDB_ALLOCATION>),
REJ_DIR : REJW$ (NMU$_NETWORK_LUN, NMU$_NETWORK_FLAG, GND_SB,,
<GND_BUF, RSX$_GNDB_ALLOCATION,
REJ_BUF, 3>);
local
LINK_INFO : ref LINK_INFO_BLOCK;
!
! Routine to find Target Links which match connections
!
routine TQ_SCAN (LINK_INFO, CURRENT_GNDB) =
begin
map
CURRENT_GNDB : ref RSX$_GNDB_BLOCK,
LINK_INFO : ref LINK_INFO_BLOCK;
bind
GNDB = LINK_INFO [LINK_GNDB] : RSX$_GNDB_BLOCK,
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK;
!
! Ensure this link is a waiting target.
!
if (.LNKSTS [LSB_SERVER] and .LNKSTS [LSB_CIWAIT])
then
!
! Compare objects and determine matching characteristics
!
case .GNDB [GNDB_DEST_FORMAT] from 0 to 2 of
set
[0] : ! Format 0 Descriptor
begin
if .CURRENT_GNDB [GNDB_DEST_FORMAT] neq 0 then return 0;
if .CURRENT_GNDB [GNDB_DEST_OBJECT] eql .GNDB [GNDB_DEST_OBJECT]
then
return .LINK_INFO
else
return 0;
end;
[1] : ! Format 1 Descriptor
begin
if .CURRENT_GNDB [GNDB_DEST_FORMAT] neq 1 then return 0;
if .CURRENT_GNDB [GNDB_DEST_OBJECT] neq .GNDB [GNDB_DEST_OBJECT] then return 0;
if ch$eql (.CURRENT_GNDB [GNDB_D1_LENGTH], ch$ptr (CURRENT_GNDB [GNDB_D1_TASK_NAME]),
.GNDB [GNDB_D1_LENGTH], ch$ptr (GNDB [GNDB_D1_TASK_NAME]), 0)
then
return .LINK_INFO
else
return 0;
end;
[2] : ! Format 2 Descriptor
return 0;
tes
else
0
end; ! of TQ_SCAN
!
! Routine to find LINK_INFO block via LUN
!
routine IQ_LUN_SCAN (LINK_INFO, LUN) =
begin
map
LINK_INFO : ref LINK_INFO_BLOCK;
if .LINK_INFO [LINK_LUN] eql .LUN then .LINK_INFO else 0
end; ! of IQ_LUN_SCAN
!
! Main processing of Mailbox Entries
! Get the mailbox entry
!
dir$ (GND_DIR);
if .GND_SB [NETSB$ERR] neq IS$SUC then return;
!
! Classify request into Connects, Disconnects, and Interrupt Messages. Then
! process accordingly.
!
case .GND_SB [NETSB$ERR1] from NT$CON to NT$ABO of
set
[NT$CON] : !Connect Received
begin
if (LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, GND_BUF, TQ_SCAN)) eql 0
then
begin ! No waiting TARGET found, Reject Connection
dir$ (REJ_DIR);
end
else
begin ! We have a waiting TARGET
if ASSIGN_A_LUN (.LINK_INFO) lss 0
then
dir$ (REJ_DIR)
else
begin
bind
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK,
NETSTS = LINK_INFO [LINK_LINK_SB] : $NETWORK_STATUS_BLOCK;
NETSTS [NETSB$ERROR] = IS$SUC;
ch$copy (minu (.GND_SB [NETSB$CNT], RSX$_GNDB_ALLOCATION), ch$ptr (GND_BUF), 0,
RSX$_GNDB_ALLOCATION, ch$ptr (LINK_INFO [LINK_GNDB]));
LNKSTS [LSB_CIWAIT] = 0;
DECLARE_NETWORK_EVENT (.LINK_INFO);
end;
end;
end;
[NT$INT] : !Interrupt Message Received
return; !Ignore for now
[NT$DSC, NT$ABT] : !Disconnect or Abort Received
begin
if (LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .GND_SB [NETSB$CNT1], IQ_LUN_SCAN)) eql 0
then
return
else
begin
bind
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK;
LINK_INFO [LINK_OPTI_LENGTH] = .GND_SB [NETSB$CNT];
ch$copy (minu (.GND_SB [NETSB$CNT], 16), ch$ptr (GND_BUF), 0, 16,
ch$ptr (LINK_INFO [LINK_OPTI_DATA]));
LNKSTS [LSB_CONNECTED] = 0;
DECLARE_NETWORK_EVENT (.LINK_INFO);
end;
end;
[NT$ABO] :
begin
if (LINK_INFO = NMU$QUEUE_SCAN (INFO_QUEUE, .GND_SB [NETSB$CNT1], IQ_LUN_SCAN)) eql 0
then
return
else
begin
bind
LNKSTS = LINK_INFO [LINK_STATUS] : LINK_STATUS_BLOCK;
LNKSTS [LSB_REASON] = .GND_SB [NETSB$CNT];
LINK_INFO [LINK_OPTI_LENGTH] = 0;
LNKSTS [LSB_CONNECTED] = 0;
DECLARE_NETWORK_EVENT (.LINK_INFO);
end;
end;
[INRANGE, OUTRANGE] : !Erroneous code
return;
tes;
!
end; ! of PROCESS_MAILBOX_ENTRY
routine IQ_SCAN (LINK_INFO, LINK_IDENTIFIER) =
!++
! Functional description:
!
! This routine is called when scanning the INFO_QUEUE by
! NMU$QUEUE_SCAN to find the entry associated with a
! particular link identifier.
!
! Formal parameters:
!
! .LINK_INFO address of current entry on the info queue.
! .LINK_IDENTIFIER identifier of link to find data base for.
!
! Routine value:
!
! Address of link info block if matched (0 otherwise).
!
! Side effects: none
!
!--
begin
map
LINK_INFO : ref LINK_INFO_BLOCK;
if .LINK_INFO [LINK_ID] eql .LINK_IDENTIFIER then .LINK_INFO else 0
end; ! End of IQ_SCAN
routine ASSIGN_A_LUN (LINK_INFO) =
!++
! Functional description:
!
! This routine assigns a LUN for usage by a link. It assigns the
! LUN based upon the TYPE or LINK (e.g. SOURCE_LINK or TARGET_LINK).
!
! Formal parameters:
!
! LINK_INFO = LINK_INFO_BLOCK for this link
!
! Routine value:
!
! gtr 0 - the LUN number assigned
! lss 0 - No LUN available
!
! Side effects:
!
! *******Warning*******
! SOURCE_LINK LUNs are assigned at non-interrupt level
! TARGET_LINK LUNs are assigned at interrupt level
!
!--
begin
map
LINK_INFO : ref LINK_INFO_BLOCK;
local
LUN_ADR : ref vector,
LUN_CNT,
LUN_NUMBER;
!
! Determine search algorithm based upon type
!
LUN_NUMBER = NMU$_NETWORK_LUN + 1;
LUN_CNT = NMU$_NETWORK_MAX_INCOMING;
LUN_ADR = NETWORK_LUNS [1];
if .LINK_INFO [LINK_TYPE] eql SOURCE_LINK
then
begin
LUN_NUMBER = NMU$_NETWORK_LUN + NMU$_NETWORK_MAX_INCOMING + 1;
LUN_CNT = NMU$_NETWORK_MAX_LUNS - NMU$_NETWORK_MAX_INCOMING;
LUN_ADR = NETWORK_LUNS [NMU$_NETWORK_MAX_INCOMING + 1];
end;
do
begin
if
begin
local VAL;
VAL = .LUN_ADR [0];
LUN_ADR = LUN_ADR [1]; %(force auto-increment)%
.VAL
end eql 0
then
begin
LUN_ADR = LUN_ADR [-1]; %(force auto-decrement)%
LUN_ADR [0] = .LINK_INFO;
LINK_INFO [LINK_LUN] = .LUN_NUMBER;
LINK_INFO [LINK_FLAG] = .LUN_NUMBER;
return .LUN_NUMBER;
end;
LUN_NUMBER = .LUN_NUMBER + 1;
end
while (LUN_CNT = .LUN_CNT - 1) neq 0;
LUN_NUMBER = -1;
return .LUN_NUMBER
end; ! of ASSIGN_A_LUN
end ! End of module NMUNET
eludom
! Local Modes:
! Mode:Fundamental
! Comment Start:!
! Comment Column:40
! Comment Rounding:+1
! Auto Save Mode:2
! End: