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

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

DispatchPnP 常式在 IRP 完成所有較低驅動程式之後重新取得控制權時,函式驅動程式會執行其工作來啟動裝置。 函式驅動程式會使用如下所示的程式啟動裝置:

  1. 如果較低的驅動程式失敗, IoCallDriver (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 常式傳回錯誤。

    如果較低的驅動程式失敗,IoCallDriver (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位址對應至虛擬位址