11.1.4 Setting Up AdapterControl and ControllerControl Routines
NT device drivers must set up associated NT objects for their AdapterControl and/or ControllerControl routines during initialization.
For an AdapterControl routine, the DriverEntry routine must do the following:
1.Set up the adapter object for the device’s DMA capabilities by filling in a DEVICE_DESCRIPTION structure and calling HalGetAdapter.
2.Save the AdapterObject pointer and NumberOfMapRegisters returned by HalGetAdapter.
The platform-specific maximum NumberOfMapRegisters returned by HalGetAdapter or the transfer capabilities of the driver’s device, whichever is more restrictive, determines whether the driver must split up a given transfer request and carry out more than one DMA operation on its device to satisfy that IRP.
The returned AdapterObject pointer, the entry point of the driver’s AdapterControl routine, the DeviceObject pointer representing the target device for the current IRP, a Context pointer to an area already set up for the AdapterControl routine, and a NumberOfMapRegisters value, which can be less than the maximum possible number for smaller transfer requests, must be passed in calls to IoAllocateAdapterChannel. Usually, a device driver’s StartIo (or possibly ControllerControl) routine sets up the area at Context before it calls IoAllocateAdapterChannel.
For a ControllerControl routine, the DriverEntry routine must do the following:
1.Call IoCreateController to set up the controller object, specifying the driver-determined Size for the controller extension, which the system allocates from nonpaged pool and initializes with zeros.
2.Save the ControllerObject pointer returned by IoCreateController, usually in the device extension(s) of each device object representing a physical or logical device that is controlled by the hardware represented by the controller object.
3.Set up and/or initialize the driver-determined contents of the ControllerObject->ControllerExtension.
The returned ControllerObject pointer, the entry point of the driver’s ControllerControl routine, the DeviceObject pointer representing the target device for the current IRP, and a Context pointer to an area already set up for the ControllerControl routine must be passed in the driver’s calls to IoAllocateController. Usually, a device driver’s StartIo routine sets up the area at Context before it calls IoAllocateController.