struct device dev;&nbs…

一:dma_mask与coherent_dma_mask的定义

在linux内核中,引入了platform_device与platform_driver,这样就很方便了平台的设备与驱动。在include\linux\platform_device.h下:

struct platform_device {
 const char * name;
 int  id;
 struct device dev;
 u32  num_resources;
 struct resource * resource;

 const struct platform_device_id *id_entry;

 
 struct pdev_archdata archdata;
};

而struct device dev,在include\linux\device.h中:

struct device {
 struct device  *parent;

 struct device_private *p;

 struct kobject kobj;
 const char  *init_name;
 struct device_type *type;

 struct mutex  mutex; 

 struct bus_type *bus;  
 struct device_driver *driver; 
 void  *platform_data; 
 struct dev_pm_info power;

#ifdef CONFIG_NUMA
 int  numa_node; 
#endif
 u64  *dma_mask; 
 u64  coherent_dma_mask;

 struct device_dma_parameters *dma_parms;

 struct list_head dma_pools; 

 struct dma_coherent_mem *dma_mem;
 
 struct dev_archdata archdata;
#ifdef CONFIG_OF
 struct device_node *of_node;
#endif

 dev_t   devt; 

 spinlock_t  devres_lock;
 struct list_head devres_head;

 struct klist_node knode_class;
 struct class  *class;
 const struct attribute_group **groups; 

 void (*release)(struct device *dev);
};
dma_mask与 coherent_dma_mask这两个参数表示它能寻址的物理地址的范围,内核通过这两个参数分配合适的物理内存给 device。其中dma_coherent_mask则作用于申请一致性DMA缓冲区。因为不是所有的硬件都能够支持64bit的地址宽度。如果 addr_phy 是一个物理地址,且 (u64)addr_phy <= *dev->dma_mask,那么 该 device 就可以寻址该物理地址。如果 device 只能寻址32位地址,那么 mask 应为 0xffffffff。依此类推。

例如,在linux2.6.38中:

static u64 nuc900_device_usb_ehci_dmamask = 0xffffffffUL;

static struct platform_device nuc900_device_ehci = {
        .name    = "nuc900-ehci",
        .id    = -1,
        .num_resources   = ARRAY_SIZE(nuc900_ehci_resource),
        .resource   = nuc900_ehci_resource,
        .dev              = {
                .dma_mask = &nuc900_device_usb_ehci_dmamask,
                .coherent_dma_mask = 0xffffffffUL
        }
};

二:sample code


这段代码摘录自 arch\arm\mm\dma-mapping.c

    u64 limit;
   
    size = PAGE_ALIGN(size);
    //这个 limit 就是通过 mask 计算得到的设备最大寻址范围。
    limit = (mask + 1) & ~mask;
    //当 size 超出 limit 时,说明分配的地址超出了设备的最大寻址能力,这时返回错误。
    if ((limit && size >= limit) ||
        size >= (CONSISTENT_END - CONSISTENT_BASE)) {
        printk(KERN_WARNING "coherent allocation too big "
               "(requested %#x mask %#llx)\n", size, mask);
        goto no_page;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值