-- 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