Udostępnij przez


Uruchamianie urządzenia w sterowniku funkcji

Sterownik funkcji ustawia procedurę IoCompletion, przekazuje żądanie IRP_MN_START_DEVICE w głąb stosu urządzeń i odkłada operacje uruchamiania do momentu zakończenia operacji przez wszystkie niższe sterowniki z IRP. Aby uzyskać szczegółowe informacje na temat używania zdarzenia jądra i procedury IoCompletion w celu odroczenia przetwarzania IRP, zobacz Opóźnianie przetwarzania PnP IRP do momentu zakończenia pracy niższych sterowników.

Gdy procedura DispatchPnP odzyska kontrolę po zakończeniu działania wszystkich niższych sterowników za pomocą protokołu IRP, sterownik funkcji wykonuje swoje zadania na potrzeby uruchamiania urządzenia. Sterownik funkcji uruchamia urządzenie z procedurą podobną do następującej:

  1. Jeśli niższy sterownik zgłosi błąd (funkcja IoCallDriver zwróciła błąd), nie kontynuuj przetwarzania zapytania IRP. Wykonaj wszelkie niezbędne czynności oczyszczające i wróć z procedury DispatchPnP (przejdź do ostatniego kroku na tej liście).

  2. Jeśli niższe sterowniki pomyślnie przetworzyły protokół IRP, uruchom urządzenie.

    Dokładne kroki uruchamiania urządzenia różnią się od urządzenia do urządzenia. Takie kroki mogą obejmować mapowanie miejsca we/wy, inicjowanie rejestrów sprzętowych, ustawianie urządzenia w stanie zasilania D0 i łączenie przerwania z IoConnectInterrupt. Jeśli sterownik uruchamia ponownie urządzenie po żądaniu IRP_MN_STOP_DEVICE, sterownik może mieć stan urządzenia do przywrócenia.

    Urządzenie musi być włączone, zanim jakiekolwiek sterowniki będą mogły uzyskać do niego dostęp. Aby uzyskać więcej informacji, zobacz Powering Up a Device (Włączanie urządzenia ).

    Jeśli urządzenie powinno być włączone na potrzeby wznawiania, jego właściciel zasad zasilania (zazwyczaj sterownik funkcji) powinien wysłać protokół IRP oczekiwania/wznawiania po włączeniu urządzenia i przed ukończeniem żądania IRP_MN_START_DEVICE . Aby uzyskać szczegółowe informacje, zobacz Wysyłanie IRP Oczekiwania/Budzenia.

  3. Uruchom IRP-y w kolejce IRP-holding.

    Wyczyść flagę HOLD_NEW_REQUESTS zdefiniowaną przez sterownik i uruchom IRP w kolejce przetrzymującej IRP. Sterowniki powinny to zrobić podczas uruchamiania urządzenia po raz pierwszy oraz po ponownym uruchomieniu urządzenia po zatrzymaniu operacji zapytania lub zatrzymaniu operacji IRP. Aby uzyskać więcej informacji, zobacz Holding Incoming IRPs When A Device Is Paused (Przechowywanie przychodzących adresów IRP po wstrzymaniu urządzenia ).

  4. [Opcjonalnie] Włącz interfejsy dla urządzenia, wywołując element IoSetDeviceInterfaceState.

    Włącz interfejsy, które, jeśli istnieją, sterownik wcześniej zarejestrował w procedurze AddDevice (lub w INF lub przez inny element, jak współinstalator).

    W systemie Windows 2000 i nowszych wersjach systemu Windows menedżer PnP nie wysyła powiadomień o przybyciu interfejsu urządzenia do momentu ukończenia IRP_MN_START_DEVICE IRP, co oznacza, że wszystkie sterowniki urządzenia zakończyły operacje uruchamiania. Menedżer pnP również kończy się niepowodzeniem wszelkich żądań tworzenia, które docierają przed ukończeniem wszystkich sterowników urządzenia podczas uruchamiania protokołu IRP.

  5. Ukończ protokół IRP.

    Procedura IoCompletion sterownika funkcji zwróciła STATUS_MORE_PROCESSING_REQUIRED, zgodnie z opisem w temacie Postponing PnP IRP Processing Until Lower Drivers Finish (Przetwarzanie protokołu IRP po dolnej części sterowników), więc procedura sterownika funkcji DispatchPnP musi wywołać procedurę IoCompleteRequest, aby wznowić przetwarzanie uzupełniania operacji we/wy.

    Jeśli operacje uruchamiania sterownika funkcji zakończyły się pomyślnie, sterownik ustawia parametr Irp-IoStatus.Status> na STATUS_SUCCESS, wywołuje funkcję IoCompleteRequest z priorytetowym zwiększeniem IO_NO_INCREMENT i zwraca STATUS_SUCCESS z procedury DispatchPnP.

    Jeśli sterownik funkcji napotka błąd podczas jego operacji uruchamiania, sterownik ustawia stan błędu w IRP, wywołuje element IoCompleteRequest z IO_NO_INCREMENT i zwraca błąd z procedury DispatchPnP .

    Jeśli niższy sterownik nie powiódł IRP (IoCallDriver zwrócił błąd), sterownik funkcji wywołuje funkcję IoCompleteRequest z IO_NO_INCREMENT i zwraca błąd IoCallDriver z rutyny DispatchPnP. Sterownik funkcji nie ustawia parametru Irp-IoStatus.Status> w tym przypadku, ponieważ stan został już ustawiony przez niższy sterownik, który uległ awarii IRP.

