Extended Device Driver Interface Specification

The Extended Device Driver interface supported in OS/2 2.1 is specifically targeted for service of hard disk devices. This interface can: The Extended Device Driver interface employs a Request List of prioritized commands the driver can reorder to optimize disk access, subject to prioritization requirements. The requests can also be grouped by the kernel for notification callout from the device driver. In addition, READ and WRITE operations use scatter/gather descriptors, which allow for data transfer to and from discontiguous data buffers. The interface is used asynchronously, removing the need for blocking in the physical device driver or the physical device driver manager when the I/O request itself is asynchronous.
 * Support submission of multiple asynchronous requests
 * Allow physically discontiguous data transfer areas
 * Support a new class of disk devices with advanced bus-mastering and intelligent transfer capabilities
 * Allow physical device drivers to optimally service large numbers of requests in a heavily loaded environment
 * Provide a mechanism and supporting semantics to support prioritization of request services

While the asynchronous, multi-request aspects of the interface contribute greatly to overall system performance on existing hardware, scatter and gather is specifically targeted for new classes of disk device hardware. This new class of devices supports transfer from disk to physically discontiguous memory space much more efficiently than alternative implementations.

The importance of this relative efficiency is amplified by the introduction of paging to the OS/2 operating system, where linearly contiguous memory normally maps to lists of discontiguous physical addresses. In addition, this interface is designed and optimized for server environments such as LAN Server 2.0, where file service paths are Ring 0 only and can execute at task or interrupt time. In such an environment, it must be possible to queue requests to the disk driver for service in the context of a network interrupt.

Extended physical disk device drivers refer to a superset of the standard OS/2 1.x physical disk device drivers. The term standard request is used to refer to the old style request packets format. The term extended request is used to refer to the new request packet format.

Disk Device Driver Architecture
Driver architecture centers around the need to provide fast, efficient services to a file system in a paged environment. In addition, consideration for the needs of a network file server has influenced aspects of the design; however, the requirements are identical in a local-only or workstation environment (that is, a direct, asynchronous, zero-overhead interface between the file system and the supporting physical disk device drivers).

In the OS/2 operating system, a physical disk device driver receives requests for service through a strategy routine at task time in the context of the requestor (an OS/2 thread). The thread of control is also obtained, in the context of interrupts generated by the disk controller, at the physical device driver interrupt routine. In the extended architecture, a second strategy routine is introduced, which can be called directly by File System Drivers (FSDs) at task time or in the context of an arbitrary interrupt. This yields a set of new requirements.

Standard OS/2 Strategy Routine
The standard OS/2 strategy routine is essentially unchanged in this architecture. Underlying queueing mechanisms used by the driver in the strategy routine are modified to support an environment where there are normally two kinds of requests in the queue, standard and extended.

Extended Strategy Routine
The extended strategy routine entry point can be called at interrupt or task time. At interrupt time, the driver can work only with physical addresses or global virtual addresses; therefore, only physical and global virtual addresses, which reference structures that are physically contiguous in memory, are used in this interface. Physical addresses are used for data transfer areas. Global virtual addresses are used for request packets, control structures, and entry points.

Much of the performance gain realized in this interface is dependent on the asynchronous processing of requests. The performance gain realized is degraded considerably if the driver blocks in the strategy routine, forcing the request to be synchronous. Therefore, while it is not required that the driver never block, it is very strongly recommended if performance is of interest in the system for which the driver is targeted. Additionally, if the driver has set the does-not-block bit in the DD_DriverCaps field returned from the GET DRIVER CAPABILITIES command, then the driver absolutely must not block in any code path accessible by the extended strategy routine entry point. Furthermore, it must not call any DevHlp routine that could block, effectively limiting the DevHlps that can be called to only those permissible at interrupt time. Among the DevHlps that could block are Lock and Unlock, so all buffers passed through the extended entry points are guaranteed to be locked.

The extended strategy routine is used only to pass requests in Request List form (see Request Lists and Request Control). The physical device driver queues the requests passed, services the controller as necessary, sets status fields in the requests, and returns.

