함수 드라이버에서 디바이스 시작
함수 드라이버는 IoCompletion 루틴을 설정하고, IRP_MN_START_DEVICE 요청을 디바이스 스택 아래로 전달하고, 모든 하위 드라이버가 IRP로 완료될 때까지 시작 작업을 연기합니다. 커널 이벤트 및 IoCompletion 루틴을 사용하여 IRP 처리를 연기하는 방법에 대한 자세한 내용은 낮은 드라이버가 완료될 때까지 PnP IRP 처리 연기를 참조하세요.
모든 하위 드라이버가 IRP를 완료한 후 DispatchPnP 루틴이 다시 제어되면 함수 드라이버는 디바이스를 시작하기 위한 작업을 수행합니다. 함수 드라이버는 다음과 같은 프로시저를 사용하여 디바이스를 시작합니다.
낮은 드라이버가 IRP에 실패한 경우(IoCallDriver에서 오류를 반환함) IRP 처리를 계속하지 마세요. 필요한 정리를 수행하고 DispatchPnP 루틴에서 반환합니다(이 목록의 마지막 단계로 이동).
낮은 드라이버가 IRP를 성공적으로 처리한 경우 디바이스를 시작합니다.
디바이스를 시작하는 정확한 단계는 디바이스마다 다릅니다. 이러한 단계에는 I/O 공간 매핑, 하드웨어 레지스터 초기화, D0 전원 상태에서 디바이스 설정, 인터럽트와 IoConnectInterrupt 연결 등이 포함될 수 있습니다. 드라이버가 IRP_MN_STOP_DEVICE 요청 후 디바이스를 다시 시작하는 경우 드라이버에 복원할 디바이스 상태가 있을 수 있습니다.
모든 드라이버가 디바이스에 액세스하려면 먼저 디바이스의 전원을 켜야 합니다. 자세한 내용은 디바이스 전원 켜 기 를 참조하세요.
절전 모드 해제에 디바이스를 사용하도록 설정해야 하는 경우 전원 정책 소유자(일반적으로 함수 드라이버)는 디바이스의 전원을 켜고 IRP_MN_START_DEVICE 요청을 완료하기 전에 대기/절전 모드 해제 IRP를 보내야 합니다. 자세한 내용은 대기/절전 모드 해제 IRP 보내기를 참조하세요.
IRP 보유 큐에서 IRP를 시작합니다.
드라이버 정의 HOLD_NEW_REQUESTS 플래그를 지우고 IRP 보유 큐에서 IRP를 시작합니다. 드라이버는 처음으로 디바이스를 시작하고 IRP를 쿼리 중지 또는 중지한 후 디바이스를 다시 시작할 때 이 작업을 수행해야 합니다. 자세한 내용은 디바이스가 일시 중지된 경우 들어오는 IRP 유지 를 참조하세요.
[선택 사항] IoSetDeviceInterfaceState를 호출하여 디바이스에 대한 인터페이스를 사용하도록 설정합니다.
드라이버가 이전에 AddDevice 루틴(또는 INF 또는 공동 설치 관리자와 같은 다른 구성 요소)에 등록한 인터페이스(있는 경우)를 사용하도록 설정합니다.
Windows 2000 이상 버전의 Windows에서 PnP 관리자는 IRP_MN_START_DEVICE IRP가 완료될 때까지 디바이스 인터페이스 도착 알림을 보내지 않으므로 디바이스의 모든 드라이버가 시작 작업을 완료했음을 나타냅니다. 또한 PnP 관리자는 디바이스의 모든 드라이버가 시작 IRP를 완료하기 전에 도착하는 모든 만들기 요청에 실패합니다.
IRP를 완료합니다.
함수 드라이버의 IoCompletion 루틴은 낮은 드라이버가 완료될 때까지 PnP IRP 처리 연기에 설명된 대로 STATUS_MORE_PROCESSING_REQUIRED 반환되므로 함수 드라이버의 DispatchPnP 루틴은 I/O 완료 처리를 다시 시작하려면 IoCompleteRequest 를 호출해야 합니다.
함수 드라이버의 시작 작업이 성공한 경우 드라이버는 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에 실패한 하위 드라이버에 의해 상태 이미 설정되었기 때문에 Irp-IoStatus.Status>를 설정하지 않습니다.
함수 드라이버가 IRP_MN_START_DEVICE 요청을 받으면 PnP 관리자가 디바이스에 할당한 원시 및 변환된 리소스를 각각 설명하는 IrpSp-Parameters.StartDevice.AllocatedResources> 및 IrpSp-Parameters.StartDevice.AllocatedResourcesTranslated>의 구조를 검사해야 합니다. 드라이버는 디버깅 지원으로 디바이스 확장에 있는 각 리소스 목록의 복사본을 저장해야 합니다.
리소스 목록은 원시 목록의 각 요소가 변환된 목록 의 동일한 요소에 해당하는 CM_RESOURCE_LIST 구조체와 쌍을 이웁니다. 예를 들어 AllocatedResources.List[0]에서 원시 I/O 포트 범위를 설명하는 경우 AllocatedResourcesTranslated.List[0]는 번역 후 동일한 범위를 설명합니다. 번역된 각 리소스에는 실제 주소와 리소스 유형이 포함됩니다.
드라이버에 변환된 메모리 리소스(CmResourceTypeMemory)가 할당된 경우 MmMapIoSpace 를 호출하여 물리적 주소를 디바이스 레지스터에 액세스할 수 있는 가상 주소에 매핑해야 합니다. 드라이버가 플랫폼 독립적 방식으로 작동하려면 반환되고 번역된 각 리소스를 검사 필요한 경우 매핑해야 합니다.
함수 드라이버는 모든 디바이스 리소스에 대한 액세스를 보장하기 위해 IRP_MN_START_DEVICE 대한 응답으로 다음을 수행해야 합니다.
IrpSp-Parameters.StartDevice.AllocatedResources>를 디바이스 확장에 복사합니다.
IrpSp-Parameters.StartDevice.AllocatedResourcesTranslated>를 디바이스 확장에 복사합니다.
루프에서 AllocatedResourcesTranslated의 각 설명자 요소를 검사합니다. 설명자 리소스 종류가 CmResourceTypeMemory이면 MmMapIoSpace를 호출하여 번역된 리소스의 실제 주소와 길이를 전달합니다.
드라이버는 IRP_MN_STOP_DEVICE, IRP_MN_REMOVE_DEVICE 또는 IRP_MN_SURPRISE_REMOVAL 요청을 받으면 비슷한 루프에서 MmUnmapIoSpace 를 호출하여 매핑을 해제해야 합니다. 또한 드라이버는 IRP_MN_START_DEVICE 요청에 실패해야 하는 경우 MmUnmapIoSpace를 호출해야 합니다.
자세한 내용은 Bus-Relative 주소를 가상 주소에 매핑 을 참조하세요.