<> <> <> <> <> <> DIRECTORY DiskFace USING [Command, DeterminationMode, DeviceHandle, DontCare, Label, PageCount, PageNumber, Status, Tries, Type]; Disk: CEDAR DEFINITIONS = BEGIN PageNumber: TYPE = DiskFace.PageNumber; PageCount: TYPE = DiskFace.PageCount; Add: PROC [p: PageNumber, n: PageCount] RETURNS [PageNumber] = INLINE { <> RETURN[ [p+n] ] }; Channel: TYPE = LONG POINTER TO ChannelObject; ChannelObject: TYPE; NextChannel: PROC [prev: Channel, wait: BOOL _ FALSE] RETURNS [Channel]; <> InspectDiskShape: PROC [channel: Channel, mode: DiskFace.DeterminationMode] RETURNS [BOOL]; <> SameDrive: PROC [a, b: Channel] RETURNS [BOOL]; <> GetDeviceFromChannel: PROC [channel: Channel] RETURNS [DeviceHandle: DiskFace.DeviceHandle]; <> Valid: PROC [channel: Channel] RETURNS [BOOL]; <> DriveAttributes: PROC [channel: Channel] RETURNS [type: DiskFace.Type, ordinal: INT, ready: BOOL, nPages: PageCount]; <> Command: TYPE = DiskFace.Command; Label: TYPE = DiskFace.Label; Tries: TYPE = DiskFace.Tries; defaultTries: Tries = 24; Request: TYPE = RECORD[ diskPage: PageNumber, -- disk page number of first page of transfer -- data: LONG POINTER, -- first data page incrementDataPtr: BOOL _ TRUE, -- if TRUE, increment data pointer after each successful page. command: Command, tries: Tries _ defaultTries, count: PageCount, -- number of pages -- seek: PageNumber _ [0] -- optional address for initiating a seek after the transfer ]; Status: TYPE = RECORD[ SELECT type: * FROM changed => NULL, unchanged => [status: DiskFace.Status], ENDCASE ]; ok: Status = [unchanged[goodCompletion]]; -- transfer completed successfully labelCheck: Status = [unchanged[labelVerifyError]]; -- label verify was requested and failed notReady: Status = [unchanged[notReady]]; -- drive was not ready at some point in transfer invalid: Status = [changed[]]; -- drive's ChangeCount changed; no IO performed <> DoIO: UNSAFE PROC [channel: Channel, label: LONG POINTER TO Label, request: LONG POINTER TO Request] RETURNS [status: Status, countDone: PageCount]; GetBootChainLink: PROC [channel: Channel, diskPage: PageNumber] RETURNS [DiskFace.DontCare]; <> GetPageNumber: PROC [channel: Channel, link: DiskFace.DontCare] RETURNS [PageNumber]; Pulses: TYPE = LONG CARDINAL; GetStatistics: PROC RETURNS [active, total: Pulses, reads, writes, readPages, writePages: INT]; <<"active" and "total" are measured in fine-grain clock pulses (PrincOpsUtils.GetClockPulses[]). If [a1, t1] and [a2, t2] are results of successive calls of this procedure, then the fraction of time that the disk channel has had requests on a controller queue between the calls is given by (a2-a1)/(t2-t1).>> END.