Trailing-Edge
-
PDP-10 Archives
-
BB-P363B-SM_1985
-
mcb/drivers/kdp.b16
There are no other files named kdp.b16 in the archive.
module KDP ( ! DDM driver for KMC11/DUP11
ident = 'X04230',
language (bliss16)
) =
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 KDP Driver
!
! ABSTRACT:
!
! This is the DDM process which services the KMC11 microprocessor
! which controls DUP11 synchronous line devices.
!
! ENVIRONMENT: MCB V3.0
!
! AUTHOR: Alan D. Peckham CREATION DATE: 10-Jan-81
!
! MODIFIED BY:
!
! S. I. GOLDFARB, 25-MAR-1977
! R. H. ROSENBAUM, 30-AUG-1977
! L. J. TWAITS, 10-SEP-1977
! D. B. TUTTLE, 10-OCT-1977
!
! Alan D. Peckham, 16-APR-80: Version 4
! 01 - Update to operate under MCB V3.0
! 02 - Update for MCB V3.1
! 03 - Rewrite in BLISS
! 04 - Only initialize KMC once during process initialization calls.
! 05 - Add Network Management event logging.
! 06 - Correct DDCMP data message bug in CITBA.
! 07 - Mark transmit buffer chain on transmitter underrun
! and return if finished.
! 08 - Optimize BDADR routine in MACRO-11.
! Fix buffer descriptor mapping bug.
! 09 - Split off Network Management code.
! 10 - Change SET_DESCRIPTOR to BDADR in transmit underrun error in COCTL.
! 11 - Change abort-DLXCP to DDXCP in KDPXME.
! 12 - Add control of DUPLEX, CLOCK, and LOOPBACK.
! 13 - Adapt to using new UNIBUS address converion routines.
! 14 - Fix signal bug in KDPNMX.
! 15 - Correct DSR event logging.
! 16 - Keep count of transmit/receive buffers to the KMC
! so that kills are done properly.
! 17 - Fix CTLGET to pass NM parameters to higher layer.
! 18 - Eliminate SIGNAL_STOP conditions and maintain error counters.
! 19 - Stop assign loop on RDB-get failure in GET_RECEIVE_BUFFERS.
! 20 - Use new microcode (X1.4) to set maintenance mode
! during control-in and eliminate SET_DUP_MODE.
! 21 - Optimize code in TIMPIN.
! If killing receives or transmits,
! do not increment DF_ASSIGNABLE_*_COUNT.
! Added RETURNED_RECEIVE_BUFFER routine to centralize accounting.
! Handle stack overflow problem of CALL$P overruns:
! Change COMPLETE to continue control processing indirectly
! by scheduling the CTL CCB to ourselves.
! 22 - Still haven't found our receive_BA bug.
! Centralize receive BA checking into RECEIVE_CCB.
! Remove RETURNED_RECEIVE_BUFFER.
! 23 - Found bug! It is interaction between unfinished KILCRA
! and CTLSTP. Solution:
! If D_PENDING_CONTROL_CCBS is non-empty (kill in progress),
! then queue CTLSTP CCB on it and go away.
! When kill completes, COMPLETE all CCBs on this queue.
! This continues the CTLSTP. Yay!!!!!
!--
!
! INCLUDE FILES:
!
library 'MCBLIB';
library 'XPORT';
library 'NMXLIB';
library 'KDPDAT';
!
! TABLE OF CONTENTS:
!
linkage
LINKAGE_CCB_DESC = jsr (register = 4, register = 1),
LINKAGE_CSR = jsr (register = 1),
LINKAGE_CSR_MC_LNG = jsr (register = 1, register = 2, register = 3),
LINKAGE_DESC_STS = jsr (register = 1, register = 3),
LINKAGE_PORT = jsr (register = 1),
LINKAGE_RING_POOL_COUNT = jsr (register = 2, register = 3,register = 4),
LINKAGE_STS = jsr (register = 3),
KDP_CCB = jsr (register = 4) : preserve (0) nopreserve (1, 3),
KDP_EDB = jsr (; register = 3),
KDP_LKG_DB_DESC_CCB = jsr (register = 5, register = 1; register = 4);
forward routine
ASSIGN_RECEIVE_BUFFER : LINKAGE_CCB novalue,
ASSIGN_TRANSMIT_BUFFER : novalue,
CIBAS : CALL$,
CICTL : CALL$,
CIRBA : CALL$,
CIRBK : CALL$,
CITBA : CALL$,
CITBK : CALL$,
COBAD : CALL$ novalue,
COCTL : CALL$ novalue,
COMPLETE : LINKAGE_DB_CCB novalue,
CORBA : CALL$ novalue,
COTBA : CALL$ novalue,
CTLGET : MCB_DB_CCB novalue,
CTLSET : MCB_DB_CCB novalue,
CTLSTP : MCB_DB_CCB novalue,
CTLSTR : MCB_DB_CCB novalue,
DEVICE_BROKEN : LINKAGE_DB novalue,
GET_RECEIVE_BUFFERS : novalue,
GIVE_TO_KMC : KDP_CCB novalue,
INITIALIZE_CHARACTERISTICS : novalue,
INITIALIZE_DESCRIPTOR_LIST : LINKAGE_RING_POOL_COUNT novalue,
KDPCTL : MCB_DB_CCB_MOD novalue,
KDPKIL : MCB_DB_CCB_MOD novalue,
KDPTIM : MCB_DB_MOD novalue,
KDPXME : MCB_DB_CCB_MOD novalue,
KILCRA : MCB_DB_CCB novalue,
KILKIL : MCB_DB_CCB novalue,
KILXKL : MCB_DB_CCB novalue,
PARAMETER_DEVICE_REGISTERS : KDP_REG novalue,
POLLING_FAILURE : novalue,
RECEIVE_CCB : KDP_LKG_DB_DESC_CCB,
RECEIVE_DONE : LINKAGE_DESC_STS novalue,
RECEIVE_KILLED : novalue,
SET_DESCRIPTOR : LINKAGE_CCB_DESC,
TIMLTM : MCB_DB novalue,
TIMPIN : MCB_DB novalue,
TIMPWF : MCB_DB novalue,
TIMRDB : MCB_DB_CCB novalue,
TRANSMIT_DONE : LINKAGE_DESC_STS novalue,
TRANSMIT_KILLED : novalue;
!
! MACROS:
!
macro
BDADR (LOW, HIGH) =
begin
local
ADDR;
$MCB_CONVERT_FROM_UBA_ADDRESS (LOW, HIGH, ADDR);
.ADDR
end %;
!
! EQUATED SYMBOLS:
!
literal
FALSE = 1 EQL 0,
NO_OPERATION = 0,
POLLING_THRESHOLD = 4,
TRUE = 1 EQL 1;
global literal
%name ('D.LEN') = D_LEN*%upval,
%name ('E.LEN') = E_LEN*%upval;
!+
! POLLING CLASS TABLE FOR DETERMINING LIMITS FOR GIVEN SPEED
!
! ENTRIES ARE SET FOR THE STANDARD SPEED ENTRIES:
!
! NUM BAUD NUM BAUD NUM BAUD
! 0 50. 1 75. 2 110.
! 3 134.5 4 150. 5 300.
! 6 600. 7 1200. 10 1800.
! 11 2000. 12 2400. 13 3600.
! 14 4800. 15 7200. 16 9600.
! 17 EXT
!-
macro
HIPOL (index) =
ch$rchar (ch$ptr (HIPOL_STRING, index)) %,
LOPOL (index) =
ch$rchar (ch$ptr (LOPOL_STRING, index)) %;
bind
HIPOL_STRING = uplit (%char (
4, 4, 4,
4, 4, 4,
4, 4, 4,
4, 4, 3,
2, 1, 1,
0)),
LOPOL_STRING = uplit (%char (
12, 12, 12,
12, 12, 12,
12, 12, 12,
12, 12, 8,
6, 5, 3,
0));
!
! OWN STORAGE:
!
external routine
$DSPCR : novalue,
$RDBRT : novalue;
$MCB_PROCESS (
NAME = KDP, ! Process name
DDM_DISPATCH = TABLE$ ($DSPCR, FC_CCP, ! DDM dispatch vector:
(FC_XME, KDPXME), ! Transmit enable
(FC_RCE, $RDBRT), ! Receive enable
(FC_KIL, KDPKIL), ! Kill enable
(FC_CTL, KDPCTL), ! Control enable
(FC_TIM, KDPTIM))) ! Timeout
!
! EXTERNAL REFERENCES:
!
external routine
REGISTER_NXM : KDP_CSR_NUM,
KDPNMI : novalue;
external
MCB$GAW_PROCESS_DATA_BASE : vector [2],
MCB$GW_PROCESS_HANDLE,
MCB$GW_RDB_SIZE; ! Size of RDB buffer.
bind
DB_BIAS = MCB$GAW_PROCESS_DATA_BASE [0];
macro
GET_DUP_DATA_BASE (NAME) =
%if %declared (NAME)
%then map NAME : ref DUP_DATA_BASE
%else bind NAME = .MCB$GAW_PROCESS_DATA_BASE [1] : DUP_DATA_BASE
%fi %;
routine ASSIGN_RECEIVE_BUFFER (CCB) : LINKAGE_CCB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = available RDB.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS);
GET_DUP_DATA_BASE (DB);
DB [D_ASSIGNABLE_RECEIVE_COUNT] = .DB [D_ASSIGNABLE_RECEIVE_COUNT] - 1;
DB [D_ASSIGNED_RECEIVE_COUNT] = .DB [D_ASSIGNED_RECEIVE_COUNT] + 1;
CCB [C_CNT] = .MCB$GW_RDB_SIZE;
CCB [C_STS] = CIRBA;
GIVE_TO_KMC (.CCB);
end; !of routine ASSIGN_RECEIVE_BUFFER
routine ASSIGN_TRANSMIT_BUFFER : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! None
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
local
CCB : ref block field (C_FIELDS);
GET_DUP_DATA_BASE (DB);
if .DB [D_ASSIGNABLE_TRANSMIT_COUNT] neq 0
then
if $MCB_DEQUEUE_CCB (DB [D_ASSIGNABLE_TRANSMIT_CCBS], CCB)
then
begin
DB [D_ASSIGNABLE_TRANSMIT_COUNT] = .DB [D_ASSIGNABLE_TRANSMIT_COUNT] - 1;
DB [D_ASSIGNED_TRANSMIT_COUNT] = .DB [D_ASSIGNED_TRANSMIT_COUNT] + 1;
CCB [C_STS] = CITBA;
GIVE_TO_KMC (.CCB);
end;
end; !of routine ASSIGN_TRANSMIT_BUFFER
routine CIBAS (CCB, PORT) : CALL$ =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! PORT = address of KMC data port buffer.
! CCB = address of request CCB.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS),
PORT : ref vector [2];
local
EDB : ref block field (E_FIELDS),
SAVE_MAP;
GET_DUP_DATA_BASE (DB);
SMAP$ (SAVE_MAP);
MAP$ (.DB_BIAS);
EDB = .DB [D_EXT_ADDR];
PORT [0] = 0;
PORT [1] = .EDB [E_REGISTER] and %o'017770';
DB [DF_DUP_CSR_SET] = TRUE;
COMPLETE (DB [D_TIM], .CCB);
MAP$ (.SAVE_MAP);
BAS
end; !of routine CIBAS
routine CICTL (CCB, PORT) : CALL$ =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! PORT = address of KMC data port buffer.
! CCB = address of request CCB.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS),
PORT : ref vector [2];
local
SAVE_MAP;
SMAP$ (SAVE_MAP);
begin
local
EDB : ref block field (E_FIELDS);
GET_DUP_DATA_BASE (DB);
MAP$ (.DB_BIAS);
EDB = .DB [D_EXT_ADDR];
PORT [0] = .EDB [E_POLLING_RATE];
PORT [1] = .EDB [E_CTL];
DB [DF_ENABLED] = .EDB [$SUB_FIELD (E_CTL, CT_ENB)];
COMPLETE (DB [D_TIM], .CCB);
end;
MAP$ (.SAVE_MAP);
CTL
end; !of routine CICTL
routine CIRBA (CCB, PORT) : CALL$ =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = address of request CCB.
! PORT = address of KMC data port buffer.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS),
PORT : ref vector [2];
local
DESC : ref vector,
EDB : ref block field (E_FIELDS),
SAVE_MAP;
GET_DUP_DATA_BASE (DB);
SMAP$ (SAVE_MAP);
MAP$ (.DB_BIAS);
EDB = .DB [D_EXT_ADDR];
DESC = .EDB [E_NEXT_RECEIVE_DESCRIPTOR];
EDB [E_NEXT_RECEIVE_DESCRIPTOR] = .DESC [0];
PORT [0] = .DESC [1];
PORT [1] = .DESC [2];
DESC = DESC [3];
CCB [C_STS] = SET_DESCRIPTOR (.CCB, .DESC);
EDB = EDB [E_ASSIGNED_RECEIVE_CCBS];
$MCB_QUEUE_CCB (.EDB, .CCB);
MAP$ (.SAVE_MAP);
RBA
end; !of routine CIRBA
routine CIRBK (CCB, PORT) : CALL$ =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! PORT = address of KMC data port buffer.
! CCB = address of request CCB.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS),
PORT : ref vector [2];
local
SAVE_MAP;
GET_DUP_DATA_BASE (DB);
SMAP$ (SAVE_MAP);
MAP$ (.DB_BIAS);
PORT [0] = 0;
PORT [1] = BIT_MASK [BA_KIL];
$MCB_QUEUE_CCB (DB [D_PENDING_CONTROL_CCBS], .CCB);
if not .DB [DF_DUP_CSR_SET] then RECEIVE_KILLED ();
MAP$ (.SAVE_MAP);
RBA
end; !of routine CIRBK
routine CITBA (CCB, PORT) : CALL$ =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = address of request CCB.
! PORT = address of KMC data port buffer.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS),
PORT : ref vector [2];
local
DESC : ref vector,
EDB : ref block field (E_FIELDS),
SAVE_MAP;
GET_DUP_DATA_BASE (DB);
SMAP$ (SAVE_MAP);
MAP$ (.DB_BIAS);
EDB = .DB [D_EXT_ADDR];
DESC = .EDB [E_NEXT_TRANSMIT_DESCRIPTOR];
EDB [E_NEXT_TRANSMIT_DESCRIPTOR] = .DESC [0];
PORT [0] = .DESC [1];
PORT [1] = .DESC [2];
DESC = DESC [3];
CCB [C_STS] = SET_DESCRIPTOR (.CCB, .DESC);
$MCB_QUEUE_CCB (EDB [E_ASSIGNED_TRANSMIT_CCBS], .CCB);
block [DESC [0], BD_SOM] = 1;
block [.CCB [C_STS], BD_EOM] = 1;
if .EDB [$SUB_FIELD (E_CTL, CT_DEC)]
then
begin
if .block [DESC [0], BD_LBD] eql 0
then
begin
block [DESC [0], BD_EOM] = 1;
block [DESC [3], BD_SOM] = 1;
end;
end;
if .CCB [C_MOD] eql FM_SYN
then
block [DESC [0], BD_SYN] = 1;
DB [D_TIM] = .DB [D_TRANSMIT_TIMEOUT];
ASSIGN_TRANSMIT_BUFFER ();
MAP$ (.SAVE_MAP);
TBA
end; !of routine CITBA
routine CITBK (CCB, PORT) : CALL$ =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! PORT = address of KMC data port buffer.
! CCB = address of request CCB.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS),
PORT : ref vector [2];
local
SAVE_MAP;
GET_DUP_DATA_BASE (DB);
SMAP$ (SAVE_MAP);
MAP$ (.DB_BIAS);
PORT [0] = 0;
PORT [1] = BIT_MASK [BA_KIL];
$MCB_QUEUE_CCB (DB [D_PENDING_CONTROL_CCBS], .CCB);
if not .DB [DF_DUP_CSR_SET] then TRANSMIT_KILLED ();
MAP$ (.SAVE_MAP);
TBA
end; !of routine CITBK
global routine COBAD (REG) : CALL$ novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! REG = address of KMC register buffer.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
REG : ref block field (KDP_FIELDS);
local
SAVE_MAP;
SMAP$ (SAVE_MAP);
MAP$ (.DB_BIAS);
begin
GET_DUP_DATA_BASE (DB);
bind
EDB = .DB [D_EXT_ADDR] : block field (E_FIELDS);
DB [DF_DUP_CSR_SET] = FALSE;
DB [DF_ENABLED] = FALSE;
DB [D_ASSIGNABLE_RECEIVE_COUNT] = 0;
DB [D_ASSIGNABLE_TRANSMIT_COUNT] = 0;
$NM_PLL_EVENT (4, .EDB [E_ENTITY], %(Communications Interface Error)%
PARAMETER_DEVICE_REGISTERS (.REG));
end;
MAP$ (.SAVE_MAP);
end; !of routine COBAD
global routine COCTL (REG) : CALL$ novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! REG = address of KMC register buffer.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
REG : ref block field (KDP_FIELDS);
macro
$return =
begin
MAP$ (.SAVE_MAP);
return
end %;
local
SAVE_MAP;
GET_DUP_DATA_BASE (DB);
SMAP$ (SAVE_MAP);
MAP$ (.DB_BIAS);
DB [D_TIM] = 0;
case .REG [$SUB_FIELD (SEL6, 0, 0, 8, 1)] from 6 to 22 of
set
[6] : ! Abort
begin
local
CCB : ref block field (C_FIELDS);
if not RECEIVE_CCB (DB [D_TIM], 0; CCB) then $return;
$MCB_RETURN_RDB (.CCB);
end;
[8] : ! Receive DDCMP Header CRC Error
begin
RECEIVE_DONE (BDADR (.REG [$SUB_FIELD (SEL4, BA_LOW)], .REG [$SUB_FIELD (SEL6, BA_HIGH)]), CE_HFE);
end;
[10] : ! Receive Data CRC Error
begin
RECEIVE_DONE (BDADR (.REG [$SUB_FIELD (SEL4, BA_LOW)], .REG [$SUB_FIELD (SEL6, BA_HIGH)]), CE_DCR);
end;
[12] : ! No Buffer Assigned
begin
COUNTER_INCREMENT (DB, D_NO_BUFFER_ASSIGNED);
COUNTER_INCREMENT (DB, D_PERFORMANCE_ERRORS);
end;
[14] : ! Data Set Ready (DSR) Transition
begin
literal
OFF = 0,
ON = 1;
bind
EDB = .DB [D_EXT_ADDR] : block field (E_FIELDS);
local
STATE;
DB [DF_DSR] = not .DB [DF_DSR];
STATE = (if .DB [DF_DSR] then ON else OFF);
$NM_PLL_EVENT (0, .EDB [E_ENTITY],
PARAMETER_C_1 (1, STATE));
end;
[16] : ! Nonexsistent Memory
begin
COUNTER_INCREMENT (DB, D_NONEXISTENT_MEMORY);
COUNTER_INCREMENT (DB, D_DEVICE_ERRORS);
DEVICE_BROKEN (DB [D_TIM]);
end;
[18] : ! Transmit Underrun
begin
bind
EDB = .DB [D_EXT_ADDR] : block field (E_FIELDS);
local
DESC : ref block field (BD_FIELDS);
DESC = BDADR (.REG [$SUB_FIELD (SEL4, BA_LOW)], .REG [$SUB_FIELD (SEL6, BA_HIGH)]);
DB [DF_TRANSMIT_UNDERRUN] = TRUE;
if .DESC [BD_LBD] then TRANSMIT_DONE (.DESC, CE_UDR);
POLLING_FAILURE ();
$NM_PLL_EVENT (5, .EDB [E_ENTITY],
PARAMETER_DEVICE_REGISTERS (.REG));
end;
[20] : ! Receiver Overrun
begin
bind
EDB = .DB [D_EXT_ADDR] : block field (E_FIELDS);
POLLING_FAILURE ();
RECEIVE_DONE (BDADR (.REG [$SUB_FIELD (SEL4, BA_LOW)], .REG [$SUB_FIELD (SEL6, BA_HIGH)]), CE_ROV);
$NM_PLL_EVENT (5, .EDB [E_ENTITY],
PARAMETER_DEVICE_REGISTERS (.REG));
end;
[22] : ! Kill Complete
if .REG [$SUB_FIELD (SEL2, IN_I_O)]
then
RECEIVE_KILLED ()
else
TRANSMIT_KILLED ();
[inrange, outrange] :
begin
COUNTER_INCREMENT (DB, D_INVALID_ERROR_CODE);
COUNTER_INCREMENT (DB, D_DEVICE_ERRORS);
DEVICE_BROKEN (DB [D_TIM]);
end;
tes;
GET_RECEIVE_BUFFERS ();
MAP$ (.SAVE_MAP);
end; !of routine COCTL
routine COMPLETE (DB, CCB) : LINKAGE_DB_CCB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! DB = DUP data base
! CCB = CCB to complete
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS);
GET_DUP_DATA_BASE (DB);
selectone .CCB [C_FNC] of
set
[FC_AST] :
$MCB_RETURN_CCB (.CCB);
[FC_CTL] :
begin
CCB [C_PIX] = .MCB$GW_PROCESS_HANDLE;
$MCB_SCHEDULE_CCB (.CCB);
end;
[otherwise] :
begin
CCB [C_LIX] = .DB [D_LIX];
DDKCP$ (.CCB, CS_SUC)
end;
tes
end; !of routine COMPLETE
global routine CORBA (REG) : CALL$ novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! REG = address of KMC register buffer.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
REG : ref block field (KDP_FIELDS);
macro
$return =
begin
MAP$ (.SAVE_MAP);
return
end %;
local
SAVE_MAP;
GET_DUP_DATA_BASE (DB);
SMAP$ (SAVE_MAP);
MAP$ (.DB_BIAS);
if not .REG [$SUB_FIELD (SEL6, BA_EOM)]
then
begin
if not .DB [DF_TRUNCATING_RECEIVE]
then
begin
DB [DF_TRUNCATING_RECEIVE] = TRUE;
RECEIVE_DONE (BDADR (.REG [$SUB_FIELD (SEL4, BA_LOW)], .REG [$SUB_FIELD (SEL6, BA_HIGH)]), CE_MTL);
end
else
begin
local
CCB : ref block field (C_FIELDS);
if not RECEIVE_CCB (DB [D_TIM], 0; CCB) then $return;
$MCB_RETURN_RDB (.CCB);
end;
end
else
begin
if POLLING_THRESHOLD gtr .DB [D_POLLING_THRESHOLD]
then
DB [D_POLLING_THRESHOLD] = .DB [D_POLLING_THRESHOLD] + 1;
if not .DB [DF_TRUNCATING_RECEIVE]
then
RECEIVE_DONE (BDADR (.REG [$SUB_FIELD (SEL4, BA_LOW)], .REG [$SUB_FIELD (SEL6, BA_HIGH)]), CS_SUC)
else
begin
local
CCB : ref block field (C_FIELDS);
DB [DF_TRUNCATING_RECEIVE] = FALSE;
if not RECEIVE_CCB (DB [D_TIM], 0; CCB) then $return;
$MCB_RETURN_RDB (.CCB);
end;
end;
GET_RECEIVE_BUFFERS ();
MAP$ (.SAVE_MAP);
end; !of routine CORBA
global routine COTBA (REG) : CALL$ novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! REG = address of KMC register buffer.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
REG : ref block field (KDP_FIELDS);
macro
$return =
begin
MAP$ (.SAVE_MAP);
return
end %;
local
CCB : ref block field (C_FIELDS),
DESC : ref block field (BD_FIELDS),
SAVE_MAP;
GET_DUP_DATA_BASE (DB);
SMAP$ (SAVE_MAP);
MAP$ (.DB_BIAS);
DESC = BDADR (.REG [$SUB_FIELD (SEL4, BA_LOW)], .REG [$SUB_FIELD (SEL6, BA_HIGH)]);
if not .DESC [BD_LBD] then $return;
if not .DB [DF_TRANSMIT_UNDERRUN]
then
begin
if POLLING_THRESHOLD gtr .DB [D_POLLING_THRESHOLD]
then
DB [D_POLLING_THRESHOLD] = .DB [D_POLLING_THRESHOLD] + 1;
TRANSMIT_DONE (.DESC, CS_SUC);
end
else
begin
DB [DF_TRANSMIT_UNDERRUN] = FALSE;
TRANSMIT_DONE (.DESC, CE_UDR);
end;
MAP$ (.SAVE_MAP);
end; !of routine COTBA
routine CTLGET (DB, CCB) : MCB_DB_CCB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = address of CCB.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
GET_DUP_DATA_BASE (DB);
map
CCB : ref block field (C_FIELDS);
bind
EDB = .DB [D_EXT_ADDR] : block field (E_FIELDS);
CALL$P (KMCPRM, .DB [D_KMC_PIX], .CCB);
CCB [C_PRM2] = .EDB [E_REGISTER];
CCB [$SUB_FIELD (C_PRM5, 0, 0, 8, 1)] = .EDB [ES_XMT];
CCB [$SUB_FIELD (C_PRM5, 0, 8, 8, 1)] = .EDB [ES_RCV];
DDCCP$ (.CCB, CS_SUC);
end; !of routine CTLGET
routine CTLSET (DB, CCB) : MCB_DB_CCB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = address of CCB.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
GET_DUP_DATA_BASE (DB);
map
CCB : ref block field (C_FIELDS);
DB [DF_HALF_DUPLEX] = .CCB [C_PRM2];
DB [DF_CONTROLLER_LOOPBACK] = .CCB [C_PRM3];
DB [DF_INTERNAL_CLOCK] = .CCB [C_PRM4];
DDCCP$ (.CCB, CS_SUC);
end; !of routine CTLSET
routine CTLSTP (DB, CCB) : MCB_DB_CCB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = address of CCB.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS);
local
EDB : ref block field (E_FIELDS);
GET_DUP_DATA_BASE (DB);
if not .DB [DF_LINE_ACTIVE] then return DDCCP$ (.CCB, CS_SUC);
DB [DF_STOPPING_LINE] = TRUE;
EDB = .DB [D_EXT_ADDR];
if .DB [DF_ENABLED]
then
begin
EDB [E_CTL] = 0;
CCB [C_STS] = CICTL;
GIVE_TO_KMC (.CCB);
return;
end;
if .vector [DB [D_PENDING_CONTROL_CCBS], 0] neqa 0
then
begin
$MCB_QUEUE_CCB (DB [D_PENDING_CONTROL_CCBS], .CCB);
return;
end;
DB [D_ASSIGNABLE_RECEIVE_COUNT] = 0;
DB [D_ASSIGNABLE_TRANSMIT_COUNT] = 0;
$MCB_CANCEL_RDB_REQUEST ();
if .DB [D_ASSIGNED_RECEIVE_COUNT] neq 0
then
begin
DB [DF_KILLING_RECEIVES] = TRUE;
CCB [C_STS] = CIRBK;
GIVE_TO_KMC (.CCB);
return;
end;
if .DB [D_ASSIGNED_TRANSMIT_COUNT] neq 0
then
begin
DB [DF_KILLING_TRANSMITS] = TRUE;
CCB [C_STS] = CITBK;
GIVE_TO_KMC (.CCB);
return;
end;
$MCB_DISABLE_LONG_TIMER ();
CALL$P (KMCSTP, .DB [D_KMC_PIX], .DB [D_UNIT]);
DB [DF_DUP_CSR_SET] = FALSE;
DB [DF_STOPPING_LINE] = FALSE;
DB [DF_LINE_ACTIVE] = FALSE;
CCB [C_LIX] = .DB [D_LIX];
DDCCP$ (.CCB, CS_SUC);
end; !of routine CTLSTP
routine CTLSTR (DB, CCB) : MCB_DB_CCB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = address of CCB.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS);
GET_DUP_DATA_BASE (DB);
if .DB [DF_LINE_ACTIVE] then return DDCCP$ (.CCB, CS_SUC);
if not .DB [DF_STARTING_LINE]
then
begin
local
EDB : ref block field (E_FIELDS);
EDB = .DB [D_EXT_ADDR];
if .EDB [E_REGISTER] lssa %o'160000' then return DDCCP$ (.CCB, CE_ABO);
if REGISTER_NXM (.EDB [E_REGISTER], 4) then return DDCCP$ (.CCB, CE_ABO);
if not CALL$P (KMCSTR, .DB [D_KMC_PIX], .DB [D_UNIT], .MCB$GW_PROCESS_HANDLE)
then
return DDCCP$ (.CCB, CE_ABO);
DB [D_LIX] = .CCB [C_LIX];
$MCB_ENABLE_LONG_TIMER ();
DB [DF_STARTING_LINE] = TRUE;
end;
if not .DB [DF_DUP_CSR_SET]
then
begin
CCB [C_STS] = CIBAS;
GIVE_TO_KMC (.CCB);
return;
end;
if not .DB [DF_ENABLED]
then
begin
INITIALIZE_CHARACTERISTICS ();
DB [DF_DSR] = FALSE;
CCB [C_STS] = CICTL;
GIVE_TO_KMC (.CCB);
return;
end;
DB [D_ASSIGNABLE_TRANSMIT_COUNT] = 2;
DB [D_ASSIGNABLE_RECEIVE_COUNT] = 2;
GET_RECEIVE_BUFFERS ();
DB [DF_STARTING_LINE] = FALSE;
DB [DF_LINE_ACTIVE] = TRUE;
CCB [C_LIX] = .DB [D_LIX];
DDCCP$ (.CCB, CS_SUC);
end; !of routine CTLSTR
routine DEVICE_BROKEN (DB) : LINKAGE_DB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! None
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
GET_DUP_DATA_BASE (DB);
DB [DF_ENABLED] = FALSE;
DB [DF_DUP_CSR_SET] = FALSE;
end; !of routine DEVICE_BROKEN
routine GET_RECEIVE_BUFFERS : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! None
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
GET_DUP_DATA_BASE (DB);
while .DB [D_ASSIGNABLE_RECEIVE_COUNT] neq 0 do
begin
local
CCB : ref block field (C_FIELDS);
if $MCB_GET_RDB (CCB)
then
begin
CCB [C_FNC] = 0;
ASSIGN_RECEIVE_BUFFER (.CCB);
end
else
begin
$MCB_REQUEST_RDB ();
exitloop;
end;
end;
end; !of routine GET_RECEIVE_BUFFERS
routine GIVE_TO_KMC (CCB) : KDP_CCB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = address of service CCB.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS);
GET_DUP_DATA_BASE (DB);
CCB [C_LIX] = .DB [D_UNIT];
CCB [C_PIX] = .MCB$GW_PROCESS_HANDLE;
CALL$P (KMCQUE, .DB [D_KMC_PIX], .CCB);
end; !of routine GIVE_TO_KMC
routine INITIALIZE_CHARACTERISTICS : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! None
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
local
EDB : ref block field (E_FIELDS);
GET_DUP_DATA_BASE (DB);
EDB = .DB [D_EXT_ADDR];
EDB [E_CTL] = BIT_MASK [CT_ENB];
if .EDB [ES_PRT] eql EP_DEC
then
EDB [$SUB_FIELD (E_CTL, CT_DEC)] = 1;
if .DB [DF_HALF_DUPLEX]
then
EDB [$SUB_FIELD (E_CTL, CT_DUP)] = 1;
if .DB [DF_INTERNAL_CLOCK]
then
begin
if .DB [DF_CONTROLLER_LOOPBACK]
then
EDB [$SUB_FIELD (E_CTL, CT_MNT)] = 1
else
EDB [$SUB_FIELD (E_CTL, CT_MNT)] = 2;
end;
EDB [E_POLLING_RATE] = LOPOL [.EDB [ES_XMT]];
DB [D_POLLING_THRESHOLD] = POLLING_THRESHOLD;
end; !of routine INITIALIZE_CHARACTERISTICS
routine INITIALIZE_DESCRIPTOR_LIST (RING, POOL, COUNT) : LINKAGE_RING_POOL_COUNT novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! RING = address of ring to link descriptor list into.
! POOL = address vector of memory available for descriptors.
! COUNT = number of descriptors to put in list.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! RING = constructed descriptor list added to this ring.
! POOL = advanced over allocated descriptors.
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
local
DESC : ref vector;
GET_DUP_DATA_BASE (DB);
DESC = ..POOL;
begin
local
BIAS;
$MCB_CONVERT_TO_UBA_ADDRESS ((.DB [D_EXT_BIAS], DESC [3]), DESC [1], BIAS);
DESC [2] = BIAS = .BIAS^14;
end;
if ..RING neq 0
then
begin
DESC [0] = ...RING;
..RING = DESC [0];
end
else
.RING = DESC [0] = DESC [0];
.POOL = DESC [3 + .COUNT*BD_LEN];
end; !of routine INITIALIZE_DESCRIPTOR_LIST
routine KDPCTL (DB, CCB, MODIFIER) : MCB_DB_CCB_MOD novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = address of CTL CCB.
! MODIFIER = control function modifier (from C_MOD of CCB).
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
external routine
$CCBRT;
DISPATCH$ (.MODIFIER,
TABLE$ ($DSPCR, FD_CTL, ! Control dispatch table:
(FM_STR, CTLSTR), ! Start line
(FM_STP, CTLSTP), ! Stop line
(FM_SET, CTLSET), ! Set characteristics
(FM_GET, CTLGET)), ! Get characteristics
(.DB, .CCB),
MCB_DB_CCB);
end; !of routine KDPCTL
routine KDPKIL (DB, CCB, MODIFIER) : MCB_DB_CCB_MOD novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = address of CTL CCB.
! MODIFIER = control function modifier (from C_MOD of CCB).
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
DISPATCH$ (
.MODIFIER,
TABLE$ ($DSPCR, FD_KIL, ! Kill dispatch table:
(FM_KIL, KILKIL), ! Transmit and receive kill
(FM_CRA, KILCRA), ! Receive kill
(FM_XKL, KILXKL)), ! Transmit kill
(.DB, .CCB),
MCB_DB_CCB);
end; !of routine KDPKIL
routine KDPTIM (DB, MODIFIER) : MCB_DB_MOD novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! MODIFIER = timer function modifier.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
DISPATCH$ (
.MODIFIER,
TABLE$ ($DSPCR, FD_TIM, ! Timer dispatch table:
(FM_LTM, TIMLTM), ! Long timer
(FM_RDB, TIMRDB), ! RDB available
(FM_PWF, TIMPWF), ! Power failure
(FM_PIN, TIMPIN)), ! Process initialization
(.DB),
MCB_DB);
end; !of routine KDPTIM
routine KDPXME (DB, CCB, MODIFIER) : MCB_DB_CCB_MOD novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = address of transmit CCB.
! MODIFIER = transmit function modifier (from C_MOD of CCB).
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS);
GET_DUP_DATA_BASE (DB);
if .DB [DF_LINE_ACTIVE]
then
begin
local
SEG_CNT;
$MCB_QUEUE_CCB (DB [D_ASSIGNABLE_TRANSMIT_CCBS], .CCB);
SEG_CNT = .DB [D_MAXIMUM_TRANSMIT_SEGMENTS];
do
begin
if (SEG_CNT = .SEG_CNT - 1) lss 0
then
return SIGNAL_STOP (KDP$_SEG, .DB [$SUB_FIELD (D_ASSIGNABLE_TRANSMIT_CCBS, LIST_LAST)]);
end
while (CCB = .CCB [C_CHN]) neq 0;
ASSIGN_TRANSMIT_BUFFER ();
end
else
begin
CCB [C_LIX] = .DB [D_LIX];
DDXCP$ (.CCB, CE_ABO);
end;
end; !of routine KDPXME
routine KILCRA (DB, CCB) : MCB_DB_CCB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = address of kill CCB.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS);
local
EDB : ref block field (E_FIELDS);
GET_DUP_DATA_BASE (DB);
EDB = .DB [D_EXT_ADDR];
if .DB [D_ASSIGNED_RECEIVE_COUNT] neq 0
then
begin
DB [DF_KILLING_RECEIVES] = TRUE;
DB [D_ASSIGNABLE_RECEIVE_COUNT] = 0;
CCB [C_STS] = CIRBK;
GIVE_TO_KMC (.CCB);
end
else
COMPLETE (DB [D_TIM], .CCB);
end; !of routine KILCRA
routine KILKIL (DB, CCB) : MCB_DB_CCB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = address of kill CCB.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS);
local
EDB : ref block field (E_FIELDS);
GET_DUP_DATA_BASE (DB);
EDB = .DB [D_EXT_ADDR];
if .DB [D_ASSIGNED_RECEIVE_COUNT] eql 0
then
return KILXKL (DB [D_TIM], .CCB);
DB [DF_KILLING_RECEIVES] = TRUE;
DB [D_ASSIGNABLE_RECEIVE_COUNT] = 0;
if .DB [D_ASSIGNED_TRANSMIT_COUNT] neq 0
then
begin
DB [DF_KILLING_TRANSMITS] = TRUE;
DB [D_ASSIGNABLE_TRANSMIT_COUNT] = 0;
end;
CCB [C_STS] = CIRBK;
GIVE_TO_KMC (.CCB);
end; !of routine KILKIL
routine KILXKL (DB, CCB) : MCB_DB_CCB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = address of kill CCB.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS);
local
EDB : ref block field (E_FIELDS);
GET_DUP_DATA_BASE (DB);
EDB = .DB [D_EXT_ADDR];
if .DB [D_ASSIGNED_TRANSMIT_COUNT] neq 0
then
begin
DB [DF_KILLING_TRANSMITS] = TRUE;
DB [D_ASSIGNABLE_TRANSMIT_COUNT] = 0;
CCB [C_STS] = CITBK;
GIVE_TO_KMC (.CCB);
end
else
COMPLETE (DB [D_TIM], .CCB);
end; !of routine KILXKL
global routine PARAMETER_DEVICE_REGISTERS
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
(REG : ref vector)
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
: KDP_REG novalue =
!
! SIDE EFFECTS:
! None
!--
begin
decr COUNT from 4 to 1 do
begin
PARAMETER_H_2 (0, REG [0]);
REG = REG [1];
end;
end; !of routine PARAMETER_DEVICE_REGISTERS
routine POLLING_FAILURE : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! None
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
local
CCB : ref block field (C_FIELDS),
EDB : ref block field (E_FIELDS);
GET_DUP_DATA_BASE (DB);
DB [D_POLLING_THRESHOLD] = .DB [D_POLLING_THRESHOLD] - 1;
if .DB [D_POLLING_THRESHOLD] neq 0 then return;
EDB = .DB [D_EXT_ADDR];
if .EDB [E_POLLING_RATE] eqlu HIPOL [.EDB [ES_XMT]]
then
if $MCB_GET_CCB (CCB)
then
begin
COUNTER_INCREMENT (DB, D_POLLING_ADJUSTMENT);
COUNTER_INCREMENT (DB, D_PERFORMANCE_ERRORS);
EDB [E_POLLING_RATE] = .EDB [E_POLLING_RATE] - 1;
DB [D_POLLING_THRESHOLD] = POLLING_THRESHOLD;
CCB [C_FNC] = FC_AST;
CCB [C_STS] = CICTL;
GIVE_TO_KMC (.CCB);
end
else
DB [D_POLLING_THRESHOLD] = .DB [D_POLLING_THRESHOLD] + 1;
end; !of routine POLLING_FAILURE
routine RECEIVE_CCB (DB, DESC; CCB) : KDP_LKG_DB_DESC_CCB =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! DESC = terminated descriptor.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS),
DESC : ref block field (BD_FIELDS);
local
QUE;
GET_DUP_DATA_BASE (DB);
QUE = block [.DB [D_EXT_ADDR], E_ASSIGNED_RECEIVE_CCBS];
if not $MCB_DEQUEUE_CCB (.QUE, CCB)
then
begin
COUNTER_INCREMENT (DB, D_RECEIVE_BA_ERROR);
COUNTER_INCREMENT (DB, D_DEVICE_ERRORS);
DEVICE_BROKEN (DB [D_TIM]);
return FALSE;
end;
if .DESC neq 0
then
if .CCB [C_STS] neq .DESC
then
begin
$MCB_STACK_CCB (.QUE, .CCB);
COUNTER_INCREMENT (DB, D_RECEIVE_BA_ERROR);
COUNTER_INCREMENT (DB, D_DEVICE_ERRORS);
DEVICE_BROKEN (DB [D_TIM]);
return FALSE;
end;
DB [D_ASSIGNED_RECEIVE_COUNT] = .DB [D_ASSIGNED_RECEIVE_COUNT] - 1;
if not .DB [DF_KILLING_RECEIVES]
then
DB [D_ASSIGNABLE_RECEIVE_COUNT] = .DB [D_ASSIGNABLE_RECEIVE_COUNT] + 1;
CCB [C_CNT] = .DESC [BD_CC];
TRUE
end; !of routine RECEIVE_CCB
routine RECEIVE_DONE (DESC, STS) : LINKAGE_DESC_STS novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! DESC = terminated descriptor.
! STS = return status code for receive CCB.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
DESC : ref block field (BD_FIELDS);
local
CCB : ref block field (C_FIELDS);
GET_DUP_DATA_BASE (DB);
if not RECEIVE_CCB (DB [D_TIM], .DESC; CCB) then return;
CCB [C_LIX] = .DB [D_LIX];
CCB [C_FNC] = FC_RCE;
CCB [C_MOD] = 0;
DDRCP$ (.CCB, .STS);
end; !of routine RECEIVE_DONE
routine RECEIVE_KILLED : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! None
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
GET_DUP_DATA_BASE (DB);
DB [DF_KILLING_RECEIVES] = FALSE;
DB [DF_TRUNCATING_RECEIVE] = FALSE;
DB [D_ASSIGNED_RECEIVE_COUNT] = 0;
if .DB [DF_ENABLED]
then
DB [D_ASSIGNABLE_RECEIVE_COUNT] = 2;
while TRUE do
begin
local
CCB : ref block field (C_FIELDS);
if not $MCB_DEQUEUE_CCB (block [.DB [D_EXT_ADDR], E_ASSIGNED_RECEIVE_CCBS], CCB) then exitloop;
$MCB_RETURN_RDB (.CCB);
end;
GET_RECEIVE_BUFFERS ();
begin
local
CCB : ref block field (C_FIELDS);
if $MCB_DEQUEUE_CCB (DB [D_PENDING_CONTROL_CCBS], CCB)
then
if .DB [DF_KILLING_TRANSMITS]
then
begin
CCB [C_STS] = CITBK;
GIVE_TO_KMC (.CCB);
end
else
do
COMPLETE (DB [D_TIM], .CCB)
while $MCB_DEQUEUE_CCB (DB [D_PENDING_CONTROL_CCBS], CCB);
end;
end; !of routine RECEIVE_KILLED
routine SET_DESCRIPTOR (CCB, DESC) : LINKAGE_CCB_DESC =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = address of CCB chain.
! DESC = address of buffer descriptor list.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! Address of last buffer descriptor used.
!
! SIDE EFFECTS:
! None
!--
begin
local
NEXT_CCB : ref block field (C_FIELDS),
NEXT_DESC : ref block field (BD_FIELDS);
NEXT_CCB = .CCB;
NEXT_DESC = .DESC;
do
begin
local
HIGH;
$MCB_CONVERT_TO_UBA_ADDRESS ((.NEXT_CCB [C_BIAS], .NEXT_CCB [C_ADDR]),
NEXT_DESC [BD_LOW], HIGH);
NEXT_DESC [BD_CC] = .NEXT_CCB [C_CNT];
NEXT_DESC [%fieldexpand (BD_HIGH, 0), 0, %bpval, 0] = .HIGH^%fieldexpand (BD_HIGH, 1);
NEXT_DESC = NEXT_DESC [BD_LEN, 0, %bpval, 1];
end
while (NEXT_CCB = .NEXT_CCB [C_CHN]) neq 0;
NEXT_DESC = NEXT_DESC [-BD_LEN, 0, %bpval, 1];
NEXT_DESC [BD_LBD] = 1;
.NEXT_DESC
end; !of routine SET_DESCRIPTOR
routine TIMLTM (DB) : MCB_DB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! None
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
local
EDB : ref block field (E_FIELDS);
GET_DUP_DATA_BASE (DB);
EDB = .DB [D_EXT_ADDR];
if .EDB [$SUB_FIELD (E_ASSIGNED_TRANSMIT_CCBS, LIST_FIRST)] neq 0 and
not .DB [DF_KILLING_TRANSMITS]
then
begin
local
CCB : ref block field (C_FIELDS);
if not $MCB_GET_CCB (CCB) then return DB [D_TIM] = .DB [D_TIM] + 1;
CCB [C_FNC] = FC_AST;
KILXKL (DB [D_TIM], .CCB);
end;
end; !of routine TIMLTM
routine TIMPIN (DB) : MCB_DB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! None
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
local
DESC : ref vector,
EDB : ref block field (E_FIELDS);
GET_DUP_DATA_BASE (DB);
MAP$ (DB_BIAS = .DB [D_EXT_BIAS]);
EDB = .DB [D_EXT_ADDR];
DB [DF_HALF_DUPLEX] = .EDB [EF_HDX];
DESC = EDB [E_DESCRIPTORS];
decr CNT from 2 to 1 do
INITIALIZE_DESCRIPTOR_LIST (EDB [E_NEXT_TRANSMIT_DESCRIPTOR], DESC, .DB [D_MAXIMUM_TRANSMIT_SEGMENTS]);
decr CNT from 2 to 1 do
INITIALIZE_DESCRIPTOR_LIST (EDB [E_NEXT_RECEIVE_DESCRIPTOR], DESC, 1);
if .DB [D_UNIT] eql 0
then
begin
local
KMC_PIX;
if $MCB_SET_PROCESS (, KMC_PIX)
then
begin
DB [D_KMC_PIX] = .KMC_PIX;
CALL$P (KMCDB, .KMC_PIX, .DB_BIAS, vector [DB [D_TIM], -K_LEN]);
end;
end
else
begin
bind
DB0 = vector [DB [D_TIM], .DB [D_UNIT]*-D_LEN] : block field (D_FIELDS);
DB [D_KMC_PIX] = .DB0 [D_KMC_PIX];
end;
KDPNMI ();
end; !of routine TIMPIN
routine TIMPWF (DB) : MCB_DB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
NO_OPERATION
end; !of routine TIMPWF
routine TIMRDB (DB, CCB) : MCB_DB_CCB novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! CCB = available RDB.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS);
GET_DUP_DATA_BASE (DB);
if .DB [D_ASSIGNABLE_RECEIVE_COUNT] neq 0
then
ASSIGN_RECEIVE_BUFFER (.CCB)
else
$MCB_RETURN_RDB (.CCB);
end; !of routine TIMRDB
routine TRANSMIT_DONE (DESC, STS) : LINKAGE_DESC_STS novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! DESC = terminated descriptor address.
! STS = completion status.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
DESC : ref block field (BD_FIELDS);
local
CCB : ref block field (C_FIELDS),
QUE;
GET_DUP_DATA_BASE (DB);
QUE = block [.DB [D_EXT_ADDR], E_ASSIGNED_TRANSMIT_CCBS];
if not $MCB_DEQUEUE_CCB (.QUE, CCB)
then
begin
COUNTER_INCREMENT (DB, D_TRANSMIT_BA_ERROR);
COUNTER_INCREMENT (DB, D_DEVICE_ERRORS);
DEVICE_BROKEN (DB [D_TIM]);
return;
end;
if .CCB [C_STS] neq .DESC
then
begin
$MCB_STACK_CCB (.QUE, .CCB);
COUNTER_INCREMENT (DB, D_TRANSMIT_BA_ERROR);
COUNTER_INCREMENT (DB, D_DEVICE_ERRORS);
DEVICE_BROKEN (DB [D_TIM]);
return;
end;
DB [D_TIM] = 0;
DB [D_ASSIGNED_TRANSMIT_COUNT] = .DB [D_ASSIGNED_TRANSMIT_COUNT] - 1;
if not .DB [DF_KILLING_TRANSMITS]
then
DB [D_ASSIGNABLE_TRANSMIT_COUNT] = .DB [D_ASSIGNABLE_TRANSMIT_COUNT] + 1;
CCB [C_LIX] = .DB [D_LIX];
DDXCP$ (.CCB, .STS);
ASSIGN_TRANSMIT_BUFFER ();
end; !of routine TRANSMIT_DONE
routine TRANSMIT_KILLED : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! None
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
GET_DUP_DATA_BASE (DB);
DB [DF_KILLING_TRANSMITS] = FALSE;
DB [DF_TRANSMIT_UNDERRUN] = FALSE;
DB [D_ASSIGNED_TRANSMIT_COUNT] = 0;
if .DB [DF_ENABLED]
then
DB [D_ASSIGNABLE_TRANSMIT_COUNT] = 2;
while TRUE do
begin
local
CCB : ref block field (C_FIELDS);
if not $MCB_DEQUEUE_CCB (block [.DB [D_EXT_ADDR], E_ASSIGNED_TRANSMIT_CCBS], CCB)
then
if not $MCB_DEQUEUE_CCB (DB [D_ASSIGNABLE_TRANSMIT_CCBS], CCB)
then
exitloop;
CCB [C_LIX] = .DB [D_LIX];
DDXCP$ (.CCB, CE_ABO);
end;
while TRUE do
begin
local
CCB : ref block field (C_FIELDS);
if not $MCB_DEQUEUE_CCB (DB [D_PENDING_CONTROL_CCBS], CCB) then exitloop;
COMPLETE (DB [D_TIM], .CCB);
end;
end; !of routine TRANSMIT_KILLED
end
eludom