Sorting and Priority
Requests should be sorted into internal queues based on physical disk location and I/O priority to optimize request servicing. Lower priority requests should be satisfied only where they do not significantly slow service of higher priority requests (for example, when a lower priority request refers to a sector in the same cylinder as a high priority request). Because the format of requests in Request Lists is different from the format of standard OS/2 requests, the queue management DevHlp routines cannot be used.

The queueing strategy adopted by the driver is highly dependent on the devices it services. In general, efficiency and request priority are the primary concerns in determining a queueing strategy. Lower priority requests should never slow service of higher priority requests. Lower priority requests can be serviced in the context of servicing higher priority requests, so long as no time-costly operations are necessary to service the lower priority requests. In addition, where contention for resources such as auxiliary, driver-allocated buffers or space on a controller buffer is an issue, higher priority requests should be given preference.

Request Management
The physical device driver needs to manage both requests submitted to the extended strategy routines with the Request List format and requests submitted to the standard strategy routine with the standard request packet format. Notice that the CommandCode field in the OS/2 standard request packet coincides with the CommandPrefix byte in the extended request packet, which is guaranteed to be the ExecuteChain prefix. This allows the driver to manage both requests on the same queue.

Removable Media
The physical device driver should support requests targeted for removable media in the same way it supports requests for nonremovable media.

Devices Not Capable of Scatter/Gather
Although this interface is clearly targeted for a disk device controller capable of scatter/gather, even devices that are not capable of scatter/gather still realize overall system performance gains as a result of supporting multi-request, asynchronous I/O, and interrupt-time execution. The driver is responsible for deciding how to emulate scatter/gather. In general, emulating scatter/gather to programmed I/O devices introduces no significant overhead.

However, if DMA devices, which do not support scatter/gather, attempt to emulate scatter/gather by mapping each scatter/gather descriptor in a single request to one DMA operation, performance will be poor. The driver is better off staging transfers through a pair of contiguous buffers. One buffer can be serviced by the controller while the other is being set up for subsequent operations. While there is overhead incurred in block-copying data through the staging buffer, this is no worse than the overhead the file system would incur in contiguous cache blocks before submission to a standard OS/2 device driver.

Identifying Extended Device Drivers and Capabilities
If the physical device driver is an extended device driver, it recognizes the GET DRIVER CAPABILITIES command. This command returns a characteristics bit field, which describes functional capabilities of the device driver, and an entry point vector, which includes the extended strategy routine and several device driver control routines. If the device driver does not recognize the command or does not respond appropriately, the kernel and all client FSD assume the physical device driver supports only standard OS/2 requests and restricts its behavior appropriately.

GET DRIVER CAPABILITIES Command
This command is structured as a standard OS/2 request packet. Note that the fields prefixed by DD_ are filled in by the physical device driver. (See the following table.) DD_CapStruct A 16:16 virtual pointer to the Driver Capabilities Structure. This pointer is filled in by the physical device driver. See Driver Capabilities Structure (DCS) for the format of this structure.

DD_VolCharStruct A 16:16 virtual pointer to the Volume Characteristics Structure (VCS) for this volume. This pointer is filled in by the physical device driver. See Volume Characteristics Structure (VCS) for the format of this structure.

Driver Capabilities Structure (DCS)
The Driver Capabilities Structure (DCS) is maintained by the physical device driver and is passed by reference to the kernel and client FSDs in the GET DRIVER CAPABILITIES command. The kernel and client FSDs must not modify the structure, as it is shared by FSDs and the physical device driver. A DCS has the following format: Bits 0-2 Reserved. Must be zero. Bit 3 If set, supports disk mirroring. Bit 4 If set, supports disk duplexing. Bit 5 If set, driver does not block in Strategy2. LAN Server and LAN Manager products using the HPFS 386 file system require that bit 5 be set to guarantee that the physical device driver does not block in Strategy2. Bits 6-31 Reserved. Must be zero.
 * DD_VerMajor:The major version number of the interface the physical device driver supports, equal to 01h in the first release. Old major versions do not function correctly with a file system using a newer version.
 * DD_VerMinor:The minor version number of the interface the physical device driver supports, equal to 01h in the first release. Old minor versions support a strict subset of the functionality found in newer versions.
 * DD_Capabilities:A bit field describing the capabilities of the physical device driver:
 * DD_Strategy2:The 16:16 entry point for the strategy routine that supports multi-request asynchronous I/O.
 * DD_SetFSDInfo:The 16:16 entry point for DD_SetFSDInfo. The value returned is 0:0, if the service is not provided by the physical device driver.
 * DD_ChgPriority:The 16:16 entry point for DD_ChgPriority. The value returned is 0:0, if the service is not provided by the physical device driver.
 * DD_SetRestPos:The 16:16 entry point for DD_SetRestPos. The value returned is 0:0, if the service is not provided by the physical device driver.
 * DD_GetBoundary:The 16:16 entry point for DD_GetBoundary. The value returned is 0:0, if the service is not provided by the physical device driver.

