zoukankan      html  css  js  c++  java
  • IORESOURCE_MEM IORESOURCE_IO

    /* Get pci port io resources described by bar #pci_bar in uio resource n. */
    static int
    igbuio_pci_setup_ioport(struct pci_dev *dev, struct uio_info *info,
    		int n, int pci_bar, const char *name)
    {
    	unsigned long addr, len;
    
    	if (sizeof(info->port) / sizeof(info->port[0]) <= n)
    		return -EINVAL;
    
    	addr = pci_resource_start(dev, pci_bar);
    	len = pci_resource_len(dev, pci_bar);
    	if (addr == 0 || len == 0)
    		return -EINVAL;
    
    	info->port[n].name = name;
    	info->port[n].start = addr;
    	info->port[n].size = len;
    	info->port[n].porttype = UIO_PORT_X86;
    
    	return 0;
    }
    
    


    static int
    igbuio_setup_bars(struct pci_dev *dev, struct uio_info *info)
    {
        int i, iom, iop, ret;
        unsigned long flags;
        static const char *bar_names[PCI_STD_RESOURCE_END + 1]  = {
            "BAR0",
            "BAR1",
            "BAR2",
            "BAR3",
            "BAR4",
            "BAR5",
        };
    
        iom = 0;
        iop = 0;
            //遍历PCI设备的6个BAR
        for (i = 0; i < ARRAY_SIZE(bar_names); i++) {
                    //PCI BAR空间不等于0且起始地址不等于0,认为为有效BAR
            if (pci_resource_len(dev, i) != 0 &&
                    pci_resource_start(dev, i) != 0) {
                            //拿到BAR的标识,如果为0x00000200则为内存空间
                flags = pci_resource_flags(dev, i);
                if (flags & IORESOURCE_MEM) {
                                    //对内存空间的PCI BAR进行映射
                    ret = igbuio_pci_setup_iomem(dev, info, iom,
                                     i, bar_names[i]);
                    if (ret != 0)
                        return ret;
                    iom++;
                            //IO空间不再讨论范围内
                } else if (flags & IORESOURCE_IO) {
                    ret = igbuio_pci_setup_ioport(dev, info, iop,
                                      i, bar_names[i]);
                    if (ret != 0)
                        return ret;
                    iop++;
                }
            }
        }
    
        return (iom != 0 || iop != 0) ? ret : -ENOENT;
    }
    
    //对内存BAR进行映射,以及填充数据结构
    static int
    igbuio_pci_setup_iomem(struct pci_dev *dev, struct uio_info *info,
                   int n, int pci_bar, const char *name)
    {
        unsigned long addr, len;
        void *internal_addr;
    
        if (n >= ARRAY_SIZE(info->mem))
            return -EINVAL;
            //拿到PCI BAR的起始地址
        addr = pci_resource_start(dev, pci_bar);
            //拿到PCI BAR的长度
        len = pci_resource_len(dev, pci_bar);
        if (addr == 0 || len == 0)
            return -1;
            //wc_activate为igb_uio.ko的参数,默认为0,会进入if条件
        if (wc_activate == 0) {
                    //对PCI BAR进行ioremap,映射到内核空间,得到可以在内核空间映射后的PCI BAR地址,虽然没什么用,因为igb_uio完全不需要操作PCI设备,因此获得此地址意义不大
            internal_addr = ioremap(addr, len);
            if (internal_addr == NULL)
                return -1;
        } else {
            internal_addr = NULL;
        }
            //填充数据结构
        info->mem[n].name = name; //PCI  BAR名,例如BAR0、BAR1
        info->mem[n].addr = addr; //PCI BAR起始地址,物理地址
        info->mem[n].internal_addr = internal_addr; //经过ioremap映射后的PCI BAR,可以供内核空间访问
        info->mem[n].size = len; //PCI BAR长度
        info->mem[n].memtype = UIO_MEM_PHYS; //PCI BAR类型,为内存BAR
        return 0;
    }
  • 相关阅读:
    Xamarin.Forms
    Docker Azure Kubernetes
    出现( linker command failed with exit code 1)错误总结(http://blog.csdn.net/hengshujiyi/article/details/21182813)
    UITextView学习笔记
    UIScrollView学习笔记
    如何学习ios(摘自知乎https://www.zhihu.com/question/20016551)
    iOS手势操作,拖动,轻击,捏合,旋转,长按,自定义(http://www.cnblogs.com/huangjianwu/p/4675648.html)
    触屏事件
    给UITextView添加链接
    IOS绘图详解(http://blog.163.com/wkyuyang_001/blog/static/10802122820133190545227/)
  • 原文地址:https://www.cnblogs.com/dream397/p/13659191.html
Copyright © 2011-2022 走看看