본문 바로가기
Programming/윈도우 드라이버

Io Request 처리하기

by 유주원 2013. 1. 4.

드라이버가 I/O reqeust를 수신하였을 때, 다음과 같은 동작을 한다.

1. request를 다른 queue로 Requeue 한다.

2. request를 완료한다.

3. request를 취소한다.

4. I/O target 드라이버로 request를 전송한다.


드라이버는 request를 무시하거나 삭제할 수 없다.

 

Requeuing I/O Requests

 

드라이버는 I/O queue로부터 수신한 I/O requests를 requeue 할 수 있다. 또한 버스 드라이버는 자식 디바이스의 I/O queue로부터 부모 디바이스의 I/O queue로 I.O request를 requeue할 수 있다.

 

I/O Request를 다른 I/O Queue에 Requeuing 하기


- 드라이버의 request 핸들러가 I/O queue로부터 I/O request를 수신한 후에, 드라이버는 다른 queue에 request를 requeue 하기 위해 WdfRequestForwardToIoQueue를 호출할 수 있다.

예를 들어 만약 드라이버가 request를 처리하기 전에 리소스를 할당받기를 원한다면 일단 

 

 1. 드라이버의 EvtIoDefault callback 함수에서 모든 request를 수신한다.

 2. EvtIoDefault callback 함수에서는 request의 context 메모리에 저장되어 있는 리소스 정보를
     저장한다.

 3. 추가적인 queue에 각각의 request를 requeue 하기 위해 WdfRequestForwardToIoQueue를 
     호출한다.  


만약 드라이버가 I/O request를 requeue 하기 위해 WdfRequestForwardToIoQueue를 호출한다면, 프레임워크는 requeue된 request의 완료를 기다리지 않고 곧바로 드라이버에게 다음 I/O request를 전달할 것이다.


만약 드라이버가 manual dispatching 방법을 사용한다면, 드라이버는 I/O queue의 헤더에 위치한 I/O request를 리턴 받기 위해 WdfRequestRequeue를 호출할 수 있다. WdfRequestRequeue를 호출한 후에 드라이버는 requeue된 request를 검출하기 위해 WdfIoQueueRetrieveNextRequest를 호출한다.  

 

I/O Request를 부모 디바이스의 I/O queue에 Requeuing 하기


기능 드라이버는 자식 디바이스를 열거하거나 자식 디바이스를 위한 PDO를 설정하는 등 버스 드라이버로써의 역할을 담당할 수 있다. 이러한 드라이버들은 때때로 부모 디바이스가 반드시 처리해야할 I/O request를 수신할 경우가 있다.


예를 들어 USB와 같은 프로토콜 버스는 전형적으로 디바이스에 대한 하드웨어 리소스를 제어한다. 그래서 부모 버스를 위한 기능 드라이버는 각각의 자식 디바이스를 위해 I/O 동작을 처리한다. I/O 관리자가 자식 디바이스의 디바이스 스택에 I/O request를 전송할 때, 기능 드라이버는 자식 디바이스의 I/O queue에 있는 I/O request를 수신한다. 드라이버가 부모 버스의 콘텍스트에 있는 I/O request를 처리하기 전에 자식 디바이스의 I/O queue로부터 부모 디바이스에 속하는 I/O queue에 I/O request를 requeue해야 한다.

 

그러나 드라이버는 자식 queue로부터 부모의 queue로 request를 이동시키기 위해 WdfRequestForwardToIoQueue를 호출할 수 없다. I/O 관리자가 부모 디바이스와 자식 디바이스의 디바이스 스택을 각각 분리해서 생성하기 때문이다. 근본적인 WDM 디바이스 오브젝트가 반드시 처음에 자식 디바이스에서 부모로 변경되어야 한다.

 

KMDF의 1.9 이전 버전에서는 remote I/O target을 생성하고, 자식 디바이스의 디바이스 스택 사이즈를 늘리고, 올바른 WDM 디바이스 object를 명시함으로써 자식 디바이스가 부모 디바이스에게 I/O request를 보냈었다.   


1.9의 KMDF 버전에서는 드라이버는 자식 I/O queue를 부모 queue로 requeue하기 위해 자식 디바이스를 생성하기 전에, WdfPdoInitAllowForwardingRequestToParent를 호출할 수 있고, 그런 후 WdfRequestForwardToParentDeviceIoQueue를 호출할 수 있다. 


만약 드라이버가 WdfPdoInitAllowForwardingRequestToParent와 WdfRequestForwardToParentDeviceIoQueue를 사용한다면 프레임워크는 자식의 디바이스 스택 크기를 증가시키고 I/O request를 올바른 WDM 디바이스 object로 배정할 것이다.