共用方式為


在函式驅動程式中啟動裝置

函式驅動程式會設定 IoCompletion 例程、將 IRP_MN_START_DEVICE 要求傳遞至裝置堆疊,並延後其啟動作業,直到所有較低驅動程式都已完成 IRP 為止。 如需使用核心事件和IoCompletion例程來延遲 IRP 處理的詳細資訊,請參閱延後 PnP IRP 處理直到較低驅動程式完成為止。

其 DispatchPnP 例程在 IRP 完成所有較低驅動程式之後重新取得控制權時,函數驅動程式會執行啟動裝置的任務。 功能驅動程式使用如下程序啟動裝置:

  1. 如果底層驅動程式在進行 IRP(IoCallDriver 傳回錯誤)時失敗,請勿繼續處理該 IRP。 執行任何必要的清理,然後從 DispatchPnP 例程返回(移動到此列表中的最後一個步驟)。

  2. 如果較低的驅動程式已成功處理 IRP,請啟動裝置。

    啟動裝置的確切步驟會因裝置而異。 這類步驟可能包括對應 I/O 空間、初始化硬體緩存器、設定裝置處於 D0 電源狀態,以及使用 IoConnectInterrupt 連接中斷。 如果驅動程式在 IRP_MN_STOP_DEVICE 要求之後重新啟動裝置,驅動程式可能會有要還原的裝置狀態。

    裝置必須先開啟電源,才能存取任何驅動程式。 如需更多資訊,請參閱啟動裝置

    如果裝置應啟用喚醒功能,其電源原則擁有者(通常是函式驅動程式)應該在裝置啟動電源之後,以及完成 IRP_MN_START_DEVICE 要求之前,傳送等候/喚醒 IRP。 如需詳細資訊,請參閱 傳送等候/喚醒 IRP

  3. 在 IRP 持有佇列中啟動 IRP。

    清除驅動程式定義的HOLD_NEW_REQUESTS旗標,並在 IRP 持有佇列中啟動 IRP。 驅動程式應該會在第一次啟動裝置,以及在查詢停止或停止 IRP 之後重新啟動裝置時執行此動作。 如需詳細資訊,請參閱 在裝置暫停時按住傳入 IRP

  4. [選擇性]呼叫 IoSetDeviceInterfaceState來啟用裝置的介面。

    如果有的話,啟用驅動程式先前在其 AddDevice 例行程式中,或透過 INF 檔案或其他元件(例如協同安裝程式)註冊的介面。

    在 Windows 2000 和更新版本的 Windows 上,PnP 管理員不會在 IRP_MN_START_DEVICE IRP 完成之前傳送裝置介面抵達的通知,表示裝置的所有驅動程式都已完成其啟動作業。 在裝置的所有驅動程式完成啟動 IRP 之前,PnP 管理員也會失敗任何抵達的建立要求。

  5. 完成 IRP。

    函式驅動程式的 IoCompletion 例程傳回STATUS_MORE_PROCESSING_REQUIRED,如 延後 PnP IRP 處理直到較低驅動程式完成中所述,因此函式驅動程式的 DispatchPnP 例程必須呼叫 IoCompleteRequest 以繼續 I/O 完成處理。

    如果函式驅動程式的啟動作業成功,驅動程式會將 Irp-IoStatus.Status> 設定為 STATUS_SUCCESS、呼叫具有優先順序提升IO_NO_INCREMENT的 IoCompleteRequest,並從其 DispatchPnP 例程傳回STATUS_SUCCESS。

    如果函式驅動程式在啟動作業期間遇到錯誤,驅動程式會在 IRP 中設定錯誤狀態、使用 IO_NO_INCREMENT 呼叫 IoCompleteRequest ,並從 其 DispatchPnP 例程傳回錯誤。

    如果較低的驅動程序失敗,IRP (IoCallDriver 傳回錯誤),函式驅動程式會使用 IO_NO_INCREMENT 呼叫 IoCompleteRequest,並從其 DispatchPnP 例程傳回 IoCallDriver 錯誤。 在此案例中,函式驅動程式不會設定 Irp-IoStatus.Status>,因為已由失敗 IRP 的較低驅動程式設定狀態。

當函式驅動程式收到IRP_MN_START_DEVICE要求時,它應該檢查 IrpSp-Parameters.StartDevice.AllocatedResources>IrpSp-Parameters.StartDevice.AllocatedResourcesTranslated> 的結構,分別描述 PnP 管理員指派給裝置的原始和翻譯資源。 驅動程式應將裝置擴充功能中每個資源清單的複本儲存為偵錯輔助功能。

資源清單會配對 CM_RESOURCE_LIST 結構,其中原始清單的每個元素都會對應至翻譯清單的相同元素。 例如,如果 AllocatedResources.List[0] 描述原始 I/O 埠範圍,則 AllocatedResourcesTranslated.List[0] 會在翻譯後描述相同的範圍。 每個翻譯的資源都包含實體地址和資源類型。

如果驅動程式被指派翻譯的記憶體資源 (CmResourceTypeMemory),它必須呼叫 MmMapIoSpace ,將實體地址對應到虛擬位址,才能存取裝置緩存器。 若要讓驅動程式以平台獨立的方式運作,應檢查每個被傳回並翻譯過的資源,並在必要時加以對應。

函式驅動程式應執行下列動作,以回應 IRP_MN_START_DEVICE ,以確保存取所有裝置資源:

  1. IrpSp-Parameters.StartDevice.AllocatedResources> 複製到裝置擴充功能。

  2. IrpSp-Parameters.StartDevice.AllocatedResourcesTranslated> 複製到裝置擴充。

  3. 在迴圈中,檢查 AllocatedResourcesTranslated 中的每個描述元件。 如果描述項資源類型為 CmResourceTypeMemory,請呼叫 MmMapIoSpace,傳遞翻譯資源的實體地址和長度。

當驅動程式收到 IRP_MN_STOP_DEVICEIRP_MN_REMOVE_DEVICEIRP_MN_SURPRISE_REMOVAL 要求時,它必須在類似的循環結構中呼叫 MmUnmapIoSpace 來釋放對應。 如果驅動程式必須失敗IRP_MN_START_DEVICE要求,驅動程式也應該呼叫 MmUnmapIoSpace

如需詳細資訊 ,請參閱將 Bus-Relative 位址對應至虛擬位址