Google
 

Trailing-Edge - PDP-10 Archives - BB-P363B-SM_1985 - mcb/nml/nmudlx.b16
There are no other files named nmudlx.b16 in the archive.
!NET:<PECKHAM.DEVELOPMENT>NMUDLX.B16.3 28-Apr-82 13:42:00, Edit by PECKHAM
!
! Ident 26.
! Change NMU$DLX_READ into NMU$DLX_TIMED_READ to allow for
! timeout interval specification.
!
!NET:<PECKHAM.DEVELOPMENT>NMUDLX.B16.3  2-Mar-82 11:43:34, Edit by PECKHAM
!
! Ident 25.
! Initialize I/O status blocks for events.
!
!NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NMUDLX.B16.14  1-Mar-82 16:10:02, Edit by WEBBER
!
! Ident 24.
! Add an extra return code from NMU$DLX_READ for "timeout".
!
!NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NMUDLX.B16.13  4-Feb-82 11:37:14, Edit by WEBBER
!
! Ident 23.
! Increase read timeout interval to allow CHK11 to work (Note: at some point,
! NMLDTL will have to distinguish CHK11 and pass a special timeout value
! down when it's operating.)
!
!NET:<DECNET20-V3P1.NMLLIB>NMUDLX.B16 4-Dec-81 16:53:19, Edit by THIGPEN
!
! Ident 22.
! Add timeout arg to NMU$SCHED_WAIT call
!
!NET:<DECNET20-V3P1.NMU>NMUDLX.B16.2  1-Oct-81 16:53:19, Edit by GUNN
!
! Ident 21.
! Add IE$SRE to list of I/O error codes defined in $NM$DLX_ERRORS.
!
module NMUDLX (ident = 'X00.26'
		) = 				! Direct Line Access
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 Management
!
! Abstract: This module provides direct line access for
!	    Direct Line Access in MCB Environments.
!
! Environment: MCB V3.2 RSX User Mode
!
! Author: Scott G. Robinson	Creation date: 27-May-81
!
! Modified by:
!
!--

!
! Include files
!

library 'NMULIB';				! Get all required definitions

!
! Global routines
!

forward routine
         NMU$DLX_OPEN,                  ! Open link
         NMU$DLX_TIMED_READ,            ! Read MOP message on link
         NMU$DLX_WRITE,                 ! Write MOP message on link
         NMU$DLX_TYPE,                  ! Returns circuit MOP device type
         NMU$DLX_INITIALIZE,            ! Initialize protocol on link
         NMU$DLX_CLOSE;                 ! Close link

!
! Local routines
!

forward routine
    $DLX_AST : IO_INTERRUPT_LINKAGE,
    MAP_TO_RESPONSE;

!
! Macros
!

macro
    $NM$DLX_ERRORS =
	IE$SPC,$NICE$ERR_MPE,'Internal Buffer Length Confusion',
	IE$BDV,$NICE$ERR_IID,'Unknown Entity',
	IE$BBE,$NICE$ERR_HWF,'Entity Device Failure',
	IE$DNR,$NICE$ERR_REE,'No Dynamic Resources',
	IE$ALN,$NICE$ERR_REE,'No I/O Resources',
	IE$DAA,$NICE$ERR_CWS,'Entity Already In Use',
	IE$NLN,$NICE$ERR_CWS,'Entity Not Open',
	IE$ABO,$NICE$ERR_OPF,'Operation Aborted',
	IE$CNR,$NICE$ERR_OPF,'Entity Open Request Failed',
	IE$ISQ,$NICE$ERR_OPF,'Maintenance Mode Unsupported By Entity',
	IE$SRE,$NICE$ERR_LCE,'Send/Receive Failure',
        IE$TMO,$NICE$ERR_LCE,'Response Timeout',
	IE$EOT,$NICE$ERR_LCE,'START Received In Maintenance Mode' %,
    GENERATE_RESPONSE_TEST [RSX_ERROR,NML_ERROR,STRING] =
	[RSX_ERROR]:(MESSAGE_PTR = CH$ASCIC(STRING);
		     NICE_CODE = NML_ERROR) %;

macro
    $$DLX_INTERFACE_EXPAND (FUNCTION, TYPE, ENTITY, BUFFER, LENGTH) =
 

    begin

           %if not %declared(IOSB) %then
           stacklocal
              IOSB: $IO_STATUS_BLOCK ;         ! I/O Status block

           %fi

	   $IO_STATUS_BLOCK_INITIALIZE (IOSB);
	   NMU$SCHED_EVENT (IOSB [IOSB$_EVENT], $true);

           qio$s (FUNCTION,.LUN$DL,,,IOSB,$DLX_AST,<
                   %if not %null (LENGTH) %then
                       %if not %null(BUFFER) %then
                          (if .LENGTH eql 0 then 0 else BUFFER)
                       %fi
                   %fi,
                   %if not %null(BUFFER) %then
                       %if not %null(LENGTH) %then .LENGTH
                       %fi
                   %fi,
		   %if not %null(TYPE) %then
			((TYPE+1) ^ 8)
		   %fi,
		   %if not %null(ENTITY) %then
			ENTITY
		   %fi>);
	   while .IOSB [IOSB$ERROR] eql 0 do
		NMU$SCHED_WAIT (IOSB [IOSB$_EVENT],0);

            %if not %null(LENGTH) %then LENGTH = .IOSB[IOSB$_COUNT]; %fi
            .IOSB[IOSB$ERR]
    end %;

macro
    $DLX$OPEN (TYPE, ENTITY) =
	$$DLX_INTERFACE_EXPAND(DLX$_OPEN,TYPE,ENTITY,,) %,
    $DLX$CLOSE =
        $$DLX_INTERFACE_EXPAND(DLX$_CLOSE,,,,) %,
    $DLX$READ (BUFFER, LENGTH, TIMEOUT) =
	$$DLX_INTERFACE_EXPAND(DLX$_READ,,TIMEOUT,BUFFER,LENGTH) %,
    $DLX$WRITE (BUFFER, LENGTH) =
	$$DLX_INTERFACE_EXPAND(DLX$_WRITE,,,BUFFER,LENGTH) %;

!
! Equated symbols
!

literal
    DLX$_OPEN = IO$CON,
    DLX$_CLOSE = IO$DIS,
    DLX$_READ = IO$RCV,
    DLX$_WRITE = IO$XMT;

!<BLF/NOFORMAT>
!<BLF/NOERROR>

      $field
	MCB$IOSB$fields =		!  QIO Status Block
	  set
	  IOSB$ERROR	= [$integer],	! Composite error code:
		$overlay(IOSB$ERROR)
	  	IOSB$ERR = [$tiny_integer],     ! error code
	  	IOSB$ERR1= [$tiny_integer],     ! 0 = I/O error, -1 = directive error
		$continue
	  IOSB$_COUNT= [$integer],	! I/O count (bytes)
	  IOSB$_EVENT = [$sub_block(EVENT_BLOCK_SIZE)]  ! IO Event Block
	  tes;

literal
    MCB$_IOSB_SIZE = $field_set_size,
    MCB$_IOSB_ALLOCATION = $field_set_units;

macro
    $IO_STATUS_BLOCK =
	    BLOCK[MCB$_IOSB_SIZE]  FIELD( MCB$IOSB$fields ) %;

macro
    $IO_STATUS_BLOCK_INITIALIZE (IOSB) =
	begin
	bind $DLX$IOSB = IOSB : $IO_STATUS_BLOCK;
	local ADR : ref vector;
	ADR = $DLX$IOSB [IOSB$_EVENT];
	decru $DLX$CNT from EVENT_BLOCK_SIZE to 1 do
	    (ADR [0] = 0; ADR = ADR [1];);
	end %;

$field
    DLX$LUN$FIELDS =
	set
	LUN$_LUN = [$integer],          ! The LUN for this DLX Access
        LUN$_TYPE = [$byte],            ! Type of Access for this LUN
        LUN$_ID = [$byte]               ! The ID of this LUN
	tes;

literal
    DLX$_LUN_SIZE = $field_set_size,
    DLX$_LUN_ALLOCATION = $field_set_units;

macro
    $DLX_LUN_BLOCK =
	    BLOCK[DLX$_LUN_SIZE]  FIELD( DLX$LUN$fields ) %;



!<BLF/ERROR>
!<BLF/FORMAT>
!
! Own Storage
!

own
    DLUN0 : $DLX_LUN_BLOCK initial (NMU$_DL0_DEVICE_LUN, 1^8),
    DLUN1 : $DLX_LUN_BLOCK initial (NMU$_DL1_DEVICE_LUN, 2^8),
    DLX_NEXT : initial (0);

!
! External references
!

external routine
    NMU$SCHED_MANAGER;
global routine NMU$DLX_OPEN (USAGE, CIRCUIT_ID, RESPONSE_POINTER) =

!++
! Functional description:
!
!        This routine opens a link in MOP mode.  The link is
!        conditioned to operate properly depending on the
!        use that the link will be put to.
!
! Formal parameters:
!
!	.USAGE		  Type of usage for the link.
!			  - DLX_LOAD
!			  - DLX_DUMP
!			  - DLX_LOOP
!			  - DLX_OTHER
!	.CIRCUIT_ID	  Pointer to counted ASCII identifier string
!	.RESPONSE_POINTER Pointer to NICE response buffer
!
! Implicit inputs: none
! Implicit outputs: none
!
! Routine value:
!
!	<0	Error occured while opening link
!	>=0	Link identifier (for any future reference)
!
! Side effects: none
!
!--

    begin

    local
	DLX_ID,
	DLXLUN : ref $DLX_LUN_BLOCK;

    stacklocal
	IOSB : $IO_STATUS_BLOCK;

    $IO_STATUS_BLOCK_INITIALIZE (IOSB);
!
! Assign a DLX_ID and DLX_CONTROL_BLOCK with LUN if available
!

    if (DLXLUN =
	(case .USAGE from DLX_LOAD to DLX_OTHER of
	set
	[DLX_LOAD, DLX_DUMP] : (if .DLUN0 [LUN$_TYPE] neq 0 then 0 else DLUN0);
	[Inrange] : (if .DLUN1 [LUN$_TYPE] neq 0 then 0 else DLUN1);
	tes)
	) eqlu 0
    then
	IOSB [IOSB$ERROR] = IE$NDR		! Flag No Dynamic Resources
    else
	begin
!
! Try to OPEN the Entity; error return kept in IOSB
!

	bind
	    LUN$DL = DLXLUN [LUN$_LUN];

	$DLX$OPEN (CIRCUIT_, .CIRCUIT_ID)
	end;

!
! If no error then assign the DLX_LUN_BLOCK and return its' ID
! otherwise map the error response and fail the request.
!

    if .IOSB [IOSB$ERR] lss 0
    then
	MAP_TO_RESPONSE (.IOSB [IOSB$ERR], .RESPONSE_POINTER)
    else
	begin
	DLXLUN [LUN$_TYPE] = .USAGE;
	.DLXLUN [LUN$_ID]
	end

    end;					! End of DLX_OPEN
global routine NMU$DLX_TIMED_READ (ID, USAGE, PTR, LENGTH, TIMEOUT, RESPONSE_POINTER) =

!++
! Functional description:
!
!        This routine reads a maintenance message from the specified
!        circuit.
!
! Formal parameters:
!
!        .ID                Identifier for circuit
!        .USAGE             What type of read is being done
!                           - DLX_SECONDARY, DLX_DATA, DLX_OTHER
!        .PTR               Pointer to message buffer
!        .LENGTH            Number of bytes in message buffer to write
!	 .TIMEOUT	    If not zero, number of seconds to wait for response
!        .RESPONSE_POINTER  Pointer to NICE response buffer
!
! Implicit inputs: none
! Implicit outputs: none
!
! Routine value:
!
!        Number of bytes read on circuit
!
!		or
!
!	-2 for read timeout
!	-1 for any other error
!
! Side effects: none
!
!--

    begin

    local
      AMOUNT,
      DLXLUN : ref $DLX_LUN_BLOCK;

    stacklocal
      IOSB : $IO_STATUS_BLOCK;

    $IO_STATUS_BLOCK_INITIALIZE (IOSB);
!
! Find DLX_LUN_BLOCK for this request
!

    if (DLXLUN = (selectone .ID of
	    set
	    [1] : DLUN0;
	    [2] : DLUN1;
	    [otherwise] : 0;
	    tes)) nequ 0
    then
	begin
	bind
	    LUN$DL = DLXLUN [LUN$_LUN];

        AMOUNT = .LENGTH;
	$DLX$READ((.PTR),AMOUNT,.TIMEOUT);
	end
    else
       IOSB[IOSB$ERROR] = IE$BDV;
!
! Handle Error Mapping
!
    if .IOSB[IOSB$ERR] lss 0
    then
       begin
       MAP_TO_RESPONSE(.IOSB[IOSB$ERR],.RESPONSE_POINTER);
       if .IOSB[IOSB$ERR] eql IE$TMO
           then -2
	   else -1
       end
    else
       .AMOUNT
!
    end;					! End of NMU$DLX_TIMED_READ
global routine NMU$DLX_WRITE (ID, USAGE, PTR, LENGTH, RESPONSE_POINTER) =

!++
! Functional description:
!
!        This routine sends a maintenance message across the specified
!        circuit.
!
! Formal parameters:
!
!        .ID                Identifier for circuit
!        .USAGE             What type of write is being done
!                           - DLX_SECONDARY, DLX_TERTIARY, DLX_SYSTEM_IMAGE,
!                           - DLX_OTHER
!        .PTR               Pointer to message buffer
!        .LENGTH            Number of bytes in message buffer to write
!        .RESPONSE_POINTER  Pointer to NICE response buffer
!
! Implicit inputs: none
! Implicit outputs: none
!
! Routine value:
!
!        $false    Failure during write
!        $true     Write succeeded
!
! Side effects: none
!
!--

    begin

    local
      DLXLUN : ref $DLX_LUN_BLOCK;

    stacklocal
      IOSB : $IO_STATUS_BLOCK;

    $IO_STATUS_BLOCK_INITIALIZE (IOSB);
!
! Find DLX_LUN_BLOCK for this request
!

    if (DLXLUN = (selectone .ID of
	    set
	    [1] : DLUN0;
	    [2] : DLUN1;
	    [otherwise] : 0;
	    tes)) nequ 0
    then
	begin

        local
          AMOUNT;

	bind
	    LUN$DL = DLXLUN [LUN$_LUN];

        AMOUNT = .LENGTH;
	$DLX$WRITE((.PTR),AMOUNT);
	end
    else
       IOSB[IOSB$ERROR] = IE$BDV;
!
! Handle Error Mapping
!
    if .IOSB[IOSB$ERR] lss 0
    then
       begin
       MAP_TO_RESPONSE(.IOSB[IOSB$ERR],.RESPONSE_POINTER);
       $false
       end
    else
       $true
!
    end;					! End of NMU$DLX_WRITE
global routine NMU$DLX_TYPE (ID) =

!++
! Functional description:
!
!        This routine returns the device type code for the
!        specified circuit.
!
! Formal parameters:
!
!        .ID    Identifier for circuit
!
! Implicit inputs: none
! Implicit outputs: none
!
! Routine value:
!
!        Circuit device type code
!
! Side effects: none
!
!--

    begin
    28						!Type is always a KDP in MCB
    end;					! End of NMU$DLX_TYPE
global routine NMU$DLX_INITIALIZE (ID, RESPONSE_POINTER) =

!++
! Functional description:
!
!        This routine intializes protocol on links that need
!        such a service.
!
! Formal parameters:
!
!        .ID    Identifier for circuit
!
! Implicit inputs: none
! Implicit outputs: none
!
! Routine value: none
! Side effects: none
!
!--

    begin
    $true
    end;					! End of NMU$DLX_INITIALIZE
global routine NMU$DLX_CLOSE (ID) =

!++
! Functional description:
!
!        This routine releases the specified circuit from
!        use by Network Management.
!
! Formal parameters:
!
!        .ID    Identifier for circuit
!
! Implicit inputs: none
! Implicit outputs: none
!
! Routine value: none
! Side effects: none
!
!--

    begin

    local
	DLXLUN : ref $DLX_LUN_BLOCK;

!
! Find DLX_LUN_BLOCK for this request
!

    if (DLXLUN = (selectone .ID of
	    set
	    [1] : DLUN0;
	    [2] : DLUN1;
	    [otherwise] : 0;
	    tes)) nequ 0
    then
	begin

	bind
	    LUN$DL = DLXLUN [LUN$_LUN];

	$DLX$CLOSE;
	DLXLUN [LUN$_TYPE] = 0;
	$true
	end
    else
	$false

!
    end;					! End of NMU$DLX_CLOSE
routine $DLX_AST IO_INTERRUPT_ROUTINE =

!++
! Functional description:
!
!
! Interrupt Service Routine for DLX Operation Complete
!
!
! Formal parameters:
!
!  .IO_STATUS_BLOCK - points at IOSB for this operation
!
! Implicit inputs: none
! Implicit outputs: none
!
! Routine value: none
! Side effects: none
!
!--

    begin

    map
	IO_STATUS_BLOCK : ref $IO_STATUS_BLOCK;

    NMU$SCHED_FLAG (IO_STATUS_BLOCK [IOSB$_EVENT]);
    PROCESS_WAKE;
    end;					! of $DLX_AST
routine MAP_TO_RESPONSE(ERROR_CODE,RESPONSE_POINTER) =

!++
! Functional description:
!
!    Convert an ERROR_CODE into the appropriate RESPONSE_MESSAGE.
!
! Formal parameters:
!
!  .ERROR_CODE - the DLX Error Code Returned
!  .RESPONSE_POINTER - points at the RESPONSE buffer
!
! Implicit inputs: none
! Implicit outputs: none
!
! Routine value: none
! Side effects: none
!
!--

    begin

    local
	RESPONSE_PTR,
	NICE_CODE,
	MESSAGE_PTR;
!
! Generate Correct Code and Error Message
!
    selectone .ERROR_CODE of
        set
        GENERATE_RESPONSE_TEST($NM$DLX_ERRORS);

	[otherwise]:(NICE_CODE=$NICE$ERR_MPE;
		     MESSAGE_PTR = CH$ASCIC('Unknown Reason Code'));
        tes;
!
! Format Response Buffer
!
    RESPONSE_PTR = .RESPONSE_POINTER;
    MESSAGE_PTR = ch$plus(.MESSAGE_PTR,-1);
    putb((.NICE_CODE),RESPONSE_PTR);
    putw(ERROR_CODE,RESPONSE_PTR);
    begin
    local
	LENGTH;
    putb((LENGTH = minu(ch$rchar_a(MESSAGE_PTR),72)),RESPONSE_PTR);
    ch$move(.LENGTH,.MESSAGE_PTR,.RESPONSE_PTR);
    end;
    .ERROR_CODE
    end;					! of MAP_TO_RESPONSE
end						! End of NMUDLX

eludom