2.3. Device Power-Down and Removal
KMDF can remove a device from the operational state for several reasons:
To put the device in a low-power state because it is idle or the system is entering a sleep state.
To rebalance resources.
To remove the device after the user has requested an orderly removal.
To disable the device in response to the user’s request in Device Manager.
As in enumeration and power-up, the sequence of callbacks depends on the driver’s role in device management.
2.3.1. Power-Down and Removal Sequence for a Function or Filter Driver Object
The
following shows the sequence of callbacks that are involved in
power-down and removal for an FDO or filter DO. The sequence starts at
the top of the figure with an operational device that is in the working
power state (DO).
Device Operational
Suspend self-managed I/O, if driver supports it | EvtDeviceSelfManagedIoSuspend | Stop power-managed queues | EvtIoStop | Arm wake signal, if driver supports it | EvtDeviceArmWakeFromSx EvtDeviceArmWakeFromSO (called only during transitions to low power, not during resource rebalance or device removal) | Disable DMA, if driver supports it | EvtDmaEnablerSelfManagedIoStop
EvtDmaEnablerDisable
EvtDmaEnableFlush | Disconnect interrupts | EvtDeviceDOExitPreInterruptsDisabled EvtInterruptDisable | Notify driver of state change | EvtDeviceDOExit |
Stop here if transitioning to low-power state
Release hardware | EvtDeviceReleaseHardware |
Stop here if rebalancing resources
Purge power-managed queues | EvtIoStop | Flush I/O buffers, if driver supports self-managed I/O | EvtDeviceSelfManagedIoFlush | Purge non-power-managed queues | EvtIoStop | Clean up I/O buffers, if driver supports self-managed I/O | EvtDeviceSelfManagedIoCleanup | Delete device object’s context area | EvtCleanupContext
EvtDestroyContext |
Device Removed
|
As
the preceding example shows, the KMDF power-down and removal sequence
involves calling the corresponding “undo” callbacks in the reverse order
from which KMDF called the functions that are involved in making the
device operational.
2.3.2. Power-Down and Removal Sequence for a Physical Device Object
The following example shows the callbacks involved in power-down and removal for a PDO.
Device Operational
Enable
wake signal, if driver supports it (called only during transitions to
lower power, not during resource rebalance or device removal) | EvtDeviceEnableWakeAtBus | Suspend self-managed I/O, if driver supports it | EvtDeviceSelfManagedIoSuspend | Stop power-managed queues | EvtIoStop | Disable DMA, if driver supports it | EvtDmaEnablerSelfManagedIoStop
EvtDmaEnablerDisable
EvtDmaEnableFlush | Disconnect interrupts | EvtDeviceDOExitPreInterruptsDisabled EvtInterruptDisable | Notify driver of state change | EvtDeviceDOExit | Disable wake signal, if it is enabled | EvtDeviceDisableWakeAtBus (called only during device removal) |
Stop here if transitioning to low-power state
Release hardware | EvtDeviceReleaseHardware | Stop here if rebalancing resources | | Purge power-managed I/O queues | EvtIoStop | Flush I/O buffers, if driver supports | EvtDeviceSelfManagedIoFlush |
Stop here if device is still physically present
Purge non-power-managed I/O | EvtIoStop | Clean up I/O buffers, if driver supports self-managed I/O | EvtDeviceSelfManagedIoCleanup | Delete device object’s context area | EvtCleanupContext
EvtDestroyContext |
Device Physically Removed
|
KMDF
does not physically delete the PDO until the device is physically
removed from the system. For example, if a user disables the device in
Device Manager or uses the Safely Remove Hardware utility to stop the
device but does not physically remove it, KMDF retains the PDO. If the
device is later re-enabled, KMDF uses the EvtDevicePrepareHardware callback, as previously shown in section 7.2.2, “Startup Sequence for a Physical Device Object.”
2.3.3. Surprise-Removal Sequence
If the user removes the device without warning, by
simply unplugging it without using Device Manager or the Safely Remove
Hardware utility, the device is considered surprise removed.
When this occurs, KMDF follows a slightly different removal sequence.
It also follows the surprise-removal sequence if another driver calls IoInvalidateDeviceState on the device, even if the device is still physically present.
In the surprise-removal sequence, KMDF calls the EvtDeviceSurpriseRemoval
callback before calling any of the other callbacks in the removal
sequence. When the sequence is complete, KMDF destroys the device
object.
Drivers for all removable devices must ensure that
the callbacks in both the shutdown and startup paths can handle failure,
particularly failures caused by the removal of the hardware. Any
attempts to access the hardware should not wait indefinitely, but should
be subject to time-outs or a watchdog timer.
The following example shows the surprise-removal sequence.
Device Removal
Notify driver that device has been surprise removed | EvtDeviceSurpriseRemoval | Suspend self-managed I/O (called only if the device was in the working state at removal) | EvtDeviceSelfManagedIoSuspend | Stop power-managed queues (called only if the device was in the working state at removal) | EvtIoStop | Disable DMA, if driver supports it (called only if the device was in the working state at removal) | EvtDmaEnablerSelfManagedIoStop EvtDmaEnablerDisable EvtDmaEnablerFlush | Disconnect interrupts (called only if the device was in the working state at removal) | EvtDeviceDOExitPreInterruptsDisabled EvtInterruptDisable | Notify driver of state change (called only if the device was in the working state at removal) | EvtDeviceDOExit | Release hardware | EvtDeviceReleaseHardware | Purge power-managed queues | EvtIoStop | Flush and clean up I/O buffers, if driver supports self-managed I/O | EvtDeviceSelfManagedIoFlush | Purge non-power-managed queues | EvtIoStop | Clean up I/O buffers, if driver supports self-managed I/O | EvtDeviceSelfManagedIoCleanup | Delete device object’s context area | EvtCleanupContext
EvtDestroyContext |
Removal Processing Complete
|
If the device was not in the working state when it was removed, KMDF calls the EvtDeviceReleaseHardware event callback immediately after EvtDeviceSurpriseRemoval. It omits the intervening steps, which were already performed when the device exited from the working state.