Volume Characteristics Structure (VCS)
The parameters passed in the Volume Characteristics Structure (VCS) are used by FSDs to optimize disk access and placement of file system structures on an advisory basis. All values reflect the physical parameters of the logical volume, as if it were a single physical device (that is, whether the media is partitioned or not). This data structure is passed by reference and is maintained and updated by the physical device driver, as necessary. It is expected that the physical device driver would maintain a separate VCS for each logical volume supported. A VCS has the following format:
 * VolDescriptor:A bit field, defined as follows:
 * Bit 0 If set, volume resides on removable media
 * Bit 1 If set, volume is read-only
 * Bit 2 If set, average seek time independent of position (RAM disk)
 * Bit 3 If set, outboard cache supported
 * Bit 4 If set, scatter/gather supported by adapter
 * Bit 5 If set, ReadPrefetch supported
 * Bits 6-15 Reserved, set to 0


 * AvgSeekTime:The average seek time (in milliseconds) in servicing this volume. If the seek time is unknown, FFFFH is to be specified. Can be 0 for RAM disks.
 * AvgLatency:The average rotational latency (in milliseconds) for the device servicing this volume. If the average latency is unknown, FFFFH is to be specified. Latency can be 0 for RAM disks.
 * TrackMinBlocks:The number of blocks available on the smallest capacity track; if unknown or not applicable, a value of 1 is specified.
 * TrackMaxBlocks:The number of blocks available on the largest capacity track ; if unknown or not applicable, a value of 1 is specified.
 * Heads Per Cylinder:The number of heads per cylinder; if unknown or not applicable, a value of 1 is specified.
 * VolCylinderCount:The number of cylinders in the volume; if unknown or not applicable, the number of allocation blocks (sectors) is used.
 * VolMedianBlock:The number of the block, which is in the center of the volume with respect to seek time (that is, the block with the smallest average seek time).
 * MaxSGList:The maximum number of scatter and gather list entries, which can be directly submitted to the adapter servicing this volume with one low- level I/O command. File systems submitting extended commands with scatter and gather lists greater than MaxSGList entries must ensure that the cumulative byte count of each MaxSGList entry in the list is a multiple of the sector size. This field is set to 0, if the volume is serviced by an adapter that does not directly support scatter/gather lists. See Scatter/Gather Descriptor for details on scatter/gather lists passed in extended requests.

Request Lists and Request Control
In order to support multi-request asynchronous I/O, a new request format has been defined, called Request Lists. This format allows multiple requests to be submitted in one call to the extended strategy routine, as well as grouping of those requests for notification purposes. In general, requests from any and all lists can be reordered and considered independently by the physical device driver for optimal throughput. Presently, only READ, WRITE, and READ PREFETCH commands have been defined in the new format.

Through Request Control flags, optional restrictions can be set on the requests to force sequential execution and to allow early termination of request processing, should any of the requests fail.

The notification mechanism allows the kernel and client file systems to receive callout notification when specific individual requests complete, when the entire request list completes, or both. In addition, notification can take place when an error condition occurs, when requests complete successfully, or both. Alternatively, no callout notification can be specified, allowing the system to poll for request completion during idle time.

