3.4  Controller Objects

As its name suggests, an NT controller object usually represents a physical device controller with attached devices. An NT device driver can use a controller object to synchronize I/O operations through a physical controller to or from attached physical devices of the same type like the “AT” disk driver already described in Chapter 2. Drivers of devices with I/O channels and a set of logical device objects also might use a controller object to synchronize their I/O operations between or among the channels of such a device.

Note that such attached devices or channels must be represented by named device objects as the targets for I/O requests, while the device controller is represented by a controller object that has no name.

Because a controller object has neither a name nor an associated file object, it is invisible to user-mode protected subsystems, which cannot make device I/O requests without getting a handle for the file object that represents the target device object. A controller object is also invisible to higher-level drivers, which cannot attach their own device objects to a controller object. In other words, neither the I/O Manager nor a higher-level driver can set up an IRP requesting I/O on a device represented by a controller object.

For more information about creating device objects, see Section 3.2.

Synchronization and Overlapped I/O

Monolithic NT drivers of physical devices with features like the “AT” disk controller (see Chapter 2) are not required to use a controller object to synchronize their device I/O operations. For example, a driver writer could try something like the following synchronization technique instead of using a controller object:

Set up named device objects to represent the devices that are targets for I/O requests. Maintain state (perhaps a set of DeviceBusy flags) about which device object is the target of the current I/O operation in each device extension or in a single device extension. Carry out I/O for the currently busy device object and requeue incoming IRPs for other device objects until the current IRP is completed.

The preceding synchronization technique serializes IRP processing for all of the driver’s target device objects. Note that it also forces such a driver to complete the current IRP before its StartIo routine can begin processing the next IRP, thereby decreasing driver performance.

If a device is such that certain operations can be overlapped, using a controller object can increase a driver’s I/O throughput, because this synchronization technique allows the driver to determine whether it can overlap operations just before it sets up the physical device. For example, a disk controller might allow the driver to overlap seeks on one disk with read/write operations on another disk.

Moreover, using a controller object is a relatively easy way to synchronize I/O operations for more than one target device object through a single physical device, such as an “AT” disk controller. Using a controller object allows a monolithic driver to synchronize I/O across a set of named device objects without having to maintain state about every device and the device controller in one or more device extensions and without having to requeue IRPs.

However, some devices that are designed to overlap I/O operations, such as full-duplex serial controllers or busmaster adapters, generally do have NT drivers that set up internal queues for IRPs.

For more information about setting up and managing internal queues, see Section 3.8, and see also Chapter 7.