다음을 통해 공유


MapTransferEx 루틴 사용

MapTransferEx 루틴은 이전에 할당된 DMA 리소스 집합을 초기화하고 DMA 전송을 시작합니다. 이 루틴은 DMA 작업 인터페이스 버전 3에서 사용할 수 있습니다. 이 인터페이스의 버전 3은 Windows 8 부터 지원됩니다. DMA 작업 인터페이스에 대한 자세한 내용은 DMA_OPERATIONS 참조하세요.

MapTransferEx와 MapTransfer 비교

MapTransferExMapTransfer 루틴의 향상된 버전입니다. 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 값의 위치를 가리킵니다.