Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1247504
  • 博文数量: 122
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4004
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-20 08:27
文章分类
文章存档

2016年(1)

2015年(21)

2014年(100)

分类: LINUX

2014-03-06 10:23:33


点击(此处)折叠或打开

  1. #define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
  -->


点击(此处)折叠或打开

  1. static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
  2.            size_t size,
  3.            enum dma_data_direction dir,
  4.            struct dma_attrs *attrs)
  5. {
  6.  struct dma_map_ops *ops = get_dma_ops(dev); //获取dma_ops
  7.  dma_addr_t addr;

  8.  kmemcheck_mark_initialized(ptr, size);
  9.  BUG_ON(!valid_dma_direction(dir));
  10.  addr = ops->map_page(dev, virt_to_page(ptr), //调用dma_ops的map_page接口
  11.         (unsigned long)ptr & ~PAGE_MASK, size,
  12.         dir, attrs);
  13.  debug_dma_map_page(dev, virt_to_page(ptr),
  14.       (unsigned long)ptr & ~PAGE_MASK, size,
  15.       dir, addr, true);
  16.  return addr;
  17. }
dma_ops的初始化
fs_initcall(pci_iommu_init);  -->

点击(此处)折叠或打开

  1. pci_iommu_init(){
  2. ...
  3. intel_iommu_init();//设置intel的iommu,如果存在硬件设备的话,设置dma_ops=intel_dma_ops
  4. amd_iommu_init();//设置amd的iommu,如果存在硬件设备的话,设置dma_ops=amd_dma_ops
  5. no_iommu_init();//当不存在iommu设备时,设置dma_ops=nommu_dma_ops
  6. ...
  7. }
nommu_map_page最后将地址转换为总线地址,此时的总线地址==CPU域物理地址

点击(此处)折叠或打开

  1. static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
  2.      unsigned long offset, size_t size,
  3.      enum dma_data_direction dir,
  4.      struct dma_attrs *attrs)
  5. {
  6.  dma_addr_t bus = page_to_phys(page) + offset; //总线地址就等于物理地址。
  7.  WARN_ON(size == 0);
  8.  if (!check_addr("map_single", dev, bus, size))
  9.   return bad_dma_address;
  10.  flush_write_buffers();
  11.  return bus;
  12. }




阅读(11213) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~