<> <> <> <> DIRECTORY BufferDefs USING [BufferAccessHandle, defaultSystemBufferPoolSize, defaultSystemBuffersToReserve, FreeBufferPool, MakeBufferPool, systemAccessHandle], StatsDefs USING [StatIncr], CommUtilDefs USING [FriendOfCopyLong, LockCode, UnlockCode, SetDebuggingPointer], CommFlags USING [doDebug, doStats], DriverDefs USING [Glitch, GiantVector, GetPupRouter, GetOisRouter, GetWordsPerIocb, SetWordsPerIocb, CreateDefaultEthernetOneDrivers, CreateDefaultEthernetDrivers, Network, DispatcherOff, DispatcherOn, DispatcherImpl, BufferMgr], OISCP USING [], PupDefs USING [], SpecialCommunication USING [PhysicalMedium], NSAddress USING [NetworkNumber]; Boss: MONITOR IMPORTS BufferDefs, StatsDefs, CommUtilDefs, DriverDefs EXPORTS DriverDefs, OISCP, PupDefs, SpecialCommunication SHARES BufferDefs, DriverDefs = BEGIN OPEN CommUtilDefs, DriverDefs, NSAddress, SpecialCommunication; <> firstNetwork: PUBLIC Network _ NIL; giantVector: PUBLIC POINTER TO GiantVector _ @bigBoy; -- Debugging only bigBoy: GiantVector; increasedBufferUseCount, useCount: PUBLIC CARDINAL _ 0; state: {off, ready} _ off; -- on is ready with useCount>0 IocbNotBigEnough: PUBLIC ERROR = CODE; CommPackageNotActive: PUBLIC ERROR = CODE; NetworkNonExistent: PUBLIC ERROR = CODE; SystemBufferPoolConfused: PUBLIC ERROR = CODE; GetUseCount: PUBLIC PROCEDURE RETURNS [CARDINAL] = BEGIN RETURN[useCount]; END; GetDoStats: PUBLIC PROCEDURE RETURNS [BOOLEAN] = BEGIN RETURN[CommFlags.doStats]; END; GetGiantVector: PUBLIC PROCEDURE RETURNS [POINTER TO GiantVector] = BEGIN RETURN[giantVector]; END; <> AddDeviceToChain: PUBLIC PROCEDURE [network: Network, iocbSize: CARDINAL] = BEGIN <> tail: Network _ firstNetwork; i: CARDINAL _ 1; UNTIL (iocbSize MOD 4) = 0 DO iocbSize _ iocbSize + 1; ENDLOOP; IF state = off THEN SetWordsPerIocb[MAX[GetWordsPerIocb[], iocbSize]] ELSE IF iocbSize > GetWordsPerIocb[] THEN Glitch[IocbNotBigEnough]; IF state = ready THEN LockCode[network.interrupt]; IF useCount > 0 THEN BEGIN network.activateDriver[]; DriverDefs.GetPupRouter[].addNetwork[network]; DriverDefs.GetOisRouter[].addNetwork[network]; END; IF firstNetwork = NIL THEN BEGIN firstNetwork _ network; network.index _ 1; RETURN; END; UNTIL tail.next = NIL DO tail _ tail.next; i _ i + 1; ENDLOOP; tail.next _ network; network.index _ i + 1; END; RemoveDeviceFromChain: PUBLIC ENTRY PROCEDURE [network: Network] = BEGIN tail: Network _ firstNetwork; IF useCount > 0 THEN BEGIN DriverDefs.GetPupRouter[].removeNetwork[network]; DriverDefs.GetOisRouter[].removeNetwork[network]; network.deactivateDriver[]; END; IF state = ready THEN UnlockCode[network.interrupt]; IF firstNetwork = network THEN firstNetwork _ network.next ELSE BEGIN UNTIL tail.next = network DO tail _ tail.next; ENDLOOP; tail.next _ network.next; END; <> END; ChangeNumberOfInputBuffers: PUBLIC ENTRY PROCEDURE [ increaseTheBuffers: BOOLEAN] = BEGIN IF state # ready THEN Glitch[CommPackageNotActive]; IF increaseTheBuffers THEN BEGIN increasedBufferUseCount _ increasedBufferUseCount + 1; IF increasedBufferUseCount>1 THEN RETURN; END ELSE BEGIN IF increasedBufferUseCount=0 THEN RETURN; -- donot go negative increasedBufferUseCount _ increasedBufferUseCount - 1; IF increasedBufferUseCount#0 THEN RETURN; END; FOR net: Network _ firstNetwork, net.next UNTIL net = NIL DO IF net.changeNumberOfInputBuffers=NIL THEN LOOP; net.changeNumberOfInputBuffers[increaseTheBuffers]; ENDLOOP; END; GetDeviceChain: PUBLIC PROCEDURE RETURNS [Network] = BEGIN IF state # ready THEN Glitch[CommPackageNotActive]; RETURN[firstNetwork]; END; SmashDeviceChain: PUBLIC PROCEDURE = BEGIN firstNetwork _ NIL; END; <> <> <> SetNetworkID: PUBLIC ENTRY PROCEDURE [ physicalOrder: CARDINAL, medium: PhysicalMedium, newNetID: NetworkNumber] RETURNS [oldNetID: NetworkNumber] = BEGIN ENABLE UNWIND => NULL; net: Network; net _ GetNthDevice[physicalOrder, medium]; oldNetID _ net.netNumber; net.netNumber _ newNetID; DriverDefs.GetPupRouter[].stateChanged[net]; DriverDefs.GetOisRouter[].stateChanged[net]; END; <> <> GetNetworkID: PUBLIC ENTRY PROCEDURE [ physicalOrder: CARDINAL, medium: PhysicalMedium] RETURNS [NetworkNumber] = BEGIN ENABLE UNWIND => NULL; RETURN[GetNthDevice[physicalOrder, medium].netNumber]; END; <> <> GetNthDevice: PRIVATE PROCEDURE [ physicalOrder: CARDINAL, medium: PhysicalMedium] RETURNS [net: Network] = BEGIN i: CARDINAL _ 0; FOR net _ firstNetwork, net.next UNTIL net=NIL DO IF net.device = medium THEN IF (i _ i + 1) = physicalOrder THEN RETURN; ENDLOOP; ERROR NetworkNonExistent; END; <> OiscpPackageReady, PupPackageReady: PUBLIC ENTRY PROCEDURE = BEGIN CommPackageReady[]; END; CommPackageReady: INTERNAL PROCEDURE = BEGIN extra: CARDINAL _ 0; IF useCount = 0 AND firstNetwork = NIL THEN BEGIN [] _ CreateDefaultEthernetDrivers[]; [] _ CreateDefaultEthernetOneDrivers[]; END; IF state = ready THEN RETURN; <> IF CommFlags.doDebug THEN CommUtilDefs.SetDebuggingPointer[giantVector]; IF CommFlags.doStats THEN LockCode[StatsDefs.StatIncr]; LockCode[DriverDefs.DispatcherImpl]; LockCode[DriverDefs.BufferMgr]; LockCode[CommUtilDefs.FriendOfCopyLong]; FOR network: Network _ firstNetwork, network.next UNTIL network = NIL DO extra _ extra + network.buffers; ENDLOOP; IF BufferDefs.systemAccessHandle # NIL THEN Glitch[SystemBufferPoolConfused]; BufferDefs.systemAccessHandle _ BufferDefs.MakeBufferPool[ total: BufferDefs.defaultSystemBufferPoolSize + extra, reserve: BufferDefs.defaultSystemBuffersToReserve]; DispatcherOn[]; FOR network: Network _ firstNetwork, network.next UNTIL network = NIL DO LockCode[network.interrupt]; ENDLOOP; state _ ready; END; CommPackageGo: PUBLIC ENTRY PROCEDURE = BEGIN <> IF CommFlags.doDebug THEN CommUtilDefs.SetDebuggingPointer[giantVector]; CommPackageReady[]; IF (useCount _ useCount + 1) > 1 THEN RETURN; FOR network: Network _ firstNetwork, network.next UNTIL network = NIL DO network.activateDriver[]; ENDLOOP; END; CommPackageOff: PUBLIC ENTRY PROCEDURE = BEGIN IF (useCount _ useCount - 1) # 0 THEN RETURN; FOR network: Network _ firstNetwork, network.next UNTIL network = NIL DO network.deactivateDriver[]; UnlockCode[network.interrupt]; ENDLOOP; DispatcherOff[]; IF BufferDefs.systemAccessHandle = NIL THEN Glitch[SystemBufferPoolConfused]; BufferDefs.FreeBufferPool[BufferDefs.systemAccessHandle]; BufferDefs.systemAccessHandle _ NIL; IF CommFlags.doStats THEN UnlockCode[StatsDefs.StatIncr]; UnlockCode[CommUtilDefs.FriendOfCopyLong]; UnlockCode[DriverDefs.BufferMgr]; UnlockCode[DriverDefs.DispatcherImpl]; state _ off; END; <> IF CommFlags.doDebug THEN BEGIN CommUtilDefs.SetDebuggingPointer[giantVector]; giantVector.slaThings _ giantVector.prThings _ NIL; END; START DriverDefs.DispatcherImpl; START DriverDefs.BufferMgr; END.