Share via


Common-Buffer Bus-Master DMA 사용

Bus-Master DMA 사용에 설명된 대로 버스 master DMA 디바이스용 일부 드라이버는 공통 버퍼 DMA를 단독으로 사용하고 일부는 패킷 기반 DMA와 함께 공통 버퍼 DMA를 사용합니다.

공통 버퍼 DMA를 경제적으로 사용합니다. 공통 버퍼를 설정하면 버스 master 어댑터를 나타내는 어댑터 개체와 연결된 맵 레지스터의 일부(또는 요청된 버퍼 크기에 따라 모두)가 묶일 수 있습니다.

PAGE_SIZE 청크 또는 단일 할당을 사용하는 것과 같이 공통 버퍼 영역을 경제적으로 설정하면 패킷 기반 DMA 작업에 더 많은 지도 레지스터를 사용할 수 있습니다. 또한 더 많은 시스템 메모리를 다른 용도로 사용할 수 없으므로 전반적인 드라이버 및 시스템 성능이 향상됩니다.

버스 master DMA에 대한 공통 버퍼를 설정하려면 버스 master DMA 디바이스 드라이버가 IoGetDmaAdapter에서 반환된 어댑터 개체 포인터를 사용하여 AllocateCommonBuffer를 호출해야 합니다. 일반적으로 드라이버는 IRP_MN_START_DEVICE 요청에 대해 DispatchPnP 루틴에서 이 호출을 수행합니다. 드라이버는 드라이버가 로드된 상태로 유지되는 동안 DMA 작업에 버퍼를 반복적으로 사용하는 경우에만 공통 버퍼를 할당해야 합니다. 다음 다이어그램에서는 AllocateCommonBuffer에 대한 이러한 호출을 보여 줍니다.

버스 master dma에 대한 공통 버퍼 할당을 보여 주는 다이어그램

이전 다이어그램에 LengthForBuffer로 표시된 버퍼에 대해 요청된 크기는 공통 버퍼에 대한 가상-논리 매핑을 제공하는 데 사용해야 하는 맵 레지스터 수를 결정합니다. BYTES_TO_PAGES 매크로를 사용하여 필요한 최대 페이지 수(BYTES_TO_PAGES(LengthForBuffer))를 확인합니다. 이 값은 IoGetDmaAdapter에서 반환된 NumberOfMapRegisters보다 클 수 없습니다.

또한 호출자는 다음을 제공해야 합니다.

  • 캐싱을 사용하도록 설정해야 하는지 여부를 나타내는 부울 값

    참고 이 값은 무시됩니다. 운영 체제는 할당할 공통 버퍼에서 캐시된 메모리를 사용하도록 설정할지 여부를 결정합니다. 이러한 결정은 프로세서 아키텍처 및 디바이스 버스를 기반으로 합니다.

    x86 기반, x64 기반 및 Itanium 기반 프로세서가 있는 컴퓨터에서는 캐시된 메모리가 사용됩니다.

    Arm 또는 Arm 64 기반 프로세서가 있는 컴퓨터에서 운영 체제는 모든 디바이스에 대해 캐시된 메모리를 자동으로 사용하도록 설정하지 않습니다. 시스템은 각 디바이스에 대한 ACPI_CCA 메서드를 사용하여 디바이스가 캐시 일관성인지 여부를 확인합니다.

  • AllocateCommonBuffer에서 반환되는 버퍼에 대한 디바이스 액세스 가능한 기본 논리 주소(이전 다이어그램의 BufferLogicalAddress)를 포함하는 드라이버 정의 변수에 대한 포인터입니다.

호출이 성공하면 AllocateCommonBuffer 는 버퍼에 대한 드라이버 액세스 가능 기본 가상 주소(이전 다이어그램의 BufferVirtualAddress)를 반환합니다. 이 가상 주소는 드라이버가 디바이스 확장, 컨트롤러 확장 또는 기타 드라이버에 액세스할 수 있는 상주 스토리지 영역(드라이버가 할당한 비페이지 풀)에 저장해야 합니다.

AllocateCommonBuffer는 버퍼에 대한 메모리를 할당할 수 없는 경우 NULL 을 반환합니다. 반환된 기본 가상 주소가 NULL인 경우 드라이버는 시스템의 패킷 기반 DMA 지원을 단독으로 사용해야 하거나 드라이버가 IRP_MN_START_DEVICE 요청에 실패하여 STATUS_INSUFFICIENT_RESOURCES 반환해야 합니다.

그렇지 않으면 드라이버는 할당된 공통 버퍼를 DMA 전송을 위한 드라이버 및 어댑터 액세스 가능한 스토리지 영역으로 사용할 수 있습니다.

PnP 관리자가 디바이스를 중지하거나 제거하는 IRP를 보내면 드라이버는 FreeCommonBuffer 를 호출하여 할당된 각 공통 버퍼를 해제해야 합니다.