Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Aby zapewnić właściwe zarządzanie przejściami zasilania, IRP-y zasilania muszą być przekazywane przez cały stos urządzeń do PDO. Sterowniki obsługują protokół IRP, który zmniejsza moc urządzenia, ponieważ protokół IRP przechodzi w dół stosu urządzenia. Sterowniki obsługują IRP, który stosuje zasilanie urządzenia w procedurach IoCompletion, gdy IRP przemieszcza się z powrotem w górę stosu urządzenia.
Na poniższej ilustracji przedstawiono kroki, które sterowniki muszą wykonać, aby przekazać protokół IRP zasilania w stos urządzenia w systemach Windows 7 i Windows Vista.
Jak pokazano na poprzedniej ilustracji, w systemach Windows 7 i Windows Vista sterownik musi wykonać następujące czynności:
Wywołaj metodę IoCopyCurrentIrpStackLocationToNext, jeśli ustawiasz procedurę IoCompletion, lub IoSkipCurrentIrpStackLocation, jeśli nie ustawiasz procedury IoCompletion.
Te dwie procedury ustawiają lokalizację stosu IRP dla następnego niższego sterownika. Skopiowanie bieżącej lokalizacji stosu umożliwia, że wskaźnik stosu IRP jest ustawiony na poprawną lokalizację, gdy procedura IoCompletion działa.
Jeśli źle napisany sterownik popełnia błąd podczas wywoływania elementu IoSkipCurrentIrpStackLocation , a następnie ustawiania procedury uzupełniania, ten sterownik może zastąpić procedurę uzupełniania ustawioną przez sterownik poniżej.
Wywołaj metodę IoSetCompletionRoutine , aby ustawić procedurę IoCompletion , jeśli wymagana jest pełna procedura.
Wywołaj metodę IoCallDriver , aby przekazać protokół IRP do następnego niższego sterownika w stosie.
Na poniższej ilustracji przedstawiono kroki, które sterowniki muszą podjąć, aby przekazać żądanie mocy IRP przez stos urządzeń w systemach Windows Server 2003, Windows XP i Windows 2000.
Jak pokazano na poprzedniej ilustracji, sterownik musi wykonać następujące czynności:
W zależności od typu sterownika, prawdopodobnie wywołaj metodę PoStartNextPowerIrp. Aby uzyskać więcej informacji, zobacz Wywoływanie PoStartNextPowerIrp.
Wywołaj IoCopyCurrentIrpStackLocationToNext, jeśli ustawiasz procedurę IoCompletion, lub IoSkipCurrentIrpStackLocation, jeśli nie ustawiasz procedury IoCompletion.
Te dwie procedury ustawiają lokalizację stosu IRP dla następnego niższego sterownika. Skopiowanie bieżącej lokalizacji stosu zapewnia, że wskaźnik stosu IRP jest ustawiony na poprawną lokalizację w momencie, gdy procedura IoCompletion jest uruchamiana.
Wywołaj metodę IoSetCompletionRoutine , aby ustawić procedurę IoCompletion . W procedurze IoCompletion większość sterowników wywołuje metodę PoStartNextPowerIrp , aby wskazać, że jest gotowa do obsługi następnej mocy IRP.
Wywołaj PoCallDriver, aby przekazać IRP do następnego niższego sterownika w stosie.
Sterowniki muszą używać PoCallDriver zamiast IoCallDriver (podobnie jak w przypadku innych IRP), aby system prawidłowo synchronizował zasilanie IRP. Aby uzyskać więcej informacji, zobacz Calling IoCallDriver vs. Calling PoCallDriver.
Pamiętaj, że procedury IoCompletion można wywołać na IRQL = DISPATCH_LEVEL. W związku z tym, jeśli sterownik wymaga dodatkowego przetwarzania na poziomie IRQL = PASSIVE_LEVEL po tym, jak sterowniki niższego poziomu zakończą pracę z IRP, procedura uzupełniania sterownika powinna umieścić element roboczy w kolejce, a następnie zwrócić STATUS_MORE_PROCESSING_REQUIRED. Wątek procesu roboczego musi zakończyć proces IRP.
W systemie Windows 98/Me sterowniki muszą ukończyć IRP-y zasilania na poziomie IRQL = PASSIVE_LEVEL.
Nie zmieniaj kodów funkcji w Power IRP
Oprócz zwykłych reguł, które zarządzają przetwarzaniem IRP, IRP_MJ_POWER IRP mają następujące specjalne wymaganie: Sterownik, który odbiera IRP zasilania, nie może zmienić głównych i pomocniczych kodów funkcji w żadnych lokalizacjach stosu I/O w IRP, które zostały ustawione przez menedżera zasilania lub sterowników wyższego poziomu. Menedżer zasilania opiera się na tych kodach funkcji pozostającymi niezmienionymi do momentu zakończenia IRP. Naruszenia tej reguły mogą powodować problemy, które są trudne do debugowania. Na przykład system operacyjny może przestać odpowiadać lub "zawieszać się".
Nie blokuj podczas obsługi IRP zasilania
Sterowniki nie mogą powodować długich opóźnień podczas obsługi IRP związanych z zarządzaniem energią.
Podczas przekazywania zasilania IRP sterownik powinien wrócić z procedury DispatchPower tak szybko, jak to możliwe po wywołaniu IoCallDriver (w systemach Windows 7 i Windows Vista) lub PoCallDriver (w systemie Windows Server 2003, Windows XP i Windows 2000). Kierowca nie powinien czekać na zdarzenie jądra ani w inny sposób zwlekać, zanim wróci. Jeśli sterownik nie może obsłużyć żądania zasilania IRP w krótkim czasie, powinien zwrócić STATUS_PENDING i kolejkować wszystkie przychodzące IRP do momentu ukończenia żądania zasilania IRP. (Należy pamiętać, że to zachowanie różni się od procedur PnP IRPs i DispatchPnP , które mogą być blokowane).
Jeśli sterownik musi poczekać na działanie zasilania przez inny sterownik dalej w stosie urządzenia, powinien zwrócić STATUS_PENDING z procedury DispatchPower i ustawić procedurę IoCompletion dla protokołu IRP zasilania. Sterownik może wykonywać wszystkie zadania wymagane w procedurze IoCompletion , a następnie wywołać polecenie PoStartNextPowerIrp (Windows Server 2003, Windows XP i Windows 2000 tylko) i IoCompleteRequest.
Na przykład właściciel zasad zasilania urządzenia zwykle wysyła IRP zasilania urządzenia przy zachowaniu protokołu IRP zasilania systemu w celu ustawienia stanu zasilania urządzenia odpowiedniego dla żądanego stanu zasilania systemu.
W takiej sytuacji właściciel zasad zasilania powinien ustawić procedurę IoCompletion w IRP zasilania systemu, przekazać IRP zasilania systemu do następnego niższego sterownika i zwrócić STATUS_PENDING z procedury DispatchPower .
W procedurze IoCompletion wywołuje metodę PoRequestPowerIrp w celu wysłania protokołu IRP zasilania urządzenia, przekazując wskaźnik do procedury wywołania zwrotnego w żądaniu. Rutyna IoCompletion powinna zwrócić STATUS_MORE_PROCESSING_REQUIRED.
Na koniec sterownik przekazuje dalej systemowy IRP z procedury wywołania zwrotnego. Sterownik nie może czekać na zdarzenie jądra w swojej procedurze DispatchPower i sygnalizować procedurą IoCompletion dla IRP, który jest obecnie obsługiwany; może wystąpić zakleszczenie systemu. Aby uzyskać więcej informacji, zobacz Obsługa protokołu systemowego IRP Set-Power u właściciela zasad zasilania urządzenia.
W podobnej sytuacji, gdy system przejdzie w stan uśpienia, właściciel zasad zasilania może wymagać ukończenia niektórych oczekujących operacji we/wy, zanim wyśle urządzenie IRP do zasilania urządzenia. Zamiast sygnalizować zdarzenie, gdy operacja wejścia/wyjścia zostanie zakończona i czekać w rutynie DispatchPower, sterownik powinien ustawić w kolejce element roboczy i zwrócić STATUS_PENDING z rutyny DispatchPower. W wątku procesu roboczego oczekuje na zakończenie operacji we/wy, a następnie wysyła protokół IRP zasilania urządzenia. Aby uzyskać więcej informacji, zobacz IoAllocateWorkItem.