Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Интерфейс GUID_DEVICE_RESET_INTERFACE_STANDARD определяет стандартный способ для функциональных драйверов попытаться сбросить и восстановить неисправное устройство.
С помощью этого интерфейса доступны два типа сброса устройства:
Сброс устройства на уровне функции. В этом случае операция сброса ограничена определенным устройством и не отображается другим устройствам. Устройство остается подключенным к шине во время сброса и возвращается в допустимое состояние (начальное состояние) после сброса. Этот тип сброса оказывает наименьшее влияние на систему.
Этот тип сброса можно реализовать либо драйвером шины, либо встроенным ПО ACPI. Драйвер шины может реализовать сброс на уровне функции, если спецификация шины определяет механизм сброса в полосе, соответствующий требованию. Встроенное ПО ACPI по желанию может переопределить сброс на уровне функции, определяемый драйвером шины, с помощью собственной реализации.
Сброс устройства на уровне платформы. В этом случае операция сброса приводит к тому, что устройство будет считаться отсутствующим на шине. Операция сброса влияет на определенное устройство и все остальные устройства, подключенные к нему через ту же линию питания или ту же линию сброса. Этот тип сброса оказывает наибольшее влияние на систему. Операционная система удаляет и перестраивает стеки всех затронутых устройств, чтобы убедиться, что все перезапускается с чистого листа.
Начиная с Windows 10, эти записи реестра в разделе HKLM\SYSTEM\CurrentControlSet\Control\Pnp
настраивают операцию сброса:
DeviceResetRetryInterval: период времени перед началом операции сброса. Значение по умолчанию — 3 секунды. Минимальное значение равно 100 миллисекундам; максимальное значение — 30 секунд.
DeviceResetMaximumRetries: максимальное количество попыток выполнения операции сброса.
Примечание.
Интерфейс GUID_DEVICE_RESET_INTERFACE_STANDARD доступен начиная с операционной системы Windows 10.
Использование интерфейса перезагрузки устройства
Если драйвер функции обнаруживает, что устройство работает неправильно, сначала необходимо выполнить сброс на уровне функции. Если сброс на уровне функции не исправляет проблему, драйвер может попытаться выполнить сброс на уровне платформы. Однако сброс на уровне платформы следует использовать только в качестве крайней меры.
Чтобы запросить этот интерфейс, драйвер устройства отправляет IRP_MN_QUERY_INTERFACE IRP вниз по стеку драйверов. Для этого пакета ввода-вывода (IRP) драйвер задает параметр типа интерфейса, равный GUID_DEVICE_RESET_INTERFACE_STANDARD. При успешном завершении IRP выходной параметр интерфейса является указателем на структуру DEVICE_RESET_INTERFACE_STANDARD. Эта структура содержит указатель на функцию DeviceReset, которая позволяет запросить сброс уровня функции или уровня платформы.
Поддержка интерфейса сброса устройства в функциональных драйверах
Для поддержки интерфейса сброса устройства стек устройств должен соответствовать следующим требованиям.
Драйвер функции должен правильно обрабатывать IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE и IRP_MN_SURPRISE_REMOVAL.
В большинстве случаев, когда драйвер получает IRP_MN_QUERY_REMOVE_DEVICE, он должен вернуть успешное выполнение, чтобы устройство можно было безопасно удалить. Однако могут возникнуть случаи, когда устройство не может быть безопасно остановлено, например, если устройство застряло в цикле записи в буфер памяти. В таких случаях драйвер должен вернуть STATUS_DEVICE_HUNG в IRP_MN_QUERY_REMOVE_DEVICE. Диспетчер PnP продолжает процесс IRP_MN_QUERY_REMOVE_DEVICE и IRP_MN_REMOVE_DEVICE, но этот конкретный стек не получит IRP_MN_REMOVE_DEVICE. Вместо этого стек устройств получит IRP_MN_SURPRISE_REMOVAL после сброса устройства.
Для получения дополнительной информации об этих IRP см. в статьях:
Обработка запроса IRP_MN_QUERY_REMOVE_DEVICE
Обработка запроса IRP_MN_REMOVE_DEVICE
Обработка запроса IRP_MN_SURPRISE_REMOVAL
Поддержка интерфейса сброса устройства в драйверах фильтров
Драйверы фильтров могут перехватывать IRP_MN_QUERY_INTERFACE IRP с типом интерфейса GUID_DEVICE_RESET_INTERFACE_STANDARD. Таким образом, они могут продолжать делегировать интерфейсу GUID_DEVICE_RESET_INTERFACE_STANDARD, но также выполнять специфические для устройства операции до или после операции сброса. В качестве альтернативы они могут переопределить интерфейс GUID_DEVICE_RESET_INTERFACE_STANDARD, который вернул драйвер шины, с помощью своего интерфейса, чтобы обеспечить собственную операцию сброса.
Поддержка интерфейса сброса устройства в драйверах шины
Водители шины, участвующие в процессе сброса устройства (т. е. водители шины, связанные с устройствами, которые запрашивают сброс, и водители шины, связанные с устройствами, которые отвечают на запрос сброса), должны соответствовать одному из следующих требований:
Поддержка возможности горячего подключения. Водитель автобуса должен быть в состоянии обнаружить устройство, которое удаляется из автобуса без уведомления, и устройство, подключаемое к автобусу.
В качестве альтернативы, он должен реализовать интерфейс GUID_REENUMERATE_SELF_INTERFACE_STANDARD. Это моделирует устройство, извлекаемое из шины и подключаемое обратно. Встроенные драйверы шины (например, PCI и SDBUS) поддерживают этот интерфейс. Таким образом, если для сброса устройства используется один из этих автобусов, изменения водителя автобуса не должны быть необходимы.
Для драйверов шины на основе WDF платформа WDF регистрирует интерфейс GUID_REENUMERATE_SELF_INTERFACE_STANDARD от имени драйверов. Поэтому регистрация этого интерфейса не требуется для этих драйверов. Если драйверу шины необходимо выполнить некоторые операции до повторного перечисления дочерних устройств, он должен зарегистрировать для подпрограммы обратного вызова EvtChildListDeviceReenumerated и выполнить эти операции в этой подпрограмме. Поскольку данная подпрограмма обратного вызова может вызываться параллельно для всех PDOs, код в подпрограмме необходимо защитить от условий гонки.
Прошивка ACPI: Функциональный сброс
Для поддержки сброса устройства на уровне функции в области устройства должен быть определен метод _RST. Если такой метод существует, он переопределяет реализацию сброса устройства на уровне функций, реализованную драйвером шины, если такая реализация присутствует для этого устройства. При выполнении метод _RST должен сбрасывать только это устройство и не должен влиять на другие устройства. Кроме того, устройство должно оставаться подключенным к шине.
Встроенное ПО ACPI: аппаратный сброс уровня системы
Для поддержки на уровне платформы сброса устройства существует два варианта:
Встроенное ПО ACPI может определить энергетический ресурс, реализующий метод _RST, и все устройства, затронутые этим методом сброса, могут ссылаться на этот энергетический ресурс через объект _PRR, определённый в контексте их устройств.
Устройство может объявить объект _PR3. В этом случае драйвер ACPI использует переключение питания D3cold для выполнения сброса, а зависимости сброса между устройствами определяются из объекта _PR3.
Если объект _PRR существует в контексте устройства, драйвер ACPI использует метод _RST в указанном PowerResource для выполнения сброса. Если объект _PRR не определен, но объект _PR3 определен, драйвер ACPI использует цикл питания D3cold для выполнения сброса. Если ни _PRR или _PR3 объект не определен, устройство не поддерживает сброс на уровне платформы, а драйвер ACPI сообщает, что сброс на уровне платформы недоступен.
Проверка встроенного ПО ACPI в тестовой системе
Чтобы протестировать драйвер, поддерживающий сброс устройства и восстановление, выполните следующую процедуру. В этой процедуре предполагается, что вы используете этот пример ASL-файла.
DefinitionBlock("SSDT.AML", "SSDT", 0x01, "XyzOEM", "TestTabl", 0x00001000)
{
Scope(\_SB_)
{
PowerResource(PWFR, 0x5, 0x0)
{
Method(_RST, 0x0, NotSerialized) { }
// Placeholder methods as power resources need _ON, _OFF, _STA.
Method(_STA, 0x0, NotSerialized)
{
Return(0xF)
}
Method(_ON_, 0x0, NotSerialized) { }
Method(_OFF, 0x0, NotSerialized) { }
} // PowerResource()
} // Scope (\_SB_)
// Assumes WiFi device is declared under \_SB.XYZ.
Scope(\_SB_.XYZ.WIFI)
{
// Declare PWFR as WiFi reset power rail
Name(_PRR, Package(One)
{
\_SB_.PWFR
})
} // Scope (\_SB)
}
- Скомпилируйте тестовый ASL-файл в AML с помощью компилятора ASL, например Asl.exe. Исполняемый файл входит в состав комплекта драйверов Windows (WDK).
Asl <test>.asl
Предыдущая команда создает SSDT.aml.
Переименуйте SSDT.aml в acpitabl.dat.
Скопируйте acpitabl.dat в %systemroot%\system32 в тестовой системе.
Включите проверку подписи в тестовой системе.
bcdedit /set testsigning on
Перезагрузите тестовую систему.
Убедитесь, что таблица загружена. В отладчике Windows используйте эти команды.
- !acpicache
- dt _DESCRIPTION_HEADER адрес таблицы SSDT
0: kd> !acpicache
Dumping cached ACPI tables...
SSDT @(ffffffffffd03018) Rev: 0x1 Len: 0x000043 TableID: TestTabl
XSDT @(ffffffffffd05018) Rev: 0x1 Len: 0x000114 TableID: HSW-FFRD
...
...
0: kd> dt _DESCRIPTION_HEADER ffffffffffd03018
ACPI!_DESCRIPTION_HEADER
+0x000 Signature : 0x54445353
+0x004 Length : 0x43
+0x008 Revision : 0x1 ''
+0x009 Checksum : 0x37 '7'
+0x00a OEMID : [6] "XyzOEM"
+0x010 OEMTableID : [8] "TestTabl"
+0x018 OEMRevision : 0x1000
+0x01c CreatorID : [4] "MSFT"
+0x020 CreatorRev : 0x5000000