点击(此处)折叠或打开
- #define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
点击(此处)折叠或打开
-
static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
-
size_t size,
-
enum dma_data_direction dir,
-
struct dma_attrs *attrs)
-
{
-
struct dma_map_ops *ops = get_dma_ops(dev); //获取dma_ops
-
dma_addr_t addr;
-
-
kmemcheck_mark_initialized(ptr, size);
-
BUG_ON(!valid_dma_direction(dir));
-
addr = ops->map_page(dev, virt_to_page(ptr), //调用dma_ops的map_page接口
-
(unsigned long)ptr & ~PAGE_MASK, size,
-
dir, attrs);
-
debug_dma_map_page(dev, virt_to_page(ptr),
-
(unsigned long)ptr & ~PAGE_MASK, size,
-
dir, addr, true);
-
return addr;
- }
fs_initcall(pci_iommu_init); -->
点击(此处)折叠或打开
-
pci_iommu_init(){
-
...
-
intel_iommu_init();//设置intel的iommu,如果存在硬件设备的话,设置dma_ops=intel_dma_ops
-
amd_iommu_init();//设置amd的iommu,如果存在硬件设备的话,设置dma_ops=amd_dma_ops
-
no_iommu_init();//当不存在iommu设备时,设置dma_ops=nommu_dma_ops
-
...
- }
点击(此处)折叠或打开
-
static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
-
unsigned long offset, size_t size,
-
enum dma_data_direction dir,
-
struct dma_attrs *attrs)
-
{
-
dma_addr_t bus = page_to_phys(page) + offset; //总线地址就等于物理地址。
-
WARN_ON(size == 0);
-
if (!check_addr("map_single", dev, bus, size))
-
return bad_dma_address;
-
flush_write_buffers();
-
return bus;
- }