-- File: TedCold.mesa, Last Edit: -- MAS April 17, 1980 9:33 PM -- HGM August 3, 1980 7:34 PM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY CommUtilDefs: FROM "CommUtilDefs" USING [ DisableTimeout, SetTimeout, MsecToTicks, SetPriority, AddInterruptHandler, RemoveInterruptHandler, GetEthernetHostNumber, CleanupItem, CleanupReason, AllReasons, AddCleanupProcedure, RemoveCleanupProcedure], AltoEthernetDefs: FROM "AltoEthernetDefs", TedDefs: FROM "TedDefs", DriverDefs: FROM "DriverDefs" USING [ Glitch, GetInputBuffer, NetworkObject, AddDeviceToChain, PutOnGlobalDoneQueue], BufferDefs: FROM "BufferDefs", DriverTypes: FROM "DriverTypes"; TedCold: MONITOR LOCKS TedDefs.lock IMPORTS CommUtilDefs, DriverDefs, BufferDefs, AltoEthernetDefs, TedDefs EXPORTS DriverDefs, TedDefs SHARES BufferDefs, DriverTypes = BEGIN OPEN BufferDefs, DriverDefs, AltoEthernetDefs, TedDefs; lock: PUBLIC MONITORLOCK; timer: PUBLIC CONDITION; hardware: PUBLIC CONDITION; cleanupItem: CommUtilDefs.CleanupItem ← [,CommUtilDefs.AllReasons,Broom]; hardProcess: PROCESS; watcherProcess: PROCESS; myNetwork: PUBLIC DriverDefs.NetworkObject ← [ decapsulateBuffer: DecapsulateBuffer, encapsulatePup: EncapsulatePup, encapsulateRpp: EncapsulateRpp, sendBuffer: SendBuffer, forwardBuffer: NIL, activateDriver: ActivateDriver, deactivateDriver: DeactivateDriver, deleteDriver: DeleteDriver, interrupt: Interrupt, device: ethernet, alive: TRUE, speed: 3000, index: , netNumber: , hostNumber: , next: NIL, pupStats: NIL, stats: NIL ]; DriverNotActive: PUBLIC ERROR = CODE; DriverAlreadyActive: PUBLIC ERROR = CODE; NoEthernetBoard: PUBLIC ERROR = CODE; CantSwitchMachinesWhileEtherentDriverIsActive: PUBLIC ERROR = CODE; CantMakImageWhileEtherentDriverIsActive: PUBLIC ERROR = CODE; CreateDefaultEthernetDriver: PUBLIC PROCEDURE RETURNS [BOOLEAN] = BEGIN myDevice.postData ← EthernetNotPosted; StartIO[resetCommand]; StartIO[resetCommand]; -- sometimes it doesn't work IF myDevice.postData=EthernetNotPosted THEN RETURN[FALSE]; tedPleaseStop ← TRUE; myDevice.postData ← EthernetNotPosted; myNetwork.netNumber ← 0; AddDeviceToChain[@myNetwork,0]; RETURN[TRUE]; END; DeleteDriver: PROCEDURE = BEGIN END; ActivateDriver: PROCEDURE = BEGIN IF ~tedPleaseStop THEN Glitch[DriverAlreadyActive]; tedPleaseStop ← FALSE; StartIO[resetCommand]; StartIO[resetCommand]; -- sometimes it doesn't work IF myDevice.postData=EthernetNotPosted THEN Glitch[NoEthernetBoard]; QueueInitialize[@outputQueue]; currentInputBuffer ← nextInputBuffer ← currentOutputBuffer ← NIL; myNetwork.hostNumber ← CommUtilDefs.GetEthernetHostNumber[]; myDevice.hostNumber ← myNetwork.hostNumber; myDevice.inputBuffer ← [0,NIL0]; myDevice.outputBuffer ← [0,NIL0]; nextInputBuffer ← GetInputBuffer[]; currentInputBuffer ← GetInputBuffer[]; nextInputBuffer.device ← currentInputBuffer.device ← ethernet; nextBufferPointer ← ShortenData[ @nextInputBuffer.encapsulation+ethernetEncapsulationOffset]; nextBufferPointer↑ ← 0; -- show no input in yet myDevice.inputControlBlock ← NIL0; CommUtilDefs.AddCleanupProcedure[@cleanupItem]; CommUtilDefs.AddInterruptHandler[interruptLevel,@hardware,resetCommand]; CommUtilDefs.SetPriority[4]; hardProcess ← FORK Interrupt[]; CommUtilDefs.SetPriority[1]; -- The first interrupt will set things up. myDevice.interruptBit ← interruptBit; StartIO[resetCommand]; watcherProcess ← FORK Watcher[]; END; DeactivateDriver: PROCEDURE = BEGIN IF tedPleaseStop THEN Glitch[DriverNotActive]; tedPleaseStop ← TRUE; StartIO[resetCommand]; -- includes (naked)NOTIFY JOIN hardProcess; CommUtilDefs.RemoveCleanupProcedure[@cleanupItem]; myDevice.interruptBit ← 0; CommUtilDefs.RemoveInterruptHandler[interruptLevel]; StartIO[resetCommand]; KillDriverLocked[]; JOIN watcherProcess; IF currentInputBuffer#NIL THEN ReturnFreeBuffer[currentInputBuffer]; IF nextInputBuffer#NIL THEN ReturnFreeBuffer[nextInputBuffer]; IF currentOutputBuffer#NIL THEN PutOnGlobalDoneQueue[currentOutputBuffer]; QueueCleanup[@outputQueue]; myNetwork.netNumber ← 0; -- in case we turn it on after moving to another machine END; KillDriverLocked: ENTRY PROCEDURE = INLINE BEGIN NOTIFY timer; END; Broom: PROCEDURE [why: CommUtilDefs.CleanupReason] = BEGIN SELECT why FROM Finish, Abort, OutLd => myDevice.interruptBit ← 0; InLd => BEGIN IF myNetwork.hostNumber#CommUtilDefs.GetEthernetHostNumber[] THEN Glitch[CantSwitchMachinesWhileEtherentDriverIsActive]; myDevice.interruptBit ← interruptBit; END; Save, Checkpoint => Glitch[CantMakImageWhileEtherentDriverIsActive]; ENDCASE; StartIO[resetCommand]; END; --Note: This module must be the Control Module for a config that includes TedIn, TedLocked and TedOut. -- initialization START TedDefs.TedIn; START TedDefs.TedLocked; START TedDefs.TedOut; CommUtilDefs.DisableTimeout[@hardware]; CommUtilDefs.SetTimeout[@timer,CommUtilDefs.MsecToTicks[1000]]; END. -- TedCold