분산/수집 DMA 사용

시스템 또는 버스 master 패킷 기반 DMA를 수행하는 드라이버는 분산/수집 DMA를 위해 특별히 설계된 지원 루틴을 사용할 수 있습니다. 드라이버는 Packet-Based 시스템 DMA패킷 기반 Bus-Master DMA 사용에 설명된 루틴 시퀀스를 호출하는 대신 GetScatterGatherListPutScatterGatherList를 사용할 수 있습니다.

디바이스는 이러한 루틴을 사용하기 위해 드라이버에 대한 기본 제공 분산/수집 지원이 필요하지 않습니다.

패킷 기반 DMA를 사용하는 드라이버는 분산/수집 작업에 대해 다음과 같은 일반 지원 루틴 시퀀스를 호출합니다.

  1. GetScatterGatherList 호출에서 매개 변수로 필요한 MDL에 인덱스를 가져오는 MmGetMdlVirtualAddress

  2. 드라이버가 DMA용 디바이스를 프로그래밍할 준비가 되었으며 시스템 DMA 컨트롤러 또는 버스 master 어댑터가 필요한 경우 GetScatterGatherList

    GetScatterGatherList는 시스템 DMA 컨트롤러 또는 버스 master 어댑터를 할당하고, 필요한 지도 레지스터 수를 결정하고, 할당하고, 분산/수집 목록을 채우고, DMA 컨트롤러 또는 어댑터 및 맵 레지스터를 사용할 수 있을 때 드라이버의 AdapterListControl 루틴을 호출합니다.

  3. 요청된 모든 데이터가 전송되거나 디바이스 I/O 오류로 인해 드라이버가 IRP에 실패하는 즉시 PutScatterGatherList

    PutScatterGatherList 는 어댑터 버퍼를 플러시하고, 지도 레지스터를 해제하고, 분산/수집 목록을 해제합니다. 드라이버는 버퍼의 데이터에 액세스하기 전에 PutScatterGatherList 를 호출해야 합니다.

IoGetDmaAdapter에서 반환된 어댑터 개체 포인터는 Irp-MdlAddress>에서 MDL에 대한 포인터가 필요한 MmGetMdlVirtualAddress를 제외한 각 루틴에 필요한 매개 변수입니다.

GetScatterGatherList 루틴에는 AllocateAdapterChannelMapTransfer에 대한 호출이 포함되므로 드라이버는 이러한 호출을 할 필요가 없습니다. 루틴은 다음을 매개 변수로 사용합니다.

  • IoGetDmaAdapter에서 반환된 DMA_ADAPTER 구조체에 대한 포인터

  • DMA 작업의 대상 디바이스 개체에 대한 포인터

  • Irp-MdlAddress> 에서 버퍼를 설명하는 MDL에 대한 포인터

  • Mdl에서 설명하는 버퍼의 현재 가상 주소에 대한 포인터

  • 매핑할 바이트 수

  • 전송을 수행하는 AdapterListControl 루틴에 대한 포인터

  • AdapterListControl 루틴에 전달할 드라이버 정의 컨텍스트 영역에 대한 포인터

  • 부울 값: 디바이스로 전송하는 경우 TRUE 입니다. FALSE 이면

필요한 맵 레지스터 수를 결정하고, 어댑터 채널 및 맵 레지스터를 할당하고, 분산/수집 목록을 채우고, 전송을 준비한 후 GetScatterGatherList 는 드라이버 제공 AdapterListControl 루틴을 호출합니다. AdapterListControl 루틴은 IRQL = DISPATCH_LEVEL 임의 스레드 컨텍스트에서 실행됩니다.

GetScatterGatherList 호출에서 드라이버가 제공하는 AdapterListControl 루틴은 다음과 같은 중요한 측면에서 AllocateAdapterChannel에 전달된 AdapterControl 루틴과 다릅니다.

  • AdapterListControl 루틴에는 반환 값이 없지만 AdapterControl 루틴은 IO_ALLOCATION_ACTION 반환합니다.

  • 시스템 할당 맵 레지스터에 대한 MapRegisterBase 에 대한 포인터 대신 AdapterListControl 루틴에 대한 세 번째 매개 변수는 드라이버가 DMA를 수행할 수 있는 SCATTER_GATHER_LIST 구조를 가리킵니다.

  • AdapterListControl 루틴은 AdapterControl 루틴에 필요한 작업의 하위 집합을 수행합니다.

    AdapterListControl 루틴은 AllocateAdapterChannel 또는 MapTransfer를 호출하지 않습니다. 유일한 책임은 입력 분산/수집 목록 포인터를 저장하고, 디바이스를 설정하고, 분산/수집 목록을 사용하여 DMA를 수행하는 것입니다.

분산/수집 목록 구조에는 SCATTER_GATHER_ELEMENT 배열과 배열의 요소 수가 포함됩니다. 배열의 각 요소는 물리적으로 연속된 분산/수집 영역의 길이 및 시작 물리적 주소를 제공합니다. 드라이버는 데이터 전송에서 길이와 주소를 사용합니다.

드라이버는 디바이스가 분산/수집 DMA를 지원하는지 여부에 관계없이 GetScatterGatherList 를 사용할 수 있습니다. 분산/수집 DMA를 지원하지 않는 디바이스의 경우 분산/수집 목록에는 하나의 요소만 포함됩니다.

분산/수집 루틴을 사용하면 AllocateAdapterChannel 을 호출하는 동안 성능을 향상시킬 수 있습니다(이전에 Packet-Based 시스템 DMA 사용 및 Packet-Based Bus-Master DMA사용). AllocateAdapterChannel 호출과 달리 GetScatterGatherList에 대한 두 개 이상의 호출은 한 번에 디바이스 개체에 대해 큐에 대기할 수 있습니다. 드라이버는 AdapterListControl 루틴 실행이 완료되기 전에 동일한 드라이버 개체에서 다른 DMA 작업을 위해 GetScatterGatherList를 다시 호출할 수 있습니다.

드라이버 제공 AdapterListControl 루틴에서 반환되면 GetScatterGatherList 는 맵 레지스터를 유지하지만 DMA 어댑터 구조를 해제합니다.

드라이버가 현재 IRP의 전송 요청을 충족했거나 디바이스 또는 버스 I/O 오류로 인해 IRP에 실패해야 하는 경우 버퍼에서 전송된 데이터에 액세스하려면 먼저 PutScatterGatherList 를 호출해야 합니다. PutScatterGatherList 는 어댑터 버퍼를 플러시하고 지도 레지스터 및 분산/수집 목록을 해제합니다.