구성 요소 전원 상태를 사용하여 I/O 요청 조정

[KMDF에만 적용]

다중 구성 요소 디바이스에 대한 KMDF 드라이버는 활성 상태인 구성 요소에만 요청을 보내야 합니다. 일반적으로 드라이버는 구성 요소 또는 구성 요소 집합에 I/O 큐를 할당합니다.

먼저 단일 구성 요소에 할당된 큐를 고려합니다. 드라이버는 구성 요소가 활성화될 때 큐를 시작하고 구성 요소가 유휴 상태가 되면 큐를 중지합니다. 따라서 KMDF가 큐에 대한 요청 처리기를 호출할 때 디바이스는 완전히 켜짐(D0) 상태이며 필요한 구성 요소가 활성 상태입니다. 요청 처리기는 구성 요소 하드웨어에 안전하게 액세스할 수 있습니다.

구성 요소 집합에 할당된 큐에 동일한 개념이 적용됩니다. 이 경우 집합의 모든 구성 요소가 활성 상태이면 드라이버가 큐를 시작합니다. 드라이버는 구성 요소 중 하나가 유휴 상태가 되면 큐를 중지합니다.

이 항목에서는 여러 구성 요소 디바이스에 대한 KMDF 드라이버가 다양한 구성 요소 조합이 필요한 여러 요청 유형과 관련된 상황에서 이러한 지원을 구현하는 방법에 대해 설명합니다.

예제

드라이버에서 지원하는 각 요청 유형에 대해 필요한 구성 요소를 식별합니다. 예를 들어 드라이버가 세 가지 유형의 요청인 A, B 및 C를 수신하는 0, 1 및 2의 세 가지 구성 요소가 있는 디바이스를 생각해 보세요. 요청의 구성 요소 요구 사항은 다음과 같습니다.

요청 유형 필요한 구성 요소
A 0,2
b 1
C 0,1,2

이 예제에는 각 요청 유형에 대해 하나씩 세 개의 고유한 구성 요소 집합이 있습니다. 드라이버는 디바이스에 대한 하나의 기본 전원 관리 I/O 큐와 각 구성 요소 집합에 해당하는 하나의 추가 전원 관리형 큐를 제공합니다. 위의 예제에서 드라이버는 각 구성 요소 집합에 해당하는 하나의 주 큐와 세 개의 보조 큐를 만듭니다. 이 큐 구성은 다음 다이어그램에 나와 있습니다.

요청 유형이 A, B 및 C인 다중 구성 요소 디바이스에 대한 큐 구현을 보여 주는 다이어그램

드라이버는 각 구성 요소 집합에 대한 비트 마스크를 유지 관리합니다. 비트 마스크의 각 비트는 구성 요소 중 하나의 활성/유휴 상태를 나타냅니다. 비트가 설정되면 구성 요소가 활성 상태입니다. 비트가 지워지면 구성 요소가 유휴 상태입니다.

요청이 도착하면 최상위 큐에 대한 요청 처리기가 요청에 필요한 구성 요소를 결정하고 각 구성 요소에 대해 PoFxActivateComponent 를 호출합니다. 그런 다음 요청 처리기는 해당 구성 요소의 집합에 해당하는 보조 I/O 큐에 요청을 전달합니다.

구성 요소가 활성화되면 PoFx(전원 관리 프레임워크)는 드라이버의 ComponentActiveConditionCallback 루틴을 호출합니다. 이 콜백에서 드라이버는 해당 구성 요소가 표시되는 각 비트 마스크에서 지정된 구성 요소에 해당하는 비트를 설정합니다. 지정된 비트 마스크의 모든 비트가 설정된 경우 해당 집합의 모든 구성 요소가 활성화됩니다. 완전히 활성화된 각 구성 요소 집합에 대해 드라이버는 WdfIoQueueStart 를 호출하여 해당 보조 I/O 큐를 시작합니다.

