Share via


I/O 큐의 예제 사용

시스템에 연결되고 특정 드라이버에서 지원하는 각 디바이스에 대해 드라이버는 다음과 같은 I/O 큐 및 요청 처리기 조합을 사용할 수 있습니다.

  • 단일 기본 I/O 큐 및 단일 요청 처리기 인 EvtIoDefault입니다. 프레임워크는 디바이스의 모든 요청을 기본 큐에 전달하고 드라이버의 EvtIoDefault 처리기를 호출하여 드라이버에 각 요청을 전달합니다.

  • 단일 기본 I/O 큐 및 EvtIoRead,EvtIoWriteEvtIoDeviceControl과 같은 여러 요청 처리기. 프레임워크는 디바이스의 모든 요청을 기본 큐에 전달합니다. 드라이버의 EvtIoRead 처리기를 호출하여 읽기 요청, 쓰기 요청을 배달하는 EvtIoWrite 처리기 및 디바이스 I/O 제어 요청을 배달하는 EvtIoDeviceControl 처리기를 제공합니다.

  • 읽기 요청에 대한 큐와 쓰기 요청에 대한 큐와 같은 여러 I/O 큐입니다. 각 큐에 대해 드라이버는 하나의 요청 처리기만 제공합니다. 큐는 하나의 요청 유형만 수신하기 때문입니다.

  • 여러 개의 I/O 큐( 각각 여러 요청 처리기가 있는 큐).

다음은 예제 시나리오입니다.

단일 순차 I/O 큐

읽기 및 쓰기 요청만 한 번에 하나씩 처리할 수 있는 디스크 드라이브에 대한 함수 드라이버를 작성하는 경우 함수 드라이버에는 디바이스당 하나의 I/O 큐만 필요합니다.

드라이버는 드라이버가 WdfIoQueueCreate 를 호출하고 큐의 WDF_IO_QUEUE_CONFIG 구조에서 DefaultQueueTRUE 로 설정할 때 프레임워크가 만드는 기본 I /O 큐를 사용할 수 있습니다. WDF_IO_QUEUE_CONFIG 구조에서 드라이버는 다음을 지정해야 합니다.

  • WdfIoQueueDispatchSequential 을 디스패치 메서드로 사용하므로 기본 I/O 큐는 I/O 요청을 드라이버에 동기적으로 전달합니다.

  • 모든 I/O 요청을 수신하는 단일 이벤트 콜백 함수 인 EvtIoDefault입니다.

드라이버의 기본 I/O 큐에서 I/O 요청을 사용할 수 있을 때마다 프레임워크는 드라이버의 EvtIoDefault 요청 처리기를 호출하여 드라이버에 요청을 전달합니다. 큐에서 다른 요청을 사용할 수 있게 되면 프레임워크는 드라이버가 이전에 배달된 요청에 대해 WdfRequestComplete 를 호출할 때까지 배달하지 않습니다.

여러 순차 I/O 큐 및 수동 큐

다음과 같은 특성을 가진 직렬 포트 디바이스를 고려합니다.

  • 동시에 하나의 읽기 작업과 하나의 쓰기 작업을 수행할 수 있습니다.

  • 여러 읽기 또는 쓰기 작업을 비동기적으로 수행할 수 없습니다.

  • 상태 정보에 대한 디바이스 I/O 제어 요청을 받을 수 있습니다. 디바이스의 드라이버는 이러한 요청 중 일부(예: 상태 변경을 기다리는 요청)를 완료하는 데 시간이 오래 걸릴 수 있습니다.

이 디바이스의 함수 드라이버는 디바이스당 여러 순차 I/O 큐를 사용할 수 있습니다. 드라이버는 WdfIoQueueCreate 를 세 번 호출합니다. 기본 큐를 만들려면 한 번, 두 번 호출하여 두 개의 추가 I/O 큐를 만듭니다. 이러한 각 큐에 대한 WDF_IO_QUEUE_CONFIG 구조에서 드라이버는 다음을 지정해야 합니다.

  • WdfIoQueueDispatchSequential 을 각 큐에 대한 디스패치 메서드로 사용하여 프레임워크가 I/O 요청을 드라이버에 동기적으로 전달합니다.

  • 큐의 I/O 요청을 수신하는 각 큐(EvtIoDefault, EvtIoReadEvtIoWrite)에 대한 다른 요청 처리기입니다.

WdfIoQueueCreate를 호출한 후 드라이버는 WdfDeviceConfigureRequestDispatching을 두 번 호출하여 모든 읽기 요청을 추가 큐 중 하나에 전달하고 모든 쓰기 요청을 다른 큐에 전달할 수 있습니다.

이 구성을 사용하면 디바이스의 기본 I/O 큐 EvtIoDefault 콜백 함수는 상태 정보에 대한 디바이스 I/O 제어 요청만 수신합니다.

드라이버가 상태 요청을 오랫동안 보유해야 하는 경우 네 번째 큐를 만들고 WdfIoQueueDispatchManual을 디스패치 메서드로 지정할 수 있습니다. 드라이버가 기다려야 하는 정보에 대한 요청을 받으면 상태 정보를 사용할 수 있을 때까지 이 추가 큐에 요청을 배치할 수 있습니다. 그런 다음 드라이버는 큐에서 요청을 검색하고 완료할 수 있습니다. 그 동안 기본 큐는 드라이버에 다른 요청을 제공할 수 있습니다.

단일 병렬 I/O 큐

