다음을 통해 공유


ControllerControl 루틴 요구 사항

이름에서 알 수 있듯이 ControllerControl 루틴은 컨트롤러 개체와 연결됩니다. ControllerControl 루틴이 실행되면 컨트롤러 개체가 나타내는 하드웨어는 무료이며 컨트롤러 확장에 드라이버의 ISR과 공유되는 컨텍스트가 포함되지 않는 한 일반적으로 컨트롤러 확장은 다른 드라이버 루틴에서 액세스되지 않습니다.

일반적으로 ControllerControl 루틴은 적어도 다음을 수행합니다.

  1. 대상 디바이스 개체의 디바이스 확장 및 컨트롤러 확장에서 드라이버가 유지 관리하는 컨텍스트를 업데이트 또는 초기화합니다.

    드라이버가 DMA를 사용하는 경우 해당 ControllerControl 루틴은 일반적으로 각 DMA 전송 크기에 대한 시스템 부과 또는 디바이스 부과 제한으로 인해 지정된 전송 요청을 부분 전송으로 분할해야 하는지 여부를 결정합니다. 이러한 상황에서 ControllerControl 루틴은 드라이버에 AdapterControl 루틴이 있는 경우 AllocateAdapterChannel을 호출해야 합니다.

    드라이버가 PIO를 사용하는 경우 ControllerControl 루틴은 하드웨어에 필요한 경우 전송 요청을 부분 전송 범위로 분할하고 Irp-MdlAddress>에서 MDL로 MmGetSystemAddressForMdlSafe를 호출하는 작업을 담당합니다.

  2. 요청된 I/O 작업에 대한 하드웨어를 프로그래밍합니다.

    ISR에서 디바이스 또는 컨트롤러 확장에 액세스할 수 있는 경우 ControllerControl 루틴은 KeSynchronizeExecution을 호출하여 호출되는 SynchCritSection 루틴을 사용해야 합니다. 자세한 내용은 중요 섹션 사용을 참조하세요.

드라이버에 Cancel 루틴이 있는 경우 ControllerControl 루틴도 Irp-Cancel> 필드를 검사 현재 IRP를 취소해야 하는지 여부를 확인하고 다음 중 하나를 수행해야 합니다.

Irp-Cancel>TRUE로 설정된 경우 ControllerControl 루틴은 다음을 수행해야 합니다.

  1. 상태의 STATUS_CANCELLED 설정하고 IRP의 I/O 상태 블록에 있는 정보에 대해 0을 설정합니다.

  2. 다음 디바이스 작업을 즉시 시작할 수 있도록 컨트롤러 개체를 해제하려면 IoFreeController 를 호출합니다.

  3. 드라이버가 자체 큐를 관리하는 경우 IoStartNextPacket 을 호출하거나 다음 IRP를 큐에서 제거합니다.

  4. IoCompleteRequest를 사용하여 취소된 IRP를 완료하고 컨트롤을 반환합니다.

Irp-Cancel>TRUE로 설정되지 않은 경우 ControllerControl 루틴은 다음을 수행해야 합니다.

  1. IoSetCancelRoutine을 호출하여 IRP의 취소 루틴 진입점을 NULL로 다시 설정합니다. 드라이버가 디바이스 개체에서 I/O 관리자 제공 디바이스 큐를 사용하는 경우 이 호출에 대한 취소 스핀 잠금을 획득합니다.

  2. KeSynchronizeExecution을 호출하여 호출되는 SynchCritSection 루틴을 사용하여 요청된 I/O 작업에 대한 하드웨어를 프로그래밍합니다. 자세한 내용은 중요 섹션 사용을 참조하세요.

취소 가능한 IRP 처리에 대한 자세한 내용은 IRP 취소를 참조하세요.

실제 컨트롤러/어댑터에 연결된 다른 디바이스에서 겹치는 작업을 제외한 대부분의 인터럽트 기반 I/O 작업의 경우 DpcForIsr 또는 CustomDpc 루틴이 작업 및 IRP를 완료하기 때문에 ControllerControl 루틴은 KeepObject를 반환해야 합니다.

현재 요청을 충족하기 위한 I/O 작업이 완료되는 즉시 IRP를 완료하는 루틴은 다음 요청을 가능한 한 빨리 처리할 수 있도록 IoFreeControllerIoStartNextPacket 을 호출해야 합니다.

ControllerControl 루틴 자체가 IRP를 완료하거나 다른 디바이스 개체에 대한 작업과 겹칠 수 있는 하나의 대상 디바이스 개체(디스크)에 대해 디스크 검색과 같은 작업을 설정할 수 있는 경우 ControllerControl 루틴은 DeallocateObject를 반환해야 합니다.