Extended disk driver requests are submitted directly through the extended strategy routine entry point, DD_Strategy2, obtained through the GET DRIVER CAPABILITIES command and passed to client FSDs through FS_MOUNT. Requests are submitted in request list format, with ES:BX containing a global pointer to the Request List.

Each request in the list is an EXECUTE CHAIN command containing the EXECUTE CHAIN command prefix at the same offset into the extended request packet as the Command field in the standard request packet.

Request Lists have the following format: The Request List header has the following format: ES:BX 16:16 Address of Request List header CF Set, if an unrecoverable error has occurred The physical device driver is responsible for saving and restoring any registers that must survive the call.
 * ReqListCount:The number of requests in the Request List. Reserved Must be 0.
 * LstNotifyAddress:The 16:16 address of a notification routine to be called ( according to the flags in LstRequestControl) when all requests have been completed or terminated due to error conditions. LstNotifyAddress is not valid if bits 4 and 5 of LstRequestControl are clear. LstNotifyAddress is called with the following parameters:
 * LstRequestControl:A bit field of control flags as follows:
 * Bit 0 Reserved.
 * Bit 1 If set, there is only one request in the list. The same mechanism is used to submit one or many requests.
 * Bit 2 If set, requests are to be executed in sequence. Indicates that requests in this list must be executed in the order in which they appear in the Request List. They need not be executed adjacently; requests from other lists can interleave execution of this list.
 * Bit 3 If set, terminate on error. Indicates that, if an unrecoverable error occurs in processing any request in the list, outstanding requests in the list must not be executed. All Status, ErrorCode, and BlocksXferred fields must be updated, however.
 * Bit 4 If set, notify immediately on error only. Indicates that the request list notification routine, LstNotifyAddress, should be called immediately if an unrecoverable error occurs in servicing any of the requests in the Request List.
 * Bit 5 If set, notify on completion. Indicates that the request list notification routine should be called when execution of the requests has completed, regardless of error conditions.

If bit 4 and bit 5 are clear, the request list notification routine address is not valid. If bit 4 or bit 5 is set, the notification routine address is valid.
 * Bits 6-15 Reserved. Must be 0.


 * Block Device Unit:The logical unit number of the volume the requests are directed to. Note this forces all requests in the list to be addressed to the same block device unit.
 * LstStatus:Indicates the overall status for the Request List. This field should be set immediately by the physical device driver at strategy time and updated as requests complete successfully or unsuccessfully.
 * The low nibble indicates the completion status of the requests in the list, giving the LstStatus byte the following values:
 * X0h Indicates that no requests have been queued. It is guaranteed that the kernel will set this status on entry to the physical device driver. The physical device driver sets this status on return only if queueing was not possible due to exhausted driver-internal resources.
 * X1h Indicates that some requests have not yet been sorted into internal queues. That is, queueing is in process but has not yet been completed.
 * X2h Indicates that all requests in the list have been queued and are awaiting service.
 * X4h Indicates that all requests in the list have been completed successfully or unsuccessfully due to error conditions.
 * X8h Reserved.
 * The high nibble indicates the error status of the requests in the list, giving the LstStatus byte the following values:
 * 0Xh No error.
 * 1Xh Indicates that an error has occurred in processing at least one of the requests, but the physical device driver has successfully recovered the error through retries, ECC, disk mirroring, or duplexing.
 * 2Xh Indicates that an unrecoverable error has occurred in processing at least one of the requests.
 * 3Xh An unrecoverable error has occurred with retry.
 * 4Xh Reserved.
 * 8Xh Reserved.
 * Bits in the high nibble can be set in combination with bits in the low nibble to indicate the various error and completion states. LstStatus is guaranteed to be 0 when the request list is submitted to the physical device driver.

Each request has a fixed length header, followed by a variable length, command-specific area. The general format of an extended request is shown in the following table:
 * DDReserved:Reserved for device driver use in tracking request completion. Since the number of requests in the list is variable, this field might be used to point to an auxiliary structure maintained by the device driver.

Extended Commands
The following extended commands, and corresponding command codes, are defined for use in Request Lists:
 * 1Eh READ
 * 1Fh WRITE
 * 20h WRITE VERIFY
 * 21h READ PREFETCH