예를 들어 위의 가상 디바이스를 고려합니다. 구성 요소 0이 활성 상태이고 구성 요소 1과 2가 유휴 상태라고 가정합니다. 구성 요소 2가 활성화되면 PoFx는 해당 구성 요소의 ComponentActiveConditionCallback 루틴을 호출합니다. 요청 유형 A 및 C는 구성 요소 2를 사용하므로 드라이버는 이러한 두 요청 형식에 대한 비트 마스크를 조작합니다. 요청 유형 A에 대한 비트 마스크의 모든 비트가 이제 설정되었으므로 드라이버는 요청 형식 A에 대한 큐를 시작합니다. 그러나 요청 유형 C에 대해 모든 비트가 설정되는 것은 아닙니다(구성 요소 1은 여전히 유휴 상태임). 드라이버는 요청 형식 C에 대한 큐를 시작하지 않습니다.

보조 I/O 큐가 시작되면 프레임워크는 큐에 저장된 요청을 전달하기 시작합니다. 보조 I/O 큐에 대한 요청 처리기 에서 드라이버는 구성 요소가 활성 상태이고 각 요청에 대한 구성 요소에서 전원 참조가 수행되었으므로 요청을 안전하게 처리할 수 있습니다.

드라이버가 요청 처리를 완료하면 요청이 사용 중인 각 구성 요소에 대해 PoFxIdleComponent 를 호출한 다음 요청을 완료합니다. 구성 요소를 사용하는 요청이 더 이상 없으면 전원 프레임워크는 드라이버의 ComponentIdleConditionCallback 루틴을 호출합니다.

이 콜백에서 드라이버는 해당 구성 요소가 표시되는 각 비트 마스크에서 지정된 구성 요소에 해당하는 비트를 지웁니다. 지정된 비트 마스크가 구성 요소가 유휴 상태로 전환하기 위해 해당 집합의 첫 번째 구성 요소임을 나타내는 경우 드라이버는 WdfIoQueueStop 을 호출하여 해당 보조 I/O 큐를 중지합니다. 이렇게 하면 드라이버는 해당 집합의 모든 구성 요소가 활성 상태인 경우가 아니면 큐가 요청을 디스패치하지 않도록 합니다.

위의 예제를 다시 생각해 보세요. 모든 구성 요소가 활성 상태이므로 모든 큐가 시작되었다고 가정합니다. 구성 요소 1이 유휴 상태가 되면 PoFx는 구성 요소 1에 대한 ComponentIdleConditionCallback 루틴을 호출합니다. 이 콜백에서 드라이버는 구성 요소 1을 사용하기 때문에 요청 형식 B 및 C에 대한 비트 마스크를 조작합니다. 구성 요소 1은 이러한 두 요청 유형 모두에 대해 유휴 상태가 되는 첫 번째 구성 요소이므로 드라이버는 요청 유형 B 및 C에 대한 큐를 중지합니다.

이 시점에서 구성 요소 0이 유휴 상태가 되었다고 가정합니다. 구성 요소 0에 대한 ComponentIdleConditionCallback 에서 드라이버는 요청 형식 A 및 C에 대한 비트 마스크를 조작합니다. 구성 요소 0은 요청 유형 A에 유휴 상태가 되는 첫 번째 구성 요소이므로(구성 요소 2가 여전히 활성 상태임) 드라이버는 요청 형식 A에 대한 큐를 중지합니다. 그러나 요청 형식 C의 경우 구성 요소 0이 유휴 상태가 되는 첫 번째 구성 요소가 아닙니다. 드라이버는 요청 형식 C에 대한 큐를 중지하지 않습니다(이전에 수행).

이 예제에 설명된 기술을 사용하려면 드라이버는 각 보조 큐 에 대해 EvtIoCanceledOnQueue 콜백 함수도 등록해야 합니다. 보조 큐에 있는 동안 요청을 취소해야 하는 경우 드라이버는 이 콜백을 사용하여 각 해당 구성 요소에 대해 PoFxIdleComponent 를 호출할 수 있습니다. 이렇게 하면 요청을 보조 큐로 전달하기 전에 PoFxActivateComponent 를 호출할 때 요청 처리기가 가져온 전원 참조가 해제됩니다.