Поделиться через


Пользователь отключает устройство

Во время работы системы пользователь может удалить устройство одним из двух способов: путем упорядоченного удаления, что означает, что пользователь сообщает системе о том, что устройство будет удалено (например, с помощью программы отмены установки или удаления оборудования); или неожиданным удалением, что означает, что пользователь отключает устройство без информирования системы. Если шина поддерживает неожиданное удаление (например, USB), драйверы устройства должны иметь возможность справляться с внезапным исчезновением устройства.

Аккуратное удаление

Пользователь запрашивает удаление, используя программу 'Отключение или извлечение оборудования', отключает устройство с помощью Диспетчера устройств или нажимает кнопку извлечения устройства. Платформа позволяет удалить или отключить устройство, если драйвер не имеет:

Для каждой функции и драйвера фильтра, поддерживающего устройство, платформа выполняет в последовательности один драйвер за раз, начиная с драйвера, который является самым высоким в стеке драйверов:

  1. Если драйвер использует автономный ввод-вывод, фреймворк вызывает функцию обратного вызова драйвера EvtDeviceSelfManagedIoSuspend.

  2. Платформа останавливает все очереди управляемых драйвером операций ввода-вывода.

  3. Если оборудование и драйвер поддерживают DMA, фреймворк вызывает функции обратного вызова EvtDmaEnablerSelfManagedIoStop, EvtDmaEnablerFlush и EvtDmaEnablerDisable (если они существуют) для каждого созданного канала DMA.

  4. Платформа вызывает функцию обратного вызова EvtDeviceD0ExitPreInterruptsDisabled (если она существует), а затем вызывает функцию обратного вызова EvtInterruptDisable драйвера (если она существует) для каждого прерывания, чтобы драйвер мог отключить прерывания устройства.

  5. Платформа вызывает функцию обратного вызова EvtDeviceD0Exit драйвера (если она существует).

  6. Платформа вызывает функцию обратного вызова EvtDeviceReleaseHardware драйвера (если она существует), передавая ему список аппаратных ресурсов, назначенных диспетчеру PnP устройству.

  7. Если драйвер использует самоуправляемый ввод-вывод, фреймворк вызывает функцию обратного вызова драйвера EvtDeviceSelfManagedIoFlush.

  8. Если драйвер использует самоуправляемый ввод-вывод, фреймворк вызывает функцию обратного вызова драйвера EvtDeviceSelfManagedIoCleanup.

Водитель автобуса – последний элемент в стеке. Когда фреймворк вызывает функцию обратного вызова драйвера шины EvtDeviceD0Exit, эта функция устанавливает состояние питания устройства (дочернего устройства шины) в D3. Драйвер шины может контролировать, когда фреймворк вызывает свою функцию обратного вызова EvtDeviceReleaseHardware, вызвав WdfDeviceInitSetReleaseHardwareOrderOnFailure.

Неожиданное удаление

Пользователь неожиданно отключает устройство. Драйвер шины устройства обнаруживает, что устройство отсутствует, и вызывает WdfChildListUpdateChildDescriptionAsMissing.

Для каждой функции и драйвера фильтра, поддерживающего устройство, платформа выполняет в последовательности один драйвер за раз, начиная с драйвера, который является самым высоким в стеке драйверов:

  1. Фреймворк вызывает функцию обратного вызова EvtDeviceSurpriseRemoval (если она существует).
  2. Если устройство находилось в рабочем состоянии (D0), когда оно было отключено:
    1. Платформа останавливает все очереди управляемых драйвером операций ввода-вывода.
    2. Если драйвер использует автономный ввод-вывод, фреймворк вызывает функцию обратного вызова драйвера EvtDeviceSelfManagedIoSuspend.
    3. Если оборудование и драйвер поддерживают DMA, фреймворк вызывает функции обратного вызова EvtDmaEnablerSelfManagedIoStop, EvtDmaEnablerFlush и EvtDmaEnablerDisable (если они существуют) для каждого созданного канала DMA.
    4. Платформа вызывает функции обратного вызова драйвера EvtDeviceD0ExitPreInterruptsDisabled и EvtInterruptDisable (если они существуют), чтобы драйвер мог отключить прерывания у устройства.
    5. Платформа вызывает функцию обратного вызова EvtDeviceD0Exit драйвера (если она существует).
  3. Платформа вызывает функцию обратного вызова EvtDeviceReleaseHardware драйвера (если она существует), передав список аппаратных ресурсов, назначенных диспетчеру PnP устройству.
  4. Если драйвер использует внутренне управляемый ввод-вывод, фреймворк вызывает функцию обратного вызова EvtDeviceSelfManagedIoFlush.
  5. Если драйвер использует самоуправляемый ввод-вывод, фреймворк вызывает функцию обратного вызова драйвера EvtDeviceSelfManagedIoCleanup.

Обратите внимание, что устройство может быть неожиданно удалено в любое время. Таким образом, платформа может вызывать функцию обратного вызова драйвера EvtDeviceSurpriseRemoval в другое время, отличное от указанного в предыдущих шагах. Например, если пользователь неожиданно отключает устройство во время перехода в состояние низкого энергопотребления, платформа может вызвать функцию обратного вызова EvtDeviceSurpriseRemoval после вызова функции обратного вызова EvtDeviceReleaseHardware. Не следует кодовать функцию обратного вызова EvtDeviceSurpriseRemoval , которая предполагает, что она и другие функции обратного вызова вызываются в определенной последовательности.

Кроме того, платформа не синхронизирует функцию обратного вызова EvtDeviceSurpriseRemoval с любой из функций обратного вызова, перечисленных в предыдущих шагах для этого устройства. Таким образом, функция обратного вызова EvtDeviceSurpriseRemoval может выполняться, а другая из ранее перечисленных функций обратного вызова также выполняется.