(FILECREATED "30-Oct-85 19:04:30" {ERIS}<LISPCORE>SOURCES>10MBDRIVER.;16 53339 changes to: (FNS \10MB.TURNONETHER) previous date: "18-Sep-85 15:10:49" {ERIS}<LISPCORE>SOURCES>10MBDRIVER.;15) (* Copyright (c) 1982, 1983, 1984, 1985 by Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT 10MBDRIVERCOMS) (RPAQQ 10MBDRIVERCOMS ((COMS (* raw packet interface) (FNS \10MBGETPACKET \10MBSENDPACKET \10MBENCAPSULATE \10MB.BROADCASTP \10MBWATCHER)) (COMS (* Machine independent part) (FNS \10MB.STARTDRIVER \10MB.CREATENDB \10MB.INPUT.INTERRUPT \10MB.OUTPUT.INTERRUPT \10MB.NOTESTAT) (INITVARS (\10MB.RCLK.BOX (CREATECELL \FIXP)) (\10MB.EXPECTED.RECEIVE.INTERVAL 60) (\10MB.INPUT.TIMEOUT (TIMES \RCLKSECOND \10MB.EXPECTED.RECEIVE.INTERVAL)) (\10MB.INPUT.TIMER (SETUPTIMER 0))) (GLOBALVARS \10MB.RCLK.BOX \10MB.EXPECTED.RECEIVE.INTERVAL \10MB.INPUT.TIMEOUT \10MB.INPUT.TIMER)) (COMS (* Buffer management) (FNS \10MB.LOADINPUTQ \RELEASE.IOCB \GET.IOCB \INIT.ETHER.BUFFER.POOL) (INITVARS (\10MBPACKETLENGTH 448))) (COMS (* Dolphin/Dlion head) (FNS \10MB.GETPACKETLENGTH \10MB.GETPACKETSTATUS \QUEUE.INPUT.IOCB \QUEUE.OUTPUT.IOCB \10MB.TURNOFFETHER \10MB.TURNONETHER \10MB.RESTART.ETHER) (DECLARE: EVAL@COMPILE DONTCOPY (COMS * 10MBDECLARATIONS))) (COMS (* Misc) (FNS \NOMACHINETYPE) (FNS IOCBQLENGTH)) (INITVARS \10MB.GETGARBAGE \10MB.COLLECTSTATS) (COMS (* PUP address resolution) (FNS \HANDLE.RAW.3TO10 \TRANSLATE.3TO10 PRINT3TO10 \NOTE.3TO10) (INITVARS (\10MBTYPE.PUP 512) (\10MBTYPE.3TO10 513)) (GLOBALVARS \10MBTYPE.3TO10 \10MBTYPE.PUP) (CONSTANTS \EPT.3TO10) (ADDVARS (\PACKET.PRINTERS (513 . PRINT3TO10)))) (DECLARE: EVAL@COMPILE DONTCOPY (FILES (LOADCOMP) DOVEETHER LLETHER LLNS)))) (* raw packet interface) (DEFINEQ (\10MBGETPACKET [LAMBDA NIL (* bvm: "28-FEB-83 11:39") (PROG (PACKET) (RETURN (COND ((SETQ PACKET (\DEQUEUE \10MB.RAWPACKETQ)) [COND (\RAWTRACING (\MAYBEPRINTPACKET PACKET (QUOTE RAWGET] PACKET]) (\10MBSENDPACKET [LAMBDA (NDB PACKET) (* bvm: "26-Apr-84 09:30") (PROG ([DROPIT (AND \ETHERLIGHTNING (EQ 0 (RAND 0 \ETHERLIGHTNING] IOCB BUFLENGTH) [COND (\RAWTRACING (\MAYBEPRINTPACKET PACKET (QUOTE RAWPUT] [COND ((AND (NOT (fetch NDBCANHEARSELF of NDB)) (OR (fetch 10MBMULTICASTP of PACKET) (EQNSHOSTNUMBER (fetch 10MBDESTHOST of PACKET) \MY.NSHOSTNUMBER))) (* We would hear this packet if our hardware let us, so fake receipt) (PROG ((COPYPACKET (\ALLOCATE.ETHERPACKET))) (\BLT (LOCF (fetch 10MBLENGTH of COPYPACKET)) (LOCF (fetch 10MBLENGTH of PACKET)) (ADD1 (fetch 10MBLENGTH of PACKET))) (* Copy all data that would have been transmitted) (replace EPTYPE of COPYPACKET with (fetch 10MBTYPE of PACKET)) (replace EPNETWORK of COPYPACKET with NDB) (\ENQUEUE \10MB.RAWPACKETQ COPYPACKET] (UNINTERRUPTABLY (replace EPTRANSMITTING of PACKET with T) (COND ([OR DROPIT (NULL (SETQ IOCB (\GET.IOCB (QUOTE OUTPUT] (* Fake transmission) (replace EPNETWORK of PACKET with NIL)) (T (replace EPNETWORK of PACKET with IOCB) (SETQ BUFLENGTH (IMAX (fetch 10MBLENGTH of PACKET) \10MB.MINPACKETLENGTH)) (\TEMPLOCKPAGES PACKET (COND ((IGEQ BUFLENGTH \MIN2PAGEBUFLENGTH) 2) (T 1))) (* Put on microcode queue) (\QUEUE.OUTPUT.IOCB NDB IOCB (fetch 10MBPACKETBASE of PACKET) BUFLENGTH) T)) (\ENQUEUE (fetch NDBTQ of NDB) PACKET) (* Put on driver's queue to pick up after microcode finishes with it) ) (RETURN (AND IOCB T]) (\10MBENCAPSULATE [LAMBDA (NDB PACKET PDH LENGTH TYPE) (* bvm: " 7-MAR-83 12:44") (* Encapsulates packets for 10mb net) (replace 10MBDESTHOST of PACKET with PDH) (replace 10MBSOURCEHOST of PACKET with \MY.NSHOSTNUMBER) (replace 10MBLENGTH of PACKET with (IPLUS (FOLDHI LENGTH BYTESPERWORD) \10MBENCAPSULATION.WORDS)) (replace 10MBTYPE of PACKET with TYPE) PACKET]) (\10MB.BROADCASTP [LAMBDA (PACKET) (* bvm: "23-Apr-84 14:34") (fetch 10MBMULTICASTP of PACKET]) (\10MBWATCHER [LAMBDA (NDB) (* bvm: "26-OCT-83 15:23") (* Process that watches the 10mb net and pulls packets in. Decodes the type and passes packet to interested party) (PROG ((CNTR 0) PACKET) LP (UNINTERRUPTABLY (\10MB.INPUT.INTERRUPT NDB) (\10MB.OUTPUT.INTERRUPT NDB)) [COND ((SETQ PACKET (\10MBGETPACKET)) (* Got something) (\HANDLE.RAW.PACKET PACKET) (COND ((ILESSP (add CNTR 1) \MAXWATCHERGETS) (* Hack to get better ether service in lieu of preemption) (GO LP] (BLOCK) (SETQ CNTR 0) (GO LP]) ) (* Machine independent part) (DEFINEQ (\10MB.STARTDRIVER (LAMBDA (NDB RESTARTFLG MYNSNUMBER) (* ejs: " 7-Sep-85 19:24") (\10MB.TURNOFFETHER NDB) (OR (\INIT.ETHER.BUFFER.POOL) (ERROR "Unable to create buffer pool")) (replace NDBTQ of NDB with (create SYSQUEUE)) (SETQ \10MB.RAWPACKETQ (create SYSQUEUE)) (SETQ \10MB.INPUT.TIMEOUT (TIMES \RCLKSECOND \10MB.EXPECTED.RECEIVE.INTERVAL)) (\10MB.TURNONETHER NDB NIL NIL (OR MYNSNUMBER T) 0 0) (PROG ((LEN 0) (IQ (fetch NDBIQ of NDB))) (COND (IQ (SETQ LEN (\10MB.LOADINPUTQ NDB (fetch SYSQUEUEHEAD of IQ)))) (T (replace NDBIQ of NDB with (SETQ IQ (create SYSQUEUE))))) (bind IOCB PACKET to (IDIFFERENCE \10MB.IDEAL.INPUT.LENGTH LEN) while (SETQ IOCB (\GET.IOCB (QUOTE INPUT))) do (SETQ PACKET (\ALLOCATE.ETHERPACKET)) (\TEMPLOCKPAGES PACKET 2) (replace EPNETWORK of PACKET with IOCB) (\QUEUE.INPUT.IOCB NDB IOCB (fetch 10MBPACKETBASE of PACKET) \10MBPACKETLENGTH) (* Add IOCB to microcode's queue) (\ENQUEUE IQ PACKET) (* and to driver's queue, so it can process it after arrival) (add LEN 1)) (replace NDBIQLENGTH of NDB with LEN) (replace NDBWATCHER of NDB with (ADD.PROCESS (LIST (QUOTE \10MBWATCHER) (KWOTE NDB)) (QUOTE RESTARTABLE) (QUOTE SYSTEM) (QUOTE AFTEREXIT) (QUOTE DELETE))) (RETURN NDB)))) (\10MB.CREATENDB [LAMBDA (ETHERTASK#) (* bvm: "15-Feb-85 22:18") (\10MB.STARTDRIVER (create NDB NDBNSNET# ← 0 NDBPUPNET# ← 0 NETTYPE ← 10 NDBPUPTYPE ← \10MBTYPE.PUP NDBTRANSMITTER ←(FUNCTION \10MBSENDPACKET) NDBENCAPSULATOR ←(FUNCTION \10MBENCAPSULATE) NDBBROADCASTP ←(FUNCTION \10MB.BROADCASTP) NDBTASK# ← ETHERTASK# NDBETHERFLUSHER ←(FUNCTION \10MB.TURNOFFETHER) NDBCANHEARSELF ←(EQ \MACHINETYPE \DOLPHIN]) (\10MB.INPUT.INTERRUPT (LAMBDA (NDB) (* ejs: "18-Sep-85 14:46") (* This routine gets called when 10MB input signals an interrupt. See if the head of the input queue has indeed been processed, and if so, take care of it) (PROG ((PACKET (fetch SYSQUEUEHEAD of (fetch NDBIQ of NDB))) STATUS ACCEPTPACKET IOCB) (COND ((AND PACKET (NEQ (SETQ STATUS (\10MB.GETPACKETSTATUS (SETQ IOCB (fetch EPNETWORK of PACKET)))) \ES.PENDING)) (* Yes, something is there, and microcode is finished with it) (\DEQUEUE (fetch NDBIQ of NDB)) (COND (\10MB.COLLECTSTATS (\10MB.NOTESTAT STATUS PACKET (QUOTE INPUT)))) (COND ((SETQ ACCEPTPACKET (OR (EQ STATUS \ES.GOOD.PACKET) \10MB.GETGARBAGE)) (PROG ((LENGTH (\10MB.GETPACKETLENGTH IOCB))) (* Accept the packet) (replace 10MBLENGTH of PACKET with LENGTH) (\RCLK (LOCF (fetch EPTIMESTAMP of PACKET))) (replace EPRECEIVING of PACKET with NIL) (replace EPNETWORK of PACKET with NDB) (replace EPTYPE of PACKET with (fetch 10MBTYPE of PACKET)) (COND ((AND (OR (EQ \MACHINETYPE \DANDELION) (EQ \MACHINETYPE \DAYBREAK)) (IGREATERP LENGTH \MIN2PAGEBUFLENGTH)) (* Dandelion ether uCode doesn't set the dirty bit on pages of PACKET, so make sure the second page gets marked dirty if it needs to be. The first page has been implicitly marked dirty by the replaces above) (\PUTBASE PACKET (SUB1 (ITIMES WORDSPERPAGE 2)) 0))) (\TEMPUNLOCKPAGES PACKET 2) (\ENQUEUE \10MB.RAWPACKETQ PACKET)) (PROGN (* Now stuff a new buffer on queue) (SETQ PACKET (\ALLOCATE.ETHERPACKET)) (\TEMPLOCKPAGES PACKET 2) (replace EPNETWORK of PACKET with IOCB)))) (* Now stuff a buffer back on the input) (\QUEUE.INPUT.IOCB NDB IOCB (fetch 10MBPACKETBASE of PACKET) \10MBPACKETLENGTH) (\ENQUEUE (fetch NDBIQ of NDB) PACKET)) (PACKET (* There is something there, and the microcode is NOT finished with it) (COND ((NOT (fetch EPRECEIVING of PACKET)) (* * Furthermore, this is the first time we've seen this packet at the head of the receive queue. We timestamp it, and if it's still here sometime later, we kick the Ethernet receiver microcode, just in case it's turned itself off) (SETUPTIMER \10MB.INPUT.TIMEOUT \10MB.INPUT.TIMER (QUOTE TICKS)) (replace EPRECEIVING of PACKET with T)) (T (* * We've seen this packet before. Check for timeout, and kick the receiver microcode if necessary) (COND ((TIMEREXPIRED? \10MB.INPUT.TIMER (QUOTE TICKS)) (\10MB.RESTART.ETHER NDB) (* Update the timestamp) (SETUPTIMER \10MB.INPUT.TIMEOUT \10MB.INPUT.TIMER (QUOTE TICKS)))))))) (RETURN ACCEPTPACKET)))) (\10MB.OUTPUT.INTERRUPT [LAMBDA (NDB) (* bvm: "10-JUN-83 14:56") (* This routine gets called when 10MB output signals an interrupt. Remove the head of the output queue and put it on the done queue) (PROG ((NEXTPACKET (fetch SYSQUEUEHEAD of (fetch NDBTQ of NDB))) STATUS IOCB) (RETURN (COND ((AND NEXTPACKET (OR (NULL (SETQ IOCB (fetch EPNETWORK of NEXTPACKET))) (NEQ (SETQ STATUS (\10MB.GETPACKETSTATUS IOCB)) \ES.PENDING))) (* Yes, microcode has finished processing this buffer) (\DEQUEUE (fetch NDBTQ of NDB)) (replace EPTRANSMITTING of NEXTPACKET with NIL) (replace EPNETWORK of NEXTPACKET with NIL) (\REQUEUE.ETHERPACKET NEXTPACKET) [COND (IOCB (\RELEASE.IOCB IOCB (QUOTE OUTPUT)) (\TEMPUNLOCKPAGES NEXTPACKET 2) (COND (\10MB.COLLECTSTATS (\10MB.NOTESTAT STATUS NEXTPACKET (QUOTE OUTPUT] T]) (\10MB.NOTESTAT [LAMBDA (STATUS BUF USE) (* bvm: "15-JUL-82 14:43") (* Increment counter associated with this status) NIL]) ) (RPAQ? \10MB.RCLK.BOX (CREATECELL \FIXP)) (RPAQ? \10MB.EXPECTED.RECEIVE.INTERVAL 60) (RPAQ? \10MB.INPUT.TIMEOUT (TIMES \RCLKSECOND \10MB.EXPECTED.RECEIVE.INTERVAL)) (RPAQ? \10MB.INPUT.TIMER (SETUPTIMER 0)) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS \10MB.RCLK.BOX \10MB.EXPECTED.RECEIVE.INTERVAL \10MB.INPUT.TIMEOUT \10MB.INPUT.TIMER) ) (* Buffer management) (DEFINEQ (\10MB.LOADINPUTQ [LAMBDA (NDB PACKETS) (* bvm: "28-FEB-83 17:36") (* PACKETS points at the first of several buffers of NDB's IQ. We load them into the microcode's chain. Value returned is the number of buffers) (bind (CNT ← 0) while PACKETS do (\TEMPLOCKPAGES PACKETS 2) (\QUEUE.INPUT.IOCB NDB (fetch EPNETWORK of PACKETS) (fetch 10MBPACKETBASE of PACKETS) \10MBPACKETLENGTH) (SETQ PACKETS (fetch EPLINK of PACKETS)) (add CNT 1) finally (RETURN CNT]) (\RELEASE.IOCB [LAMBDA (IOCB USE) (* bvm: " 3-MAR-83 16:17") (* Returns an IOCB to the free pool. USE is INPUT or OUTPUT, according to which side should be credited. Must be called uninterruptably) (COND ((NOT (AND IOCB (EMADDRESSP IOCB))) (ERROR "ARG NOT IOCB" IOCB)) (T (SELECTQ USE (INPUT (add \IOCB.INPUT.ALLOC 1)) (OUTPUT (add \IOCB.OUTPUT.ALLOC 1)) (\ILLEGAL.ARG USE)) (replace D0NEXTIOCB of IOCB with (\LOLOC \IOCBFREELIST)) (* (\LOLOC NIL) = 0 works also) (SETQ \IOCBFREELIST IOCB) NIL]) (\GET.IOCB [LAMBDA (USE) (* edited: "14-Aug-85 16:46") (* returns a IOCB for INPUT or OUTPUT use, or NIL if none is available. This must be called uninterruptably, since we don't have any easy way of GCing these guys) (DECLARE (GLOBALVARS \10MBLOCALNDB)) (COND ((AND \IOCBFREELIST (IGREATERP (SELECTQ USE (INPUT \IOCB.INPUT.ALLOC) (OUTPUT \IOCB.OUTPUT.ALLOC) (\ILLEGAL.ARG USE)) 0)) (SELECTQ USE (INPUT (add \IOCB.INPUT.ALLOC -1)) (add \IOCB.OUTPUT.ALLOC -1)) (* * I removed the call to HELP that used to be in here. If the IOCB freelist goes NIL, the packet is dropped on the floor) (PROG1 \IOCBFREELIST (SETQ \IOCBFREELIST (EMPOINTER (fetch D0NEXTIOCB of \IOCBFREELIST))) (* Note that (EMPOINTER 0) = NIL, so this works even when free list runs out) ]) (\INIT.ETHER.BUFFER.POOL [LAMBDA NIL (* ejs: "26-Jul-85 23:14") (* Divides up the zone bcpl reserved for us into IOCB's used for sending/receiving ether packets. The IOCB's must be quad-aligned. When an ether packet is to be sent, or prepared for receiving, an IOCB is assigned to it. The IOCB contains length and status info and a pointer to the ether packet buffer in Lisp space. The IOCB's are chained for the microcode, and the packets are chained independently in Lisp space so that we can keep track of them after the microcode finishes. \IOCBFREELIST points at the first IOCB; there are a total of \IOCBTOTAL of them.) (PROG (LASTBUF BUFFER ZONE ZONELENGTH) (COND ((EQ (SETQ ZONELENGTH (fetch (IFPAGE MDSZoneLength) of \InterfacePage)) 0) (* Bcpl was unable to allocate any space for us) (SETQ \IOCBFREELIST NIL) (SETQ \IOCBTOTAL 0) (RETURN)) (T (SETQ ZONE (fetch (IFPAGE MDSZone) of \InterfacePage)) [SETQ ZONELENGTH (IDIFFERENCE ZONELENGTH (IDIFFERENCE ZONE (SETQ ZONE (CEIL ZONE (ITIMES 2 WORDSPERQUAD] (* 8-align the zone, in case the microcode cares, and adjust the length downward if necessary) (SETQ ZONE (EMPOINTER ZONE)) (* Make an actual pointer) )) (SETQ \IOCBTOTAL (IMIN (IQUOTIENT (IDIFFERENCE ZONELENGTH 3) (SELECTC \MACHINETYPE (\DAYBREAK \DoveEther.IOIOCBLength) \IOCB.LENGTH)) \MAXIOCBS)) (SETQ \IOCBFREELIST ZONE) (to \IOCBTOTAL do (* Link the idle IOCB's together using short addresses) [replace D0NEXTIOCB of ZONE with (\LOLOC (SETQ ZONE (\ADDBASE ZONE (SELECTC \MACHINETYPE (\DAYBREAK \DoveEther.IOIOCBLength) \IOCB.LENGTH] finally (replace D0NEXTIOCB of ZONE with 0)) [SETQ \TELERAIDIOCB (PROG1 \IOCBFREELIST (SETQ \IOCBFREELIST (EMPOINTER (fetch D0NEXTIOCB of \IOCBFREELIST] (* Pop one off for TeleRaid) (add \IOCBTOTAL -1) [SETQ \IOCB.INPUT.ALLOC (SETQ \IOCB.INPUT.TOTAL (SETQ \IOCB.OUTPUT.ALLOC (SETQ \IOCB.OUTPUT.TOTAL (IQUOTIENT (ITIMES \IOCBTOTAL 2) 3] (SETQ \10MB.IDEAL.INPUT.LENGTH (IMIN \10MB.MAX.INPUT.LENGTH (IQUOTIENT \IOCBTOTAL 2))) (RETURN \IOCBTOTAL]) ) (RPAQ? \10MBPACKETLENGTH 448) (* Dolphin/Dlion head) (DEFINEQ (\10MB.GETPACKETLENGTH (LAMBDA (IOCB) (* ejs: "18-Sep-85 15:09") (SELECTC \MACHINETYPE (\DANDELION (fetch DLIOCBBYTESUSED of IOCB)) (\DAYBREAK (fetch (Dove.EtherIOIOCB count) of IOCB)) (\DOLPHIN (FOLDLO (fetch D0IOCBBYTESUSED of IOCB) BYTESPERWORD)) (\NOMACHINETYPE)))) (\10MB.GETPACKETSTATUS [LAMBDA (IOCB) (* ejs: "26-Jul-85 22:43") (* * Translate device bits to device-independent constants) (* * Now allow odd-length packets to be received) (SELECTC \MACHINETYPE [\DANDELION (PROG ((STATUS (fetch DLIOCBSTATUS of IOCB))) (RETURN (COND ((EQ STATUS 0) \ES.PENDING) [(EQ (fetch DLFOROUTPUTUSE of IOCB) 0) (* Input errors) (COND ((EQ (fetch DLIOCBLENGTH of IOCB) 65535) \ES.PACKET.TOO.LONG) (T (COND ((EQ (SETQ STATUS (LOGAND STATUS (LOGOR \DL.BAD.ALIGNMENT \DL.OVERRUN \DL.BAD.CRC))) 0) \ES.GOOD.PACKET) ((NEQ (LOGAND STATUS \DL.OVERRUN) 0) \ES.OVERRUN) ((NEQ (LOGAND STATUS \DL.BAD.CRC) 0) (COND ((EQ (LOGAND STATUS (LOGOR \DL.BAD.ALIGNMENT \DL.ODDLENGTH)) 0) \ES.BAD.CRC) (T \ES.BAD.CRC&ALIGNMENT))) ((NEQ (LOGAND STATUS \DL.BAD.ALIGNMENT) 0) \ES.BAD.ALIGNMENT) (T \ES.OTHER.ERROR] (T (* Output errors) (COND ((EQ (fetch DLRETRANSMISSIONMASK of IOCB) 8191) \ES.TOO.MANY.COLLISIONS) (T (COND ((EQ (LOGAND STATUS (LOGOR \DL.COLLISION \DL.UNDERRUN)) 0) \ES.GOOD.PACKET) (T \ES.UNDERRUN] (\DAYBREAK (\DoveEther.GetPacketStatus IOCB)) [\DOLPHIN (PROG ((STATUS (fetch D0IOCBSTATUS of IOCB))) (RETURN (SELECTC STATUS (0 \ES.PENDING) (\D0.GOOD.PACKET \ES.GOOD.PACKET) (\D0.LATE.COLLISION \ES.LATE.COLLISION) (\D0.TOO.MANY.COLLISIONS \ES.TOO.MANY.COLLISIONS) (\D0.PACKET.TOO.LONG \ES.PACKET.TOO.LONG) (\D0.BAD.ALIGNMENT \ES.BAD.ALIGNMENT) (\D0.INPUT.BAD.CRC \ES.BAD.CRC) ((LOGOR \D0.BAD.ALIGNMENT \D0.INPUT.BAD.CRC) \ES.BAD.CRC&ALIGNMENT) (COND ((NEQ (LOGAND STATUS \D0.INPUT.OVERRUN) 0) \ES.OVERRUN) ((NEQ (LOGAND STATUS \D0.OUTPUT.UNDERRUN) 0) \ES.UNDERRUN) (T \ES.OTHER.ERROR] (\NOMACHINETYPE]) (\QUEUE.INPUT.IOCB (LAMBDA (NDB IOCB BUFFER LENGTH) (* ejs: " 7-Sep-85 19:42") (* Add IOCB to the end of the microcode input queue, with BUFFER of LENGTH words as its buffer. I.e., this is a buffer that packets will be read into) (PROG ((CSB (fetch NDBCSB of NDB))) (SELECTC \MACHINETYPE (\DANDELION (replace DLFOROUTPUTUSE of IOCB with 0) (* So that \10MB.GETPACKETSTATUS can tell which way packet is going) (replace DLNEXTIOCB of IOCB with 0) (replace DLRETRANSMISSIONMASK of IOCB with 0) (replace DLIOCBSTATUS of IOCB with \ES.PENDING) (replace DLIOCBLENGTH of IOCB with LENGTH) (replace DLIOCBBUFFER of IOCB with BUFFER) (COND ((NEQ (fetch DLFIRSTICB of CSB) 0) (* There are some packets there, so add this to end) (replace DLNEXTIOCB of (OR (EMPOINTER (fetch DLLASTICB of CSB)) (RAID "Garbage last ICB")) with (\LOLOC IOCB)))) (COND ((AND (EQ (fetch DLFIRSTICB of CSB) 0) (EQ (fetch DLIOCBSTATUS of IOCB) \ES.PENDING)) (* No buffers left, so queue this as the only one. While we were in the last clause, microcode could have eaten up its last buffer, which is why we test twice) (replace DLFIRSTICB of CSB with (\LOLOC IOCB)) (\DEVICE.OUTPUT \DL.ENABLE.INPUT \DL.ETHERINPUTREG))) (replace DLLASTICB of CSB with (\LOLOC IOCB))) (\DAYBREAK (\DoveEther.QueueInput IOCB BUFFER LENGTH)) (\DOLPHIN (replace D0NEXTIOCB of IOCB with 0) (replace D0RETRANSMISSIONMASK of IOCB with 0) (replace D0IOCBSTATUS of IOCB with \ES.PENDING) (replace D0IOCBLENGTH of IOCB with (UNFOLD LENGTH BYTESPERWORD)) (replace D0IOCBBUFFER of IOCB with BUFFER) (COND ((NEQ (fetch D0FIRSTICB of CSB) 0) (* There are some packets there, so add this to end) (replace D0NEXTIOCB of (OR (EMPOINTER (fetch D0LASTICB of CSB)) (RAID "Garbage last ICB")) with (\LOLOC IOCB)))) (COND ((AND (EQ (fetch D0FIRSTICB of CSB) 0) (EQ (fetch D0IOCBSTATUS of IOCB) \ES.PENDING)) (* No buffers left, so queue this as the only one. While we were in the last clause, microcode could have eaten up its last buffer, which is why we test twice) (replace D0FIRSTICB of CSB with (\LOLOC IOCB)) (\DEVICE.OUTPUT \D0.ENABLE.10MBINPUT (\D0.CONTROLLERBITS NDB \D0.INPUTSTATE)))) (replace D0LASTICB of CSB with (\LOLOC IOCB))) (\NOMACHINETYPE))))) (\QUEUE.OUTPUT.IOCB [LAMBDA (NDB IOCB BUFFER LENGTH) (* ejs: "26-Jul-85 22:46") (* Queue up IOCB for transmission. LENGTH is length of BUFFER in words) (PROG ((CSB (fetch NDBCSB of NDB))) (SELECTC \MACHINETYPE (\DANDELION (replace DLFOROUTPUTUSE of IOCB with 1) (* So that \10MB.GETPACKETSTATUS can tell which way packet is going) (replace DLIOCBLENGTH of IOCB with LENGTH) (replace DLNEXTIOCB of IOCB with 0) (replace DLRETRANSMISSIONMASK of IOCB with 0) (replace DLIOCBSTATUS of IOCB with \ES.PENDING) (replace DLIOCBBUFFER of IOCB with BUFFER) [COND ((NEQ (fetch DLFIRSTOCB of CSB) 0) (* Hardware active, add to end of chain) (replace DLNEXTIOCB of (OR (EMPOINTER (fetch DLLASTOCB of CSB)) (RAID "Garbage Last OCB")) with (\LOLOC IOCB] (COND ((AND (EQ (fetch DLFIRSTOCB of CSB) 0) (EQ (fetch DLIOCBSTATUS of IOCB) \ES.PENDING)) (* Separate check, as the hardware could have just gone idle since we last checked) (replace DLFIRSTOCB of CSB with (\LOLOC IOCB)) (\DEVICE.OUTPUT \DL.ENABLE.OUTPUT \DL.ETHEROUTPUTREG))) (replace DLLASTOCB of CSB with (\LOLOC IOCB))) (\DAYBREAK (\DoveEther.QueueOutput IOCB BUFFER LENGTH)) (\DOLPHIN (replace D0IOCBLENGTH of IOCB with (UNFOLD LENGTH BYTESPERWORD)) (replace D0NEXTIOCB of IOCB with 0) (replace D0RETRANSMISSIONMASK of IOCB with 0) (replace D0IOCBSTATUS of IOCB with \ES.PENDING) (replace D0IOCBBUFFER of IOCB with BUFFER) [COND ((NEQ (fetch D0FIRSTOCB of CSB) 0) (* Hardware active, add to end of chain) (replace D0NEXTIOCB of (OR (EMPOINTER (fetch D0LASTOCB of CSB)) (RAID "Garbage Last OCB")) with (\LOLOC IOCB] [COND ((AND (EQ (fetch D0FIRSTOCB of CSB) 0) (EQ (fetch D0IOCBSTATUS of IOCB) \ES.PENDING)) (* Separate check, as the hardware could have just gone idle since we last checked) (replace D0FIRSTOCB of CSB with (\LOLOC IOCB)) (\DEVICE.OUTPUT \D0.ENABLE.10MBOUTPUT (\D0.CONTROLLERBITS NDB \D0.OUTPUTSTATE] (replace D0LASTOCB of CSB with (\LOLOC IOCB))) (\NOMACHINETYPE]) (\10MB.TURNOFFETHER [LAMBDA (NDB) (* ejs: "26-Jul-85 22:47") (SELECTC \MACHINETYPE (\DANDELION (\DL.TURNOFFETHER)) (\DAYBREAK (\DoveEther.MakeSureOff)) (\DOLPHIN (\D0.TURNOFFETHER NDB)) (\NOMACHINETYPE]) (\10MB.TURNONETHER (LAMBDA (NDB SMASHSTATE NEWSTATE NSHOSTNUMBER ININTERRUPT OUTINTERRUPT) (* ejs: "30-Oct-85 17:41") (* * Reset and activate ether associated with NDB. If SMASHSTATE is given, it is a CSB-length block into which state is saved for later restoration by passing as the NEWSTATE arg. If NEWSTATE is NIL, then the remaining non-NIL args give parameters for this activation: the host number for microcode to watch for, T meaning my own number; and interrupt masks for when a packet arrives or finishes transmitting) (* * For Daybreak, SMASHSTATE and NEWSTATE must be NIL) (PROG ((CSB (fetch NDBCSB of NDB))) (SELECTC \MACHINETYPE (\DANDELION (\DL.TURNOFFETHER)) (\DAYBREAK (\DoveEther.MakeSureOff SMASHSTATE)) (\DOLPHIN (\D0.TURNOFFETHER NDB)) (\NOMACHINETYPE)) (COND ((AND SMASHSTATE (NEQ \MACHINETYPE \DAYBREAK)) (COND (CSB (\BLT SMASHSTATE CSB \CSB.LENGTH)) (T (* Arcane way of indicating ether is off. May have to revisit) (\PUTBASE CSB 4 65535))))) (COND ((AND NEWSTATE (NEQ \MACHINETYPE \DAYBREAK)) (* Smash old state into CSB) (COND ((EQ (\GETBASE NEWSTATE 4) 65535) (* Leave ether off) (RETURN))) (\BLT CSB NEWSTATE \CSB.LENGTH)) (T (SELECTC \MACHINETYPE (\DANDELION (OR CSB (replace NDBCSB of NDB with (SETQ CSB (LOCF (fetch DLETHERNET of \IOPAGE))))) (COND (NEWSTATE (* Smash old state into CSB) (* I don't think you can get here! --ejs) (COND ((EQ (\GETBASE NEWSTATE 4) 65535) (* Leave ether off) (RETURN))) (\BLT CSB NEWSTATE \CSB.LENGTH)) (T (* Initialize the Ether CSB according to args. No buffers initially) (replace DLFIRSTOCB of CSB with 0) (replace DLFIRSTICB of CSB with 0) (AND NSHOSTNUMBER (COND ((EQ NSHOSTNUMBER T) (\BLT (LOCF (fetch DLLOCALHOST0 of CSB)) (LOCF (fetch (IFPAGE NSHost0) of \InterfacePage)) \#WDS.NSHOSTNUMBER)) (T (\STORENSHOSTNUMBER (LOCF (fetch DLLOCALHOST0 of CSB)) NSHOSTNUMBER)))) (AND OUTINTERRUPT (replace DLOUTPUTMASK of CSB with OUTINTERRUPT)) (AND ININTERRUPT (replace DLINPUTMASK of CSB with ININTERRUPT)) (replace DLMISSEDPACKETS of CSB with 0) (replace DLLASTICB of CSB with 0) (replace DLLASTOCB of CSB with 0))) (\DEVICE.OUTPUT \DL.ENABLE.INPUT \DL.ETHERINPUTREG)) (\DAYBREAK (\DoveEther.TurnOn NSHOSTNUMBER NEWSTATE)) (\DOLPHIN (OR CSB (replace NDBCSB of NDB with (SETQ CSB (EMPOINTER (IPLUS 65280 (LLSH (fetch NDBTASK# of NDB) 4)))))) (* Initialize the Ether CSB according to args. No buffers initially) (replace D0FIRSTOCB of CSB with 0) (replace D0FIRSTICB of CSB with 0) (AND NSHOSTNUMBER (COND ((EQ NSHOSTNUMBER T) (\BLT (LOCF (fetch D0LOCALHOST0 of CSB)) (LOCF (fetch (IFPAGE NSHost0) of \InterfacePage)) \#WDS.NSHOSTNUMBER)) (T (\STORENSHOSTNUMBER (LOCF (fetch D0LOCALHOST0 of CSB)) NSHOSTNUMBER)))) (AND OUTINTERRUPT (replace D0OUTPUTMASK of CSB with OUTINTERRUPT)) (AND ININTERRUPT (replace D0INPUTMASK of CSB with ININTERRUPT)) (replace D0LASTICB of CSB with 0) (replace D0LASTOCB of CSB with 0) (\DEVICE.OUTPUT \D0.ENABLE.10MBINPUT (\D0.CONTROLLERBITS NDB \D0.INPUTSTATE))) (\NOMACHINETYPE)))) (SELECTC \MACHINETYPE (\DANDELION (\DEVICE.OUTPUT \DL.ENABLE.INPUT \DL.ETHERINPUTREG)) (\DAYBREAK) (\DOLPHIN (\DEVICE.OUTPUT \D0.ENABLE.10MBINPUT (\D0.CONTROLLERBITS NDB \D0.INPUTSTATE))) (\NOMACHINETYPE)) (RETURN NDB)))) (\10MB.RESTART.ETHER (LAMBDA (NDB) (* ejs: "18-Sep-85 15:10") (* * Kick the Ethernet receiver microcode (or Daybreak IOP) to restart the Ethernet receiver task. This function gets called when the 10MBDRIVER thinks the Ethernet has been accidentally disabled) (SELECTC \MACHINETYPE (\DANDELION (\DEVICE.OUTPUT \DL.ENABLE.INPUT \DL.ETHERINPUTREG)) (\DOLPHIN (\DEVICE.OUTPUT \D0.ENABLE.10MBINPUT (\D0.CONTROLLERBITS NDB \D0.INPUTSTATE))) (\DAYBREAK (\DoveIO.NotifyIOP (fetch (Dove.EtherFCB etherInWorkMask) of \DoveEther.FCBPointer))) NIL))) ) (DECLARE: EVAL@COMPILE DONTCOPY (RPAQQ 10MBDECLARATIONS ((COMS (RECORDS 10MBENCAPSULATION) (CONSTANTS \10MBENCAPSULATION.WORDS)) (MACROS \D0.CONTROLLERBITS \D0.TURNOFFETHER \DL.TURNOFFETHER) (RECORDS D0ETHERCSB D0ETHERIOCB DLETHERCSB DLETHERIOCB) (CONSTANTS (\D0.ENABLE.10MBINPUT 49152) (\D0.ENABLE.10MBOUTPUT 192) (\D0.RESET.10MBCONTROLLER 512) (\D0.INPUTSTATE 1) (\D0.OUTPUTSTATE 2) (\CSB.LENGTH 16) (\IOCB.LENGTH 8) (\MIN2PAGEBUFLENGTH 232) (\10MB.MINPACKETLENGTH 30)) (CONSTANTS * DLIONETHERCONSTANTS) (CONSTANTS * ETHERSTATUSCONSTANTS) (CONSTANTS * D0ETHERSTATUSCONSTANTS) (CONSTANTS * DLETHERSTATUSCONSTANTS) (CONSTANTS (\MAXLLBUFFERPAGES 2) (\MINLLBUFFERPAGES 1) (\MAXIOCBS 64) (\10MB.MAX.INPUT.LENGTH 20)) (GLOBALVARS \IOCB.INPUT.ALLOC \IOCB.INPUT.TOTAL \IOCB.OUTPUT.ALLOC \IOCB.OUTPUT.TOTAL \IOCBTOTAL \10MB.GETGARBAGE \10MB.RAWPACKETQ \10MB.IDEAL.INPUT.LENGTH \10MB.COLLECTSTATS \MACHINETYPE \10MBPACKETLENGTH \IOCBFREELIST))) [DECLARE: EVAL@COMPILE (ACCESSFNS 10MBENCAPSULATION ((10MBBASE (LOCF (fetch (ETHERPACKET EPENCAPSULATION) of DATUM)))) (BLOCKRECORD 10MBBASE ((10MBLENGTH WORD) (* Length of packet in words, starting at the next word. Not part of the actual packet; it is here for convenience) (10MBDESTHOST0 3 WORD) (* Immediate destination host) (10MBSOURCEHOST0 3 WORD) (* Us) (10MBTYPE WORD) (* Type of packet -- PUP, NS) ) (BLOCKRECORD 10MBBASE ((NIL WORD) (* Length) (NIL BITS 7) (10MBMULTICASTP FLAG) (NIL BITS 8) (* Lo bit of first destination byte is the multicast bit) )) (ACCESSFNS 10MBDESTHOST0 ((10MBDESTHOST (\LOADNSHOSTNUMBER (LOCF DATUM)) (\STORENSHOSTNUMBER (LOCF DATUM) NEWVALUE)) (10MBPACKETBASE (LOCF DATUM)) (10MBDESTHOSTBASE (LOCF DATUM)))) (ACCESSFNS 10MBSOURCEHOST0 ((10MBSOURCEHOST (\LOADNSHOSTNUMBER (LOCF DATUM)) (\STORENSHOSTNUMBER (LOCF DATUM) NEWVALUE)) (10MBSOURCEHOSTBASE (LOCF DATUM))))) (TYPE? (type? ETHERPACKET DATUM))) ] (DECLARE: EVAL@COMPILE (RPAQQ \10MBENCAPSULATION.WORDS 7) (CONSTANTS \10MBENCAPSULATION.WORDS) ) (DECLARE: EVAL@COMPILE (PUTPROPS \D0.CONTROLLERBITS MACRO ((NDB STATE) (* Returns a TASKREG argument for use with \DEVICE.INPUT / OUTPUT for controller's STATE reg, 0 <= STATE < 15; \D0.ETHERTASKNUMBER is a global set in initialization) (LOGOR (LLSH (fetch NDBTASK# of NDB) 4) STATE))) (PUTPROPS \D0.TURNOFFETHER MACRO (OPENLAMBDA (NDB) (\D0.STARTIO \D0.RESET.10MBCONTROLLER))) (PUTPROPS \DL.TURNOFFETHER MACRO (NIL (PROGN (\DEVICE.OUTPUT \DL.TURNOFFETHER \DL.ETHERINPUTREG) (to 3 repeatuntil (ZEROP (LOGAND (\DEVICE.INPUT \DL.ETHERSTATUSREG) (LOGOR \DL.INPUT.ENABLED \DL.OUTPUT.ENABLED))))) )) ) [DECLARE: EVAL@COMPILE (BLOCKRECORD D0ETHERCSB ((D0FIRSTOCB WORD) (* Short pointer to first OCB) (D0OUTPUTMASK WORD) (* Bit mask for output interrupt) (D0INPUTMASK WORD) (* Bit mask for input interrupt) (D0MISSEDPACKETS WORD) (* Count of missed packets (for debugging)) (D0FIRSTICB WORD) (* Short pointer to first ICB) (D0LOCALHOST0 WORD) (* Address we are listening for, 48d bits) (D0LOCALHOST1 WORD) (D0LOCALHOST2 WORD) (D0UCODESCRATCH 4 WORD) (* Scratch buffer for microcode) (D0LASTICB WORD) (* Short pointer to last ICB if D0FIRSTICB non-null; not used by microcode) (D0LASTOCB WORD) (* last OCB if D0FIRSTOCB non-null) (D0CSBSPARE 2 WORD))) (BLOCKRECORD D0ETHERIOCB ((D0NEXTIOCB WORD) (* Short pointer to next one) (D0RETRANSMISSIONMASK WORD) (* Retransmission mask, output only) (NIL WORD) (D0IOCBSTATUS WORD) (* Completion code, filled in by microcode task) (D0IOCBBYTESUSED WORD) (* Number of bytes received) (D0IOCBLENGTH WORD) (* Length of buffer in bytes) (D0IOCBBUFFERLO WORD) (* Long pointer to buffer. Must be locked and quad-1 aligned) (D0IOCBBUFFERHI WORD)) (ACCESSFNS D0ETHERIOCB ((D0IOCBBUFFER (\VAG2 (fetch D0IOCBBUFFERHI of DATUM) (fetch D0IOCBBUFFERLO of DATUM)) (PROGN (replace D0IOCBBUFFERHI of DATUM with (\HILOC NEWVALUE)) (replace D0IOCBBUFFERLO of DATUM with (\LOLOC NEWVALUE)))))) ) (BLOCKRECORD DLETHERCSB ((DLLOCALHOST0 WORD) (* Address we are listening for, 48d bits) (DLLOCALHOST1 WORD) (DLLOCALHOST2 WORD) (DLFIRSTICB WORD) (* Short pointer to first ICB) (DLINPUTMASK WORD) (* Bit mask for input interrupt) (DLFIRSTOCB WORD) (* Short pointer to first OCB) (DLOUTPUTMASK WORD) (* Bit mask for output interrupt) (DLMISSEDPACKETS WORD) (* Count of missed packets (for debugging)) (DLLASTICB WORD) (* Short pointer to last ICB if DLFIRSTICB non-null; not used by microcode) (DLLASTOCB WORD) (* last OCB if DLFIRSTOCB non-null) )) (BLOCKRECORD DLETHERIOCB ((DLIOCBLENGTH WORD) (* Length of buffer in bytes) (DLIOCBBUFFERLO WORD) (* Long pointer to buffer. Must be locked and quad-1 aligned) (DLIOCBBUFFERHI WORD) (DLRETRANSMISSIONMASK WORD) (* Retransmission mask, output only) (DLIOCBBYTESUSED WORD) (* Number of bytes received) (DLIOCBSTATUS WORD) (* Completion code, filled in by microcode task) (DLNEXTIOCB WORD) (* Short pointer to next one) (DLFOROUTPUTUSE WORD) (* Not used by microcode) ) (ACCESSFNS DLETHERIOCB ((DLIOCBBUFFER (\VAG2 (fetch DLIOCBBUFFERHI of DATUM) (fetch DLIOCBBUFFERLO of DATUM)) (PROGN (replace DLIOCBBUFFERHI of DATUM with (\HILOC NEWVALUE)) (replace DLIOCBBUFFERLO of DATUM with (\LOLOC NEWVALUE)))))) ) ] (DECLARE: EVAL@COMPILE (RPAQQ \D0.ENABLE.10MBINPUT 49152) (RPAQQ \D0.ENABLE.10MBOUTPUT 192) (RPAQQ \D0.RESET.10MBCONTROLLER 512) (RPAQQ \D0.INPUTSTATE 1) (RPAQQ \D0.OUTPUTSTATE 2) (RPAQQ \CSB.LENGTH 16) (RPAQQ \IOCB.LENGTH 8) (RPAQQ \MIN2PAGEBUFLENGTH 232) (RPAQQ \10MB.MINPACKETLENGTH 30) (CONSTANTS (\D0.ENABLE.10MBINPUT 49152) (\D0.ENABLE.10MBOUTPUT 192) (\D0.RESET.10MBCONTROLLER 512) (\D0.INPUTSTATE 1) (\D0.OUTPUTSTATE 2) (\CSB.LENGTH 16) (\IOCB.LENGTH 8) (\MIN2PAGEBUFLENGTH 232) (\10MB.MINPACKETLENGTH 30)) ) (RPAQQ DLIONETHERCONSTANTS ((\DL.ETHERINPUTREG 5) (\DL.ETHEROUTPUTREG 12) (\DL.ETHERSTATUSREG 1) (\DL.TURNOFFETHER 2) (\DL.ENABLE.OUTPUT 1) (\DL.ENABLE.INPUT 1) (\DL.INPUT.ENABLED 1024) (\DL.OUTPUT.ENABLED 256))) (DECLARE: EVAL@COMPILE (RPAQQ \DL.ETHERINPUTREG 5) (RPAQQ \DL.ETHEROUTPUTREG 12) (RPAQQ \DL.ETHERSTATUSREG 1) (RPAQQ \DL.TURNOFFETHER 2) (RPAQQ \DL.ENABLE.OUTPUT 1) (RPAQQ \DL.ENABLE.INPUT 1) (RPAQQ \DL.INPUT.ENABLED 1024) (RPAQQ \DL.OUTPUT.ENABLED 256) (CONSTANTS (\DL.ETHERINPUTREG 5) (\DL.ETHEROUTPUTREG 12) (\DL.ETHERSTATUSREG 1) (\DL.TURNOFFETHER 2) (\DL.ENABLE.OUTPUT 1) (\DL.ENABLE.INPUT 1) (\DL.INPUT.ENABLED 1024) (\DL.OUTPUT.ENABLED 256)) ) (RPAQQ ETHERSTATUSCONSTANTS ((\ES.PENDING 0) (\ES.GOOD.PACKET 1) (\ES.PACKET.TOO.LONG 2) (\ES.BAD.CRC 3) (\ES.BAD.CRC&ALIGNMENT 4) (\ES.BAD.ALIGNMENT 5) (\ES.OVERRUN 6) (\ES.TOO.MANY.COLLISIONS 7) (\ES.UNDERRUN 8) (\ES.LATE.COLLISION 9) (\ES.OTHER.ERROR 10))) (DECLARE: EVAL@COMPILE (RPAQQ \ES.PENDING 0) (RPAQQ \ES.GOOD.PACKET 1) (RPAQQ \ES.PACKET.TOO.LONG 2) (RPAQQ \ES.BAD.CRC 3) (RPAQQ \ES.BAD.CRC&ALIGNMENT 4) (RPAQQ \ES.BAD.ALIGNMENT 5) (RPAQQ \ES.OVERRUN 6) (RPAQQ \ES.TOO.MANY.COLLISIONS 7) (RPAQQ \ES.UNDERRUN 8) (RPAQQ \ES.LATE.COLLISION 9) (RPAQQ \ES.OTHER.ERROR 10) (CONSTANTS (\ES.PENDING 0) (\ES.GOOD.PACKET 1) (\ES.PACKET.TOO.LONG 2) (\ES.BAD.CRC 3) (\ES.BAD.CRC&ALIGNMENT 4) (\ES.BAD.ALIGNMENT 5) (\ES.OVERRUN 6) (\ES.TOO.MANY.COLLISIONS 7) (\ES.UNDERRUN 8) (\ES.LATE.COLLISION 9) (\ES.OTHER.ERROR 10)) ) (RPAQQ D0ETHERSTATUSCONSTANTS ((\D0.BAD.ALIGNMENT 2048) (\D0.INPUT.OVERRUN 1024) (\D0.INPUT.BAD.PACKET 512) (\D0.INPUT.BAD.CRC 256) (\D0.OUTPUT.UNDERRUN 64) (\D0.COLLISION 32) (\D0.OUTPUT.BAD.PARITY 128) (\D0.OUTPUT.FAULT 16) (\D0.GOOD.PACKET 16384) (\D0.PACKET.TOO.LONG 25088) (\D0.TOO.MANY.COLLISIONS 25600) (\D0.LATE.COLLISION 26112) (\D0.BUFFER.TOO.SHORT 26624))) (DECLARE: EVAL@COMPILE (RPAQQ \D0.BAD.ALIGNMENT 2048) (RPAQQ \D0.INPUT.OVERRUN 1024) (RPAQQ \D0.INPUT.BAD.PACKET 512) (RPAQQ \D0.INPUT.BAD.CRC 256) (RPAQQ \D0.OUTPUT.UNDERRUN 64) (RPAQQ \D0.COLLISION 32) (RPAQQ \D0.OUTPUT.BAD.PARITY 128) (RPAQQ \D0.OUTPUT.FAULT 16) (RPAQQ \D0.GOOD.PACKET 16384) (RPAQQ \D0.PACKET.TOO.LONG 25088) (RPAQQ \D0.TOO.MANY.COLLISIONS 25600) (RPAQQ \D0.LATE.COLLISION 26112) (RPAQQ \D0.BUFFER.TOO.SHORT 26624) (CONSTANTS (\D0.BAD.ALIGNMENT 2048) (\D0.INPUT.OVERRUN 1024) (\D0.INPUT.BAD.PACKET 512) (\D0.INPUT.BAD.CRC 256) (\D0.OUTPUT.UNDERRUN 64) (\D0.COLLISION 32) (\D0.OUTPUT.BAD.PARITY 128) (\D0.OUTPUT.FAULT 16) (\D0.GOOD.PACKET 16384) (\D0.PACKET.TOO.LONG 25088) (\D0.TOO.MANY.COLLISIONS 25600) (\D0.LATE.COLLISION 26112) (\D0.BUFFER.TOO.SHORT 26624)) ) (RPAQQ DLETHERSTATUSCONSTANTS ((\DL.COLLISION 64) (\DL.UNDERRUN 32) (\DL.BAD.ALIGNMENT 16) (\DL.OVERRUN 8) (\DL.BAD.CRC 4) (\DL.ODDLENGTH 2))) (DECLARE: EVAL@COMPILE (RPAQQ \DL.COLLISION 64) (RPAQQ \DL.UNDERRUN 32) (RPAQQ \DL.BAD.ALIGNMENT 16) (RPAQQ \DL.OVERRUN 8) (RPAQQ \DL.BAD.CRC 4) (RPAQQ \DL.ODDLENGTH 2) (CONSTANTS (\DL.COLLISION 64) (\DL.UNDERRUN 32) (\DL.BAD.ALIGNMENT 16) (\DL.OVERRUN 8) (\DL.BAD.CRC 4) (\DL.ODDLENGTH 2)) ) (DECLARE: EVAL@COMPILE (RPAQQ \MAXLLBUFFERPAGES 2) (RPAQQ \MINLLBUFFERPAGES 1) (RPAQQ \MAXIOCBS 64) (RPAQQ \10MB.MAX.INPUT.LENGTH 20) (CONSTANTS (\MAXLLBUFFERPAGES 2) (\MINLLBUFFERPAGES 1) (\MAXIOCBS 64) (\10MB.MAX.INPUT.LENGTH 20)) ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS \IOCB.INPUT.ALLOC \IOCB.INPUT.TOTAL \IOCB.OUTPUT.ALLOC \IOCB.OUTPUT.TOTAL \IOCBTOTAL \10MB.GETGARBAGE \10MB.RAWPACKETQ \10MB.IDEAL.INPUT.LENGTH \10MB.COLLECTSTATS \MACHINETYPE \10MBPACKETLENGTH \IOCBFREELIST) ) ) (* Misc) (DEFINEQ (\NOMACHINETYPE [LAMBDA NIL (* bvm: "24-JUL-82 17:47") (RAID "Operation not implemented on this machine"]) ) (DEFINEQ (IOCBQLENGTH [LAMBDA (FIRSTIOCB) (* bvm: " 2-MAR-83 17:52") (OR FIRSTIOCB (SETQ FIRSTIOCB \IOCBFREELIST)) (while FIRSTIOCB sum (PROGN (SETQ FIRSTIOCB (EMPOINTER (fetch D0NEXTIOCB of FIRSTIOCB))) 1]) ) (RPAQ? \10MB.GETGARBAGE NIL) (RPAQ? \10MB.COLLECTSTATS NIL) (* PUP address resolution) (DEFINEQ (\HANDLE.RAW.3TO10 [LAMBDA (PACKET TYPE) (* bvm: "15-Feb-85 21:11") (* Called when a TRANSLATION packet is received. This is either a packet requesting a 10-to-3 translation, in which case we respond if it is asking about us; or it is a response to a request of ours, in which case we store the info in the cache) (COND ((EQ TYPE \10MBTYPE.3TO10) (PROG ((NDB (fetch EPNETWORK of PACKET))) (AND XIPTRACEFLG (\MAYBEPRINTPACKET PACKET (QUOTE GET))) [SELECTC (fetch TRANSOPERATION of PACKET) [\TRANS.OP.REQUEST (COND ((EQ (fetch TRANSPUPHOST of PACKET) (fetch NDBPUPHOST# of NDB)) (* It's for us) (COND ((IGEQ (fetch 10MBLENGTH of PACKET) (IPLUS \10MBENCAPSULATION.WORDS (FOLDHI \TRANS.DATALENGTH BYTESPERWORD)) ) (* Add sender's address to cache) (\NOTE.3TO10 (fetch TRANSSENDERNSHOST of PACKET) (fetch TRANSSENDERPUPHOST of PACKET) NDB))) (replace TRANSNSHOST of PACKET with (\LOCALNSHOSTNUMBER) ) (* Add in the information he wants) (replace TRANSOPERATION of PACKET with \TRANS.OP.RESPONSE) (ENCAPSULATE.ETHERPACKET NDB PACKET (fetch TRANSSENDERNSHOST of PACKET) \TRANS.DATALENGTH \10MBTYPE.3TO10) (* Send back the response) (AND XIPTRACEFLG (NOT (MEMB (QUOTE TRANS) XIPIGNORETYPES)) (PRINT3TO10 PACKET (QUOTE PUT) XIPTRACEFILE)) (replace EPREQUEUE of PACKET with (QUOTE FREE)) (TRANSMIT.ETHERPACKET NDB PACKET) (RETURN] (\TRANS.OP.RESPONSE (* Add the information to the cache) (\NOTE.3TO10 (fetch TRANSNSHOST of PACKET) (fetch TRANSPUPHOST of PACKET) NDB)) (COND (XIPTRACEFLG (ERROR "Bad 3:10 operation" PACKET] (\RELEASE.ETHERPACKET PACKET)) T]) (\TRANSLATE.3TO10 [LAMBDA (PUPHOSTNUMBER NDB) (* bvm: "15-Feb-85 21:11") (* Translate from an PUPHOSTNUMBER to a NSHOSTNUMBER for the indicated network. If we don't have the translation, we initiate a probe for it and return NIL) (OR [CADR (ASSOC PUPHOSTNUMBER (ffetch NDBTRANSLATIONS of (\DTEST NDB (QUOTE NDB] (PROG ((MYPUPHOSTNUMBER (ffetch NDBPUPHOST# of NDB)) PACKET) (COND ((EQ MYPUPHOSTNUMBER 0) (* We don't know who we are yet) (RETURN))) (SETQ PACKET (\ALLOCATE.ETHERPACKET)) (replace EPTYPE of PACKET with \EPT.3TO10) (freplace TRANSOPERATION of PACKET with \TRANS.OP.REQUEST) (freplace TRANSPUPHOST of PACKET with PUPHOSTNUMBER) (freplace TRANSSENDERNSHOST of PACKET with (\LOCALNSHOSTNUMBER)) (freplace TRANSSENDERPUPHOST of PACKET with MYPUPHOSTNUMBER) (ENCAPSULATE.ETHERPACKET NDB PACKET BROADCASTNSHOSTNUMBER \TRANS.DATALENGTH \10MBTYPE.3TO10) (AND XIPTRACEFLG (\MAYBEPRINTPACKET PACKET (QUOTE PUT))) (freplace EPREQUEUE of PACKET with (QUOTE FREE)) (TRANSMIT.ETHERPACKET NDB PACKET) (* We didn't find out this time, but we will later on) (RETURN]) (PRINT3TO10 [LAMBDA (EPKT CALLER FILE PRE.NOTE DOFILTER) (* bvm: "14-Feb-85 21:21") (COND ((OR (NOT DOFILTER) (NOT (MEMB (QUOTE TRANS) XIPIGNORETYPES))) (OR FILE (SETQ FILE XIPTRACEFILE)) (FRESHLINE FILE) (COND (PRE.NOTE (PRIN1 PRE.NOTE FILE))) (SELECTC (fetch TRANSOPERATION of EPKT) (\TRANS.OP.REQUEST (printout FILE CALLER " 3:10 trans request for " (fetch TRANSPUPHOST of EPKT) " from " (fetch TRANSSENDERPUPHOST of EPKT) " = ") (PRINTNSHOSTNUMBER (fetch TRANSSENDERNSHOST of EPKT) FILE)) (\TRANS.OP.RESPONSE (printout FILE CALLER " 3:10 trans response: " (fetch TRANSPUPHOST of EPKT) " = ") (PRINTNSHOSTNUMBER (fetch TRANSNSHOST of EPKT) FILE)) (printout FILE CALLER " unknown 10 to 3 translation operation " (fetch TRANSOPERATION of EPKT))) (TERPRI FILE]) (\NOTE.3TO10 [LAMBDA (NSHOST PUPHOST NDB) (* bvm: "26-MAR-83 15:03") (* Update cache to include this pairing) (PROG [(A (ASSOC PUPHOST (ffetch NDBTRANSLATIONS of (\DTEST NDB (QUOTE NDB] (COND (A (RPLACA (CDR A) NSHOST)) (T (push (ffetch NDBTRANSLATIONS of NDB) (LIST PUPHOST NSHOST (CLOCK 0]) ) (RPAQ? \10MBTYPE.PUP 512) (RPAQ? \10MBTYPE.3TO10 513) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS \10MBTYPE.3TO10 \10MBTYPE.PUP) ) (DECLARE: EVAL@COMPILE (RPAQQ \EPT.3TO10 513) (CONSTANTS \EPT.3TO10) ) (ADDTOVAR \PACKET.PRINTERS (513 . PRINT3TO10)) (DECLARE: EVAL@COMPILE DONTCOPY (FILESLOAD (LOADCOMP) DOVEETHER LLETHER LLNS) ) (PUTPROPS 10MBDRIVER COPYRIGHT ("Xerox Corporation" 1982 1983 1984 1985)) (DECLARE: DONTCOPY (FILEMAP (NIL (2015 6106 (\10MBGETPACKET 2025 . 2348) (\10MBSENDPACKET 2350 . 4521) (\10MBENCAPSULATE 4523 . 5067) (\10MB.BROADCASTP 5069 . 5228) (\10MBWATCHER 5230 . 6104)) (6144 13443 (\10MB.STARTDRIVER 6154 . 7888) (\10MB.CREATENDB 7890 . 8478) (\10MB.INPUT.INTERRUPT 8480 . 12016) ( \10MB.OUTPUT.INTERRUPT 12018 . 13203) (\10MB.NOTESTAT 13205 . 13441)) (13835 19275 (\10MB.LOADINPUTQ 13845 . 14470) (\RELEASE.IOCB 14472 . 15275) (\GET.IOCB 15277 . 16357) (\INIT.ETHER.BUFFER.POOL 16359 . 19273)) (19342 34467 (\10MB.GETPACKETLENGTH 19352 . 19745) (\10MB.GETPACKETSTATUS 19747 . 22293) ( \QUEUE.INPUT.IOCB 22295 . 25484) (\QUEUE.OUTPUT.IOCB 25486 . 28470) (\10MB.TURNOFFETHER 28472 . 28770) (\10MB.TURNONETHER 28772 . 33780) (\10MB.RESTART.ETHER 33782 . 34465)) (46863 47046 (\NOMACHINETYPE 46873 . 47044)) (47047 47350 (IOCBQLENGTH 47057 . 47348)) (47456 52884 (\HANDLE.RAW.3TO10 47466 . 49887) (\TRANSLATE.3TO10 49889 . 51334) (PRINT3TO10 51336 . 52387) (\NOTE.3TO10 52389 . 52882))))) STOP