3.2.3.3 Busmaster DMA Device Initialization

A miniport that uses busmaster DMA to send and receive data must allocate and set up a mapping register or registers to map the shared memory buffers used for DMA. A miniport calls NdisQueryMapRegisterCount to determine how many map registers are available for the whole system. The miniport then calls NdisMAllocateMapRegisters to claim a number of these available system map registers. A miniport should allocate only as many map registers as it might need for a single DMA transfer since the registers are a shared system resource. Claiming all of the registers can adversely affect overall system performance and allocating more than can be used on a single transfer simply ties up resources that could be used by another driver.

When the miniport calls NdisMAllocateMapRegisters it must specify the largest buffer that must be mapped, corresponding to the maximum DMA capacity of the NIC. Allocating map registers is done once by a miniport, during initialization. After the registers are successfully allocated, they belong to the miniport until deallocated when the driver unloads.

A call to allocate shared memory will fail unless the caller has first allocated map registers. The amount of memory allocated for packet pool, buffer descriptors, and shared memory allocated for buffers, should be driven by the number of map registers and, possibly, by whether the driver is running on a uniprocessor or SMP machine. The type of machine is determined by calling NdisSystemProcessorCount. Typically, machines with more than one processor are server machines that will handle a higher level of network traffic than a uniprocessor machine that is, most likely, a client machine. This information is helpful in deciding how many packets and buffers to preallocate.

Besides the memory allocated for its adapter-specific structure, a busmaster DMA miniport should also set up the packet pool it will use for indicated packets. During initialization, the miniport must:

·Allocate packet pool for packet descriptors by calling NdisAllocatePacketPool. It must call NdisAllocatePacket to allocate single packet descriptors from the packet pool.

·Allocate buffer pool for buffer descriptors to map the buffers that will make up the packet by calling NdisAllocateBufferPool.

·Allocate shared memory for the number of buffers that will be used for receiving data incoming from the network by calling NdisMAllocateSharedMemory. The memory must be shared memory because it is accessible both by the NIC and the miniport. When the memory is used for sending and receiving, the NIC is using host memory. The NIC uses the physical address of the memory; the miniport uses the virtual address.

If the miniport supports multipacket receive indications up to NDIS, it must also allocate memory for the array used to pass the pointers to the packets, which can be of any type.