The format of the command-specific portion of the request packet format along with details of each command are described in the sections that follow.

Request Header
Each request in the Request List begins with a fixed length header, which has the following format:
 * Request:Length The offset of the next request. If this is the last request, the value is FFFFH.
 * Command Prefix:At the same offset in this request header as the command code in the standard OS/2 request header. This byte is always set to EXTENDED REQUEST (1Ch) to allow the physical device driver to maintain one queue for both standard and extended requests, while distinguishing the two packet types.
 * Command Code:The request command code. Can have any of the values defined in Extended Commands.
 * Header Offset:The offset from the beginning of the Request List header to the header of this request. This field, when subtracted from the address of the header of this request, yields the header of the list. This provides fast access to the control information in the header.
 * Request Control:A bit field of control flags as follows:
 * Bits 0-3 Reserved. Must be 0.
 * Bit 4 If set, notify on error only. Indicates that the individual request notification routine, NotifyAddress, should be called immediately in the event that an unrecoverable error occurs in servicing the request.
 * Bit 5 If set, notify on completion. Indicates that the individual notification routine, NotifyAddress, should be called when execution of the request has completed successfully and possibly with a recoverable error. This bit does not indicate notification in the case of an unrecoverable error.
 * If bit 4 and bit 5 are clear, the individual request notification routine address is not valid. If bit 4 or bit 5 is set, the notification routine address is valid. Bits 4 and 5 can both be set to indicate notification in case of error or successful completion.
 * Bits 6-7 Reserved. Must be 0.


 * Priority:A bit field indicating the priority of the request. The following values are currently defined, and others may be added as needed, without notice:
 * 00h Prefetch Requests.
 * 01h Low priority request to be satisfied in the context of servicing other, higher priority requests or when no other work exists (lazy-write).
 * 02h Read ahead, low priority pager I/O.
 * 04h Background synchronous user I/O. 08h Foreground synchronous user I/O.
 * 10h High priority pager I/O.
 * 80h Urgent request; all requests at this priority should be satisfied in a single sweep of the disk; no stopping allowed at cylinders other than those necessary to satisfy requests in this priority. The kernel uses this priority in cases such as an impending power failure or shutdown.
 * The kernel or client FSD can request a priority change after the initial submission of the request to the physical device driver by issuing a call to DD _ChgPriority.


 * Status:A bit field indicating the status of the request. The low nibble indicates the completion status of the request, giving the Status byte the following values:
 * X0h Not yet queued
 * X1h Queued and waiting
 * X2h In process
 * X4h Done
 * X8h Reserved
 * The high nibble indicates the error status of the request, giving the Status byte the following values:
 * 0Xh No error
 * 1Xh A recoverable error has occurred
 * 2Xh An unrecoverable error has occurred
 * 3Xh An unrecoverable error has occurred
 * 4Xh The request was abnormally ended
 * 8Xh Reserved
 * High and low nibbles can be set in combination by the physical device driver to indicate combinations of error and status conditions. For example, a code of 12h indicates that a recoverable error has occurred and the request is still in progress. An error condition indicates a valid error code in the ErrorCode field. Status is guaranteed to be 00h when the request is submitted.


 * Error Code:Contains a valid error condition, if an error status is indicated in Status. The following error codes are possible if the error is unrecoverable and are compatible with previous OS/2 error returns:
 * 00h Write-protect violation
 * 01h Unknown unit
 * 02h Device not ready
 * 03h Unknown command
 * 04h CRC error
 * 06h Seek error
 * 07h Unknown media
 * 08h Block not found
 * 0Ah Write fault
 * 0Bh Read fault
 * 0Ch General failure
 * 10h Uncertain media
 * 13h Invalid parameter
 * The following error codes are possible, if the error is recoverable:
 * 1Ah Verify error on write, succeeded after retry
 * 2Ah Write error, write to mirrored or duplexed drive succeeded
 * 3Ah Write error on mirrored or duplexed drive; write to primary drive succeeded
 * 1Bh Read error, corrected using ECC
 * 2Bh Read succeeded after retry
 * 3Bh Read error, recovered from mirrored or duplexed drive


 * NotifyAddress:The address of a notification routine to be called (according to the flags in RequestControl) when the request has completed successfully or unsuccessfully due to error conditions. NotifyAddress is not valid if bits 4 and 5 of RequestControl are clear. NotifyAddress is called with the following parameters:
 * ES:BX 16:16 Address of the request header
 * CF Set, if an unrecoverable error has occurred.
 * The physical device driver is responsible for saving and restoring any registers that must survive the call.


 * Hint Pointer:A 16:16 pointer to a request packet in a Request List. This field can be used when the kernel or the client FSD determines that this request might be best grouped with another request it has already submitted to the physical device driver. The request might have already completed, so the physical device driver must validate that the pointer points to a request on its internal queues. This field is FFFF:FFFFH if it is unused (that is, if a hint is not being passed).
 * DDReserved:Fields reserved for device driver use.

