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;
    }
  • 相关阅读:
    FIR滤波器相关解释
    FIR数字信号滤波器
    图像中的插值
    对DDS的深度认识
    嵌入式媒体处理(EMP)中的编码和解码
    FPGA噪声干扰
    视频压缩概述
    ALTERA DDRII IP核使用
    MyEclipse的使用
    Java开发API文档资源
  • 原文地址:https://www.cnblogs.com/dream397/p/13659191.html
Copyright © 2011-2022 走看看