Gdy sterownik funkcji odbiera żądanie IRP_MN_START_DEVICE, powinien przeanalizować struktury w IrpSp-Parameters.StartDevice.AllocatedResources> i IrpSp-Parameters.StartDevice.AllocatedResourcesTranslated>, które opisują przydzielone zasoby surowe i przetworzone przez menedżera PnP do urządzenia. Sterowniki powinny zapisywać kopię każdej listy zasobów w rozszerzeniu urządzenia jako pomoc debugowania.

Listy zasobów są połączone CM_RESOURCE_LIST struktury, w których każdy element surowej listy odpowiada temu samemu elementowi przetłumaczonej listy. Jeśli na przykład wartość AllocatedResources.List[0] opisuje nieprzetworzony zakres portów we/wy, to wartość AllocatedResourcesTranslated.List[0] opisuje ten sam zakres po tłumaczeniu. Każdy przetłumaczony zasób zawiera adres fizyczny i typ zasobu.

Jeśli sterownik ma przypisany przetłumaczony zasób pamięci (CmResourceTypeMemory), musi wywołać element MmMapIoSpace , aby zamapować adres fizyczny na adres wirtualny, za pomocą którego może uzyskiwać dostęp do rejestrów urządzeń. Aby sterownik działał w sposób niezależny od platformy, powinien sprawdzić każdy zwrócony, przetłumaczony zasób i mapować go, jeśli jest to konieczne.

Sterownik funkcji powinien wykonać następujące czynności w odpowiedzi na IRP_MN_START_DEVICE w celu zapewnienia dostępu do wszystkich zasobów urządzenia:

  1. Skopiuj IrpSp-Parameters.StartDevice.AllocatedResources> do rozszerzenia urządzenia.

  2. Skopiuj IrpSp-Parameters.StartDevice.AllocatedResourcesTranslated> do rozszerzenia urządzenia.

  3. W pętli skontroluj każdy element deskryptora w AllocatedResourcesTranslated. Jeśli typ zasobu deskryptora to CmResourceTypeMemory, wywołaj metodę MmMapIoSpace, przekazując adres fizyczny i długość przetłumaczonego zasobu.

Gdy sterownik odbiera żądanie IRP_MN_STOP_DEVICE, IRP_MN_REMOVE_DEVICE lub IRP_MN_SURPRISE_REMOVAL, musi zwolnić mapowania, wywołując funkcję MmUnmapIoSpace w pętli w podobny sposób. Sterownik powinien również wywołać polecenie MmUnmapIoSpace , jeśli musi zakończyć się niepowodzeniem żądania IRP_MN_START_DEVICE .

Aby uzyskać więcej informacji, zobacz Mapowanie adresów Bus-Relative na adresy wirtualne .