Write/Read/WriteVerify
The format of the request packet for the WRITE, READ, and WRITE VERIFY commands is:
 * Request:Header The fixed length request header.
 * Start Block:The starting disk block for the data transfer operation. A disk block is defined as a 512-byte logical disk sector.
 * Block Count:The number of 512-byte blocks to be transferred.
 * BlocksXferred:The number of 512-byte blocks successfully transferred by the driver. This field is updated before the request and request list notification routines are called and before the Status field is marked as Done.
 * Flags:A bit field of command-specific control flags. The following flags have been defined:
 * Bit 0 If set, write through. Defeats any lazy-write caching performed by the physical device driver. Notice that lazy-write, through battery-backed RAM, is permitted, even if this bit is set.
 * Bit 1 If set, cache request on outboard controller cache.
 * Bits 2-15 Reserved, set to 0.

The File System Driver (FSD) guarantees the following to be true: BlockCount * 512 equals the sum of the BufferSize fields in SGDescriptors. In addition, buffers are typically DWORD aligned. The physical device driver should be optimized for this case, but should not rely upon it.
 * SGDescrCount:The number of scatter/gather descriptors in the SGDescriptors field.
 * SGDescriptors:An array of scatter/gather descriptors describing the buffers for data transfer specified by the command.

Scatter/Gather Descriptor
READ and WRITE operations use an array of scatter/gather descriptors to describe the buffer space to be used in the operation. This enables transfers of contiguous disk blocks into physically discontiguous, byte-aligned memory blocks. Scatter/gather descriptors have the following format:
 * BufferPtr:A 32-bit physical pointer to the buffer
 * Buffer Size:Size of the buffer in bytes

READ PREFETCH
READ PREFETCH is defined to take advantage of a two-tiered disk caching scheme, where the first tier is the file system and the second tier is the controller buffer. This command is optionally supported, if the Read Prefetch bit is set in the VolDescriptor bit field of the VCS for the device. If this bit is set, it is assumed that: If both of these conditions are not met, then the physical device driver does not publish READ PREFETCH capabilities because it is more efficient for the file system to perform read-ahead into its own cache. READ PREFETCH commands are the lowest priority requests submitted to the physical device driver through the extended strategy routine and are never serviced prior to other Read/Write requests.
 * The physical device driver manages a cache located on the controller.
 * A Read into controller memory, followed by a Read into system memory, is less expensive (in terms of host CPU utilization) than just a Read into system memory.

The format of the request packet for READ PREFETCH is:
 * Request:Header The fixed length request header.
 * Start Block:The starting disk block for the data prefetch operation. A disk block is defined as a 512-byte logical disk sector.
 * Block Count:The number of 512-byte blocks to be prefetched.
 * BlocksXferred:The number of 512-byte blocks successfully prefetched by the physical device driver. This field is updated before the request and request list notification routines are called and before the Status field is marked as Done.
 * Flags:A bit field of command-specific control flags. The following flags have been defined:
 * Bit 0 If set, hold only until read. The physical device driver retains the data in controller prefetch buffers only until it is read once. This is to prevent redundant caching in the controller.
 * Bits 1-15 Reserved, set to 0.

