MapTransferEx 루틴 사용
MapTransferEx 루틴은 이전에 할당된 DMA 리소스 집합을 초기화하고 DMA 전송을 시작합니다. 이 루틴은 DMA 작업 인터페이스 버전 3에서 사용할 수 있습니다. 이 인터페이스의 버전 3은 Windows 8 부터 지원됩니다. DMA 작업 인터페이스에 대한 자세한 내용은 DMA_OPERATIONS 참조하세요.
MapTransferEx와 MapTransfer 비교
MapTransferEx 는 MapTransfer 루틴의 향상된 버전입니다. MapTransfer 는 Windows 2000 버전 1부터 모든 버전의 DMA 작업 인터페이스에서 사용할 수 있습니다. MapTransfer에 대한 한 번의 호출은 MDL에서 하나의 연속된 물리적 메모리 블록을 매핑할 수 있습니다. 그러나 복잡한 DMA 전송에 대한 데이터 버퍼는 MDL 체인에서 설명할 수 있으며 체인의 각 MDL은 물리적으로 연속된 메모리의 여러 블록을 설명할 수 있습니다. MapTransfer를 사용하여 이러한 버퍼를 전송하려면 드라이버가 MapTransfer를 많이 호출해야 합니다. 일반적으로 이러한 호출은 중첩된 루프 쌍 내에서 이루어집니다. 내부 루프는 연속 물리적 메모리의 한 블록에서 각 MDL의 다음 블록으로 반복되고 외부 루프는 MDL 체인의 한 MDL에서 다음 MDL로 반복됩니다.
반면 MapTransferEx 에 대한 한 번의 호출은 복잡한 DMA 전송을 위해 전체 데이터 버퍼를 전송할 수 있습니다. 다음 세 개의 MapTransferEx 매개 변수는 전송에 사용할 버퍼 메모리에 대해 설명합니다.
매개 변수 | Description |
---|---|
Mdl | 하나 이상의 MDL 체인에 있는 첫 번째 MDL에 대한 포인터입니다. MDL 체인에 대한 자세한 내용은 MDL 사용을 참조하세요. |
Offset | MDL 체인에서 설명하는 메모리 시작부터 버퍼의 바이트 오프셋입니다. |
길이 | 데이터 버퍼의 길이(바이트)를 포함하는 위치에 대한 포인터입니다. |
MapTransferEx 호출이 시작될 때 MapTransferEx 루틴은 MDL 체인을 통해 진행되어 버퍼의 시작을 찾습니다. 버퍼의 시작은 Offset 매개 변수로 지정됩니다. 다음으로, 버퍼의 시작부터 끝까지 작업하는 MapTransferEx 는 목록의 각 버퍼 조각이 MDL 체인의 물리적으로 연속된 메모리 블록인 분산/수집 목록을 생성합니다. 이 목록을 생성하기 위해 MapTransferEx 는 물리적으로 연속된 하나의 메모리 블록에서 각 MDL 내의 다음 블록으로, 한 MDL에서 MDL 체인의 다음 블록으로 단계를 수행합니다. 목록 생성은 분산/수집 목록에 설명된 버퍼 메모리의 총 양이 *Length 입력 매개 변수에 지정된 바이트 수와 같으면 완료됩니다. 결과 분산/수집 목록에서 버퍼 조각의 순서는 MDL 체인에서 물리적으로 연속된 블록의 순서와 일치합니다.
MapTransferEx에 대한 여러 호출
MapTransferEx 가 한 번의 호출로 전체 DMA 데이터 버퍼를 항상 전송하지 못할 수도 있습니다. 다음 목록에서는 전송을 완료하기 위해 MapTransferEx 를 두 번 이상 호출해야 할 수 있는 몇 가지 조건에 대해 설명합니다.
- DMA 어댑터에는 맵 레지스터가 필요하며 어댑터에 할당된 맵 레지스터의 수는 전체 버퍼를 설명하기에 충분하지 않습니다.
- 드라이버가 분산/수집 목록을 포함하기 위해 할당한 스토리지는 전체 버퍼에 대한 분산/수집 목록을 포함할 만큼 크지 않습니다.
- 전송은 하드웨어 분산/수집 목록에 지정할 수 있는 버퍼 조각의 수를 제한하는 시스템 DMA 컨트롤러를 사용합니다.
이러한 모든 경우에서 MapTransferEx 는 한 번의 호출에서 가능한 한 많은 데이터 버퍼를 매핑하고 호출에 의해 매핑된 버퍼의 양을 드라이버에 알려줍니다. 이전 목록에는 전송을 완료하기 위해 MapTransferEx 를 두 번 이상 호출해야 할 수 있는 플랫폼별 캐시 동작과 같은 다른 조건이 포함되지 않습니다. 향후 하드웨어 플랫폼은 DMA 전송 길이에 추가 제약 조건을 적용할 수 있습니다. 이러한 이유로 드라이버 개발자는 MapTransferEx 가 한 번의 호출로 전체 DMA 데이터 버퍼를 매핑할 수 없는 경우를 올바르게 처리하도록 드라이버를 디자인해야 합니다.
MapTransferEx를 호출하기 전에 호출자는 *Length 매개 변수를 매핑해야 하는 DMA 데이터 버퍼의 바이트 수로 설정합니다. 반환하기 전에 MapTransferEx 는 *Length 를 실제로 호출에 의해 매핑된 버퍼의 바이트 수로 설정합니다. MapTransferEx 호출이 *Length 입력 값에 지정된 대로 전체 버퍼 길이를 매핑할 수 없는 경우 *Length의 출력 값은 입력 값보다 작습니다. DMA 전송에 둘 이상의 MapTransferEx 호출이 필요한 경우 호출 드라이버는 다음 호출에 대한 *길이 입력 값을 지정하기 전에 한 호출에서 *Length 출력 값을 가져와야 합니다.
예를 들어 MapTransferEx 호출이 오프셋 = B 및 *Length = N(입력 시)이 있는 버퍼에서 X 바이트만 전송할 수 있는 경우 반환 시 *Length = X입니다. MapTransferEx에 대한 다음 호출의 경우 드라이버는 Offset = B + X 및 *Length = N - X를 설정해야 합니다. 두 호출 모두에서 수정 없이 동일한 MDL 체인이 사용됩니다.
호출자가 DmaCompletionRoutine을 지정하는 경우 MapTransferEx는 실행하도록 DmaCompletionRoutine을 예약하기 전에 *Length 출력 값을 씁니다. 이 동작은 DmaCompletionRoutine이 실행되기 전에 업데이트된 *Length 값을 항상 사용할 수 있도록 합니다. 예를 들어 DMA 전송에 두 개의 MapTransferEx 호출이 필요한 경우 첫 번째 호출이 예약하는 DmaCompletionRoutine 은 첫 번째 호출에서 *Length 출력 값을 가져올 수 있습니다. 그런 다음 루틴은 이 값을 사용하여 두 번째 호출에 대한 *길이 입력 값을 계산할 수 있습니다. 일반적으로 Length 매개 변수는 DmaCompletionRoutine에 매개 변수로 제공되는 *CompletionContext 값의 위치를 가리킵니다.