IDE 디스크 컨트롤러는 일부 I/O 작업과 겹칠 수 있지만 다른 작업은 겹칠 수 없습니다. 예를 들어 컨트롤러가 한 디스크에서 읽기 또는 쓰기 작업을 처리하는 동안 seek 명령을 다른 디스크로 보낼 수 있습니다. 반면에 여러 개의 동시 읽기 및 쓰기 명령은 지원되지 않습니다.

이 컨트롤러의 함수 드라이버는 각 I/O 요청을 검사해야 합니다. 드라이버가 seek 명령을 수신하는 경우 seek 명령을 처리할 수 있는지 확인해야 합니다. 다음과 같은 경우 seek 명령을 처리할 수 없습니다.

  • 지정된 디스크 드라이브가 이미 사용 중입니다.

  • 디스크 드라이브의 형식이 지정되므로 다른 드라이브는 활성화할 수 없습니다.

컨트롤러에 연결된 각 디바이스에 대해 드라이버는 WdfIoQueueCreate 를 호출하여 기본 I/O 큐를 만들 수 있습니다. 이러한 각 큐에 대한 WDF_IO_QUEUE_CONFIG 구조에서 드라이버는 다음을 지정해야 합니다.

  • WdfIoQueueDispatchParallel 은 프레임워크가 드라이버에 I/O 요청을 비동기적으로 전달할 수 있도록 각 큐에 대한 디스패치 메서드입니다.

  • 큐의 I/O 요청을 수신하는 각 큐에 대한 EvtIoDefault 이벤트 콜백 함수입니다.

이 구성을 사용하면 단일 병렬 I/O 큐가 각 디바이스에 할당됩니다. 드라이버는 프레임워크가 각 I/O 큐에서 제공하는 각 I/O 요청을 검사해야 합니다. 드라이버가 요청을 즉시 처리할 수 있는 경우 이렇게 합니다. 그렇지 않으면 드라이버가 WdfIoQueueStop을 호출하므로 드라이버가 WdfIoQueueStart를 호출할 때까지 프레임워크가 요청 배달을 중지합니다.

여러 병렬 I/O 큐

SCSI 호스트 어댑터는 겹치는 비동기 I/O 작업을 지원하는 디바이스의 예입니다. 최대 32개 디바이스를 어댑터에 연결할 수 있습니다. 다음 구성을 사용하는 시스템을 고려합니다.

  • SCSI 어댑터에 연결된 일부 디바이스는 "다시 선택"을 지원하며 일부는 지원하지 않습니다. SCSI 디바이스가 다시 선택을 지원하는 경우 I/O 작업 중에 어댑터가 다른 디바이스를 서비스할 수 있도록 디바이스가 어댑터를 일시적으로 해제할 수 있습니다. 첫 번째 디바이스는 나중에 자체적으로 다시 선택하여 작업을 완료합니다.

  • SCSI 어댑터는 하드웨어 사서함을 사용하여 드라이버와 디바이스 간에 요청 및 응답을 전달합니다. 디바이스가 요청에 대한 준비가 되었지만 사용 가능한 사서함이 없는 경우 디바이스는 기다려야 합니다.

최상의 성능을 위해 이 SCSI 호스트 어댑터의 함수 드라이버는 사용 가능한 즉시 프레임워크에서 I/O 요청을 받아야 합니다. 드라이버는 각 요청을 검사하고 즉시 시작할 수 있는지 또는 디바이스 및 리소스(예: 사서함 메모리)를 사용할 수 있을 때까지 연기해야 하는지 확인해야 합니다.

드라이버는 여러 병렬 I/O 큐를 사용해야 합니다. 어댑터에 연결된 각 디바이스에 대해 드라이버는 WdfIoQueueCreate 를 호출하여 기본 I/O 큐를 만듭니다. 이러한 각 큐에 대한 WDF_IO_QUEUE_CONFIG 구조에서 드라이버는 다음을 지정해야 합니다.

  • WdfIoQueueDispatchParallel 은 프레임워크가 드라이버에 I/O 요청을 비동기적으로 전달할 수 있도록 각 큐에 대한 디스패치 메서드입니다.

  • 큐의 I/O 요청을 수신하는 각 큐에 대한 EvtIoDefault 이벤트 콜백 함수입니다.

각 I/O 큐의 EvtIoDefault 콜백 함수는 큐가 배달될 때 큐의 I/O 요청을 검사하고 각 요청을 즉시 서비스할 수 있는지 여부를 결정해야 합니다. 디바이스 및 시스템 리소스를 사용할 수 있는 경우 드라이버는 I/O 작업을 시작합니다. 디바이스 또는 리소스를 사용할 수 없는 경우 드라이버는 WdfIoQueueStop 을 호출하여 현재 요청을 처리할 수 있을 때까지 추가 요청 배달을 중지해야 합니다.

필요에 따라 드라이버는 WdfIoQueueCreate 를 호출하여 각 디바이스에 대한 추가 큐를 만들 수 있습니다. 그런 다음 드라이버는 WdfRequestForwardToIoQueue 를 호출하여 일부 유형의 요청을 추가 큐에 다시 큐에 추가할 수 있습니다. 프레임워크가 추가 큐에서 요청을 전달하는 경우 드라이버는 필요한 경우 기본 큐 대신 해당 큐에서 WdfIoQueueStop을 호출하여 배달이 연기되는 요청의 수 또는 유형을 최소화할 수 있습니다.