Request Control Functions
Request control functions are used by the FSD to manage requests after they have been submitted to obtain advisory information from the physical device driver and to pass advisory information to the physical device driver. Entry points are exported by the physical device driver through the GET DRIVER CAPABILITIES command. Request control functions can be called at interrupt time and cannot block. Request control functions need only preserve segment registers.

The following request control functions are defined:
 * DD_SetFSDInfo
 * DD_ChgPriority
 * DD_SetRestPos
 * DD_GetBoundary

DD_SetFSDInfo
This entry point allows the FSD to inform the physical disk device driver of its FSD_EndOfInt and FSD_AccValidate entry points. The physical disk device driver allows DD_SetFSDInfo to be called exactly once, and ignores subsequent calls. ENTRY ES:BX  16:16 pointer to the FSDInfo structure. EXIT CF     Set, if call was ignored. The format of the FSDInfo structure is:
 * FSD_EndOfInt:The 16:16 entry point of the FSD's FSD_EndOfInt routine. This field is set to 0 if the FSD does not provide an FSD_EndofInt routine. The entry point is called by the physical device driver when it has completed interrupt processing and after it has called DevHlp_EOI. FSD_EndOfInt takes no parameters and leaves all registers intact.
 * FSD_AccValidate:The 16:16 entry point of the FSD's FSD_AccValidate routine. This field is set to 0 if the FSD does not provide an FSD_AccValidate routine. The entry point is called whenever direct I/O is done through a Category 08h or 09h IOCtl to an HPFS volume or whenever direct I/O is done to the Master Startup (Boot) record through a Category 09h IOCtl.
 * For Category 09h IOCtls, the physical device driver must use the Head, Cylinder, and Sector values passed in the IOCtl. These values are used to determine whether the I/O request falls within an HPFS volume, because the unit number in the IOCtl represents the entire physical disk and not the logical volume.
 * The physical device driver should call FSD_AccValidate with:

AL Operation Code 00 Non-destructive (READ, VERIFY) 01 Destructive (WRITE, FORMAT TRACK, and so forth)
 * }
 * On return from the FSD:

NC I/O access is allowed. CF If set, access is denied. The physical device driver should return error code 00h (Write-protection violation) to the caller.
 * }

DD_ChgPriority
This entry point allows the FSD to notify the physical device driver of a possible change in the priority of a request. HPFS calls this entry point with: ENTRY ES:BX Address of the request AL    New priority for the request; EXIT CF    Set, if request packet not found on any of the physical device driver's internal queues This call is used to change the priority of a previously submitted request. The physical device driver performs whatever resorting of internal queues is necessary, and returns. The FSD guarantees that the pointer that was passed references a valid request (that is, a request with allowed values in all fields). There is no guarantee that the priority of the request has actually been changed or that the request is still on the internal queues of the driver. If the request has been removed from internal queues, has already been incorporated into internal structures in preparation for service, or has already been serviced, the physical device driver can ignore the requested change.

DD_SetRestPos
This entry point advises the physical device driver of a block to seek when there is no work in the queue. No immediate action is necessary when the call is made. This call is purely advisory and can be ignored by the driver if it is not useful or applicable to the hardware it supports. ENTRY AX:BX  Block to use as resting point, FFFF:FFFFH, if none CL  Logical Unit Number (A:=0)

EXIT CF     Set, if block is out of range. The physical device driver updates a static variable, specifying where to rest the heads during idle time. When any seek occurs, either as a result of this call or as the result of I/O requests, the variable is set to FFFFFFFFH. A value of FFFFFFFFH indicates rest-where-you-end-up.

This call essentially assumes that there is only one active logical volume serviced by the underlying physical device. Physical device, in this context, means mechanical, usually multi-headed, disk arm. If this is not the case, this call should be ignored by the driver.

DD_GetBoundary
This entry point returns the first block number that is greater than the block number specified in the DWORD passed and is past an access time boundary, such as a cylinder. This information can be used by file systems to optimally place file system objects. ENTRY AX:BX  Reference block number

EXIT AX:BX  Number of first block past access time boundary CF     Set, if block number out of range. If the physical device driver cannot compute this efficiently, it can precompute this information and retain it internally, or if this is not feasible, it can return (AX:BX) + 1.