다음을 통해 공유


DPC 루틴 작성

DpcForIsrCustomDpc 루틴의 기본 책임은 다음 디바이스 I/O 작업이 즉시 시작되도록 하고 현재 IRP를 완료하는 것입니다.

DpcForIsr 또는 CustomDpc 루틴에서 수행하는 추가 작업은 드라이버의 디자인과 디바이스의 특성에 따라 달라집니다. 예를 들어 DpcForIsr 또는 CustomDpc 루틴은 다음 중 어느 것도 수행할 수 있습니다.

  • 시간이 초과되었거나 실패한 작업을 다시 시도합니다.

  • IoAllocateErrorLogEntry를 호출하고, 오류 로그 패킷을 설정하여 디바이스 I/O 오류를 보고하고, IoWriteErrorLogEntry를 호출합니다.

    I/O 오류 처리에 대한 자세한 내용은 로깅 오류를 참조하세요.

  • 드라이버가 버퍼링된 I/O를 사용하거나 IRP가 디바이스 제어 작업을 지정하는 경우 IRP를 완료하기 전에 디바이스에서 읽은 데이터를 Irp-ASSOCIATedIrp.SystemBuffer>의 시스템 버퍼로 전송합니다.

  • 드라이버가 직접 I/O 를 사용하고 큰 전송을 더 작은 부분으로 분할해야 하는 경우 방금 완료된 각 부분 전송 작업에 대한 상태를 저장하고, 다음 부분 전송 범위를 계산하고, 드라이버 제공 SynchCritSection 루틴을 사용하여 다음 부분 전송 작업을 위해 디바이스를 프로그래밍합니다.

    버퍼링된 I/O를 사용하는 드라이버도 디바이스에 제한된 전송 기능이 있는 경우 전송 요청을 분할해야 할 수 있습니다.

  • 드라이버가 패킷 기반 DMA를 사용하는 경우 각 디바이스 전송 작업 후 FlushAdapterBuffers 를 호출하고 부분 전송 시퀀스가 완료되고 전체 전송 요청이 충족되면 FreeAdapterChannel 또는 FreeMapRegisters 를 호출합니다.

    요청된 전송이 단일 DMA 작업에 의해 부분적으로만 충족되는 경우 DpcForIsr 또는 CustomDpc 루틴은 일반적으로 IRP의 지정된 바이트 수가 완전히 전송될 때까지 하나 이상의 DMA 작업을 설정하는 작업을 담당합니다.

    DMA 사용에 대한 자세한 내용은 어댑터 개체 및 DMA를 참조하세요.

  • 드라이버에서 프로그래밍된 I/O(PIO)를 사용하는 경우 현재 IRP가 읽기를 요청하는 경우 각 전송 작업이 끝날 때 KeFlushIoBuffers 를 호출합니다.

    요청된 전송이 단일 PIO 작업에서 부분적으로만 충족되는 경우 DpcForIsr 또는 CustomDpc 루틴은 일반적으로 IRP의 지정된 바이트 수가 완전히 전송될 때까지 하나 이상의 전송 작업을 설정해야 합니다.

    PIO 사용에 대한 자세한 내용은 Direct I/O 사용을 참조하세요.

  • 비 WDM 드라이버에 ControllerControl 루틴이 있는 경우 요청된 작업이 완료되면 IoFreeController 를 호출합니다.

DpcForIsr 또는 CustomDpc 루틴은 일반적으로 대부분의 드라이버 디바이스 I/O 처리를 수행하여 IRP를 충족합니다. 이러한 루틴은 또한 드라이버의 디스패치 루틴을 사용하여 디바이스에 IRP를 큐에 대기시키는 일부 책임을 공유합니다.

다음 일반 디자인 지침을 고려합니다.

  • 모든 DpcForIsr 또는 CustomDpc 루틴은 안전하게 호출할 수 있는 즉시 IoStartNextPacket을 호출해야 합니다. 즉, 드라이버의 StartIo 루틴 또는 StartIo 루틴이 실행되도록 하는 다른 루틴으로 리소스 충돌 또는 경합 상태를 유발하지 않을 수 있습니다.

  • 드라이버가 자체 IRP 큐를 관리하는 경우 DpcForIsr 또는 CustomDpc 루틴은 다음 IRP를 큐에서 제거하고 다음 요청에 대한 디바이스를 설정하는 것이 안전한 즉시 드라이버에 알려야 합니다.

DpcForIsr 또는 CustomDpc 루틴은 IoStartNextPacket을 호출하거나, 다음 요청에 대한 디바이스 I/O 처리를 시작할 수 있을 때 적절한 드라이버 루틴을 알려야 합니다. 드라이버 및 해당 디바이스에 따라 DpcForIsr 또는 CustomDpc 루틴이 IoCompleteRequest를 사용하여 현재 IRP를 완료하기 전에 발생하거나 이 루틴이 현재 IRP를 완료하고 컨트롤을 반환하기 직전에 발생할 수 있습니다.