1. exallocatepool()
函數說明:
exallocatepool allocates pool memory of the specified type and returns a pointer to the allocated
block.
函數定義:
pvoid exallocatepool(
__in pool_type pooltype,
__in size_t numberofbytes
);
代碼中用來配置設定裝置描述dma adepter裝置的特性(device_description),作為參數傳遞給iogetdmaadapter()函數。在調用iogetdmaadapter()函數之前就要對pdevice_description結構進行指定各種特性。
實際中這樣使用:
pdevice_description devicedescription = (pdevice_description) exallocatepool
(pagedpool, sizeof(device_description));
2. rtlzeromemory()
函數說明:
the rtlzeromemory routine fills a block of memory with zeros, given a pointer to the block and the length, in bytes, to be filled.
函數定義:
void rtlzeromemory(
__in void unaligned *destination,
__in size_t length
3. iogetdmaadapter()
the iogetdmaadapter routine returns a pointer to the dma adapter structure for a physical device object.
struct _dma_adapter* iogetdmaadapter(
__in_opt pdevice_object physicaldeviceobject,
__in struct _device_description *devicedescription,
__out pulong numberofmapregisters
實際代碼中這樣使用:
ulong numberofmapregisters=100;
pdx->dmaadapter=iogetdmaadapter(pdx->nextstackdevice,devicedescription,&numberofmapregisters);// nextstackdevice在adddevice函數中已經attach了。
4. allocatecommonbuffer()
the allocatecommonbuffer routine allocates memory and maps it so that it is simultaneously accessible from both the processor and a device for dma operations。
pvoid allocatecommonbuffer(
__in pdma_adapter dmaadapter,
__in ulong length,
__out pphysical_address logicaladdress,
__in boolean cacheenabled
注:第一個參數是iogetdmaadapter()傳回的,第三個參數是自己頂一頂一個實體位址類型,用來接收配置設定得到的實體位址首址。
傳回值:傳回值為虛拟位址,供上層使用
pdx->descaddress=pdx->allocatecommonbuffer(pdx->dmaadapter,(ulong)desc_address*port_num,&pdx->desclogicaladdress,false);
附:使用該函數必不可少的會使用下面的函數
pdx->dmaadapter=iogetdmaadapter(pdx->nextstackdevice,devicedescription,&numberofmapregisters);
//建立一個dma擴充卡
pdx->allocatecommonbuffer=*pdx->dmaadapter->dmaoperations->allocatecommonbuffer;
//配置設定連續的實體記憶體dma函數
pdx->freecommonbuffer = *pdx->dmaadapter->dmaoperations->freecommonbuffer;
//釋放連續的實體記憶體dma函數
pdx->putdmaadapter=*pdx->dmaadapter->dmaoperations->putdmaadapter;
//釋放dma adapter對象
當通過allocatecommonbuffer()配置設定得到位址之後需要把這個位址分成兩部分來處理,與硬體打交道的需要用logicaddress 與 應用程式打交道需用 virtual address.
最好将allocatecommonbuffer()函數取得的這兩個位址儲存到裝置擴充中特定的變量中(根據記憶體塊的用處),便于以後操作。可以這樣做:
pdx->rxdescvirbase=(pchar)pdx->descaddress;
pdx->rxdescphybase=(ulong)(pdx->desclogicaladdress.lowpart); //實體位址
write_register_ulong( (pulong)&pdx->phbaregs->rxaddr_des_0,pdx->rx_fc_des
c_buf_phy[0]+16);
write_register_ulong( (pulong)&pdx->phbaregs->rxaddr_des_addr0_ptr,pdx->r
x_fc_desc_buf_phy[0]+4);
注意前面的 +16 和 +4 實際分别代表美一塊記憶體的的偏移位置,由于我們定義了這塊記憶體的結構,并在裡面布局,+16 其實代表了struct rx_fc_ctl_tab 結構中的 struct rx_fc_desc_entity entity[rx_fc_desc_num] 域,這裡又是一個結構,也就是我們最終會用到的“描述符”。注意:我們這裡的操作是将一個位址寫到一個寄存器,這個位址必須是實體位址,也就是前面說的logicaddress。這裡phbaregs是通過pdx->phbaregs=(phba_regs)pdx->regsbase;
獲得的,也就是在cmresourcetypememory傳過來時解析,代表硬體提供的dma寄存器首址。
對于硬體的初始化就是通過write_register_ulong()函數來完成,針對裝置的起始位址來進行偏移,自己定義結構來比對各個寄存器的内容,注意這個自己定義的結構一定要嚴格跟硬體寄存器相同,一bit都不能差。