<> <> <> DiskFace: CEDAR DEFINITIONS = BEGIN <<>> <> <<>> <<>> <> wordsPerPage: CARDINAL = 256; PageNumber: TYPE = RECORD[INT]; <> PageCount: TYPE = INT; <> ControllerHandle: TYPE[1]; GetNextController: PROC[ControllerHandle] RETURNS [ControllerHandle]; nullControllerHandle: READONLY ControllerHandle; GetControllerAttributes: PROC[ControllerHandle] RETURNS [globalStateSize: CARDINAL]; InitializeController: PROC[controller: ControllerHandle, globalState: LONG POINTER, mask: WORD]; <<"globalState" is in first 64K of VM. "mask" indicates naked notify channels>> InitializeCleanup: PROC[ControllerHandle]; Reset: PROC[ControllerHandle]; <> <> Type: TYPE = MACHINE DEPENDENT { null(0), sa800(1), sa1000(2), sa4000(3), cdc9730(4), ethernet(5), (LAST[CARDINAL]) }; DeviceHandle: TYPE[1]; nullDeviceHandle: READONLY DeviceHandle; GetNextDevice: PROC[DeviceHandle] RETURNS[DeviceHandle]; DeterminationMode: TYPE = { quickReadOnly, longReadOnly, writeEnabled }; DetermineDiskShape: PROC[device: DeviceHandle, operation: OperationPtr, mode: DeterminationMode, buffer: LONG POINTER _ NIL] RETURNS [nowKnown: BOOL]; GetDeviceType: PROC[DeviceHandle] RETURNS [Type]; GetDeviceAttributes: PROC[DeviceHandle] RETURNS [cylinders, movingHeads, fixedHeads, sectorsPerTrack: CARDINAL]; <> unknownAttribute: CARDINAL = LAST[CARDINAL]; Tries: TYPE = (0..400B]; <> SuggestedTries: PROC[DeviceHandle] RETURNS [Tries]; <> Recalibrate: PROC[DeviceHandle]; <> <> DiskAddress: TYPE = MACHINE DEPENDENT RECORD[ cylinder(0): CARDINAL, head(1:0..7): [0..256), sector(1:8..15): [0..256) ]; Command: TYPE = MACHINE DEPENDENT RECORD[header, label, data: Op]; Op: TYPE = MACHINE DEPENDENT { noOp, read, write, verify }; Label: TYPE = MACHINE DEPENDENT RECORD[ fileID(0): FileID, filePage(5): INT, attributes(7): Attributes, dontCare(8): DontCare ]; <> FileID: TYPE = MACHINE DEPENDENT RECORD[id(0): SELECT OVERLAID * FROM rel => [ relID(0): RelID, fill4(4): CARDINAL _ 0], abs => [ absID(0): AbsID ], ENDCASE ]; RelID: TYPE[4]; AbsID: TYPE[5]; Attributes: TYPE[1]; DontCare: TYPE[2]; <> DeviceOpStatus: TYPE[2]; <> <<>> operationSize: READONLY CARDINAL; <> OperationPtr: TYPE = LONG POINTER TO Operation; Operation: TYPE = MACHINE DEPENDENT RECORD[ -- 16-word aligned and in first 64K of VM clientHeader(0): DiskAddress, -- address of first sector of request labelPtr(2): LONG POINTER TO Label, -- first label of request. Must not be NIL. dataPtr(4): LONG POINTER, -- first (VM page aligned) data address of operation incrementDataPtr(6:0..0): BOOL, -- increment dataPtr after each successful data r/w/v unused(6:1..1): [0..1] _ NULL, command(6:2..7): Command, tries(6:8..15): Tries, -- indication of how hard to retry after errors pageCount(7): CARDINAL, -- number of (remaining) sectors for this operation deviceStatus(10B): DeviceOpStatus _ NULL, -- used by the Head diskHeader(12B): DiskAddress _ NULL, -- if command.header=read, places result here device(14B): DeviceHandle ]; Initiate: PROC[OperationPtr]; <> Poll: PROC[ControllerHandle] RETURNS [status: Status, op: OperationPtr, retriedCount: CARDINAL]; <> Status: TYPE = { inProgress, goodCompletion, notReady, recalibrateError, seekTimeout, headerCRCError, labelCRCError, dataCRCError, headerNotFound, labelVerifyError, dataVerifyError, overrunError, writeFault, memoryError, memoryFault, clientError, operationReset, otherError }; <> FormattingUnit: TYPE = {arbitrary, singleTrack}; GetFormattingUnit: PROC[DeviceHandle] RETURNS [FormattingUnit]; END.