PCI驱动

news/2024/11/15 1:51:10/
一、PCI总线
1、PCI桥
Host/PCI桥:用于连接CPU与PCI根总线,即“北桥芯片组”
PCI/ISA桥:用于连接PCI与旧的ISA总线,即“南桥芯片组”
PCI-to-PCI桥:用于连接PCI主总线与次总线


2、pci_bus结构体(PCI总线结构体)
定义在include/linux/pci.h中
struct pci_bus {
struct list_head node; /* 链表元素node*/
struct pci_bus *parent; /* PCI总线的父总线*/
struct list_head children; /* 子总线链表头 */
struct list_head devices; /* PCI总线上的设备链表*/
struct pci_dev *self; /* 指向应用该PCI总线*/
struct list_head slots; /* PCI总线上的插槽链表*/
struct resource *resource[PCI_BRIDGE_RESOURCE_NUM];
struct list_head resources; /* 路由到该总线上的地址空间资源链表*/


struct pci_ops *ops; /* PCI总线的访问配置空间的函数集 */
void *sysdata; /* 系统特定的数据hook for sys-specific extension */
struct proc_dir_entry *procdir; /* /proc/bus/pci对应的目录项*/


unsigned char number; /* 总线数*/
unsigned char primary; /* 总线号 */
unsigned char secondary; /* 次总线号 */
unsigned char subordinate; /* 最大总线号 */
unsigned char max_bus_speed; /* enum pci_bus_speed */
unsigned char cur_bus_speed; /* enum pci_bus_speed */


char name[48];


unsigned short  bridge_ctl; /* manage NO_ISA/FBB/et al behaviors */
pci_bus_flags_t bus_flags; /* Inherited by child busses */
struct device *bridge;
struct device dev;
struct bin_attribute *legacy_io; /* legacy I/O for this bus */
struct bin_attribute *legacy_mem; /* legacy mem */
unsigned int is_added:1;
};


3、pci_dev结构体(PCI设备结构体)
定义在include/linux/pci.h中
struct pci_dev {
struct list_head bus_list; /* node in per-bus list */
struct pci_bus *bus; /* 这个设备所在的PCI总线的pci_bus结构体 */
struct pci_bus *subordinate; /*这个设备所桥接的下级总线*/


void *sysdata; /* 系统的扩展数据*/
struct proc_dir_entry *procent; /*/proc/bus/pci对应的目录项 */
struct pci_slot *slot; /* 这个设备位于的物理插槽*/


unsigned int devfn; /* 设备的功能号 */
unsigned short vendor;//PCI厂商ID
unsigned short device;//PCI设备ID
unsigned short subsystem_vendor;//子系统厂商ID
unsigned short subsystem_device;//子系统设备ID
unsigned int class; /* PCI设备的类别*/
u8 revision; /* PCI版本 */
u8 hdr_type; /* PCI配置空间头类型 */
u8 pcie_cap; /* PCI-E capability offset */
u8 pcie_type; /* PCI-E 设备/端口 类型 */
u8 rom_base_reg; /* 配置寄存器在ROM中的位置 */
u8 pin;   /* 中断引脚 */


struct pci_driver *driver; /*对应的驱动pci_driver结构体 */
u64 dma_mask; /* 总线地址为掩码*/
struct device_dma_parameters dma_parms;


pci_power_t     current_state;  /* 当前操作状态*/
int pm_cap;
unsigned int pme_support:5; /* Bitmask of states from which PME#
  can be generated */
unsigned int pme_interrupt:1;
unsigned int d1_support:1; /* Low power state D1 is supported */
unsigned int d2_support:1; /* Low power state D2 is supported */
unsigned int no_d1d2:1; /* Only allow D0 and D3 */
unsigned int mmio_always_on:1; /* disallow turning off io/mem
  decoding during bar sizing */
unsigned int wakeup_prepared:1;
unsigned int d3_delay; /* D3->D0 transition time in ms */


#ifdef CONFIG_PCIEASPM
struct pcie_link_state *link_state; /* ASPM link state. */
#endif
pci_channel_state_t error_state; /* current connectivity state */
struct device dev; /* 通用设备接口 */


int cfg_size; /* 配置空间大小 */


unsigned int irq;
struct resource resource[DEVICE_COUNT_RESOURCE]; /* 该设备可能用到的资源 */
resource_size_t fw_addr[DEVICE_COUNT_RESOURCE]; /* FW-assigned addr */


/* These fields are used by common fixups */
unsigned int transparent:1; /* Transparent PCI bridge */
unsigned int multifunction:1;/* Part of multi-function device */
/* keep track of device state */
unsigned int is_added:1;
unsigned int is_busmaster:1; /* device is busmaster */
unsigned int no_msi:1; /* device may not use msi */
unsigned int block_ucfg_access:1; /* userspace config space access is blocked */
unsigned int broken_parity_status:1; /* Device generates false positive parity */
unsigned int irq_reroute_variant:2; /* device needs IRQ rerouting variant */
unsigned int msi_enabled:1;
unsigned int msix_enabled:1;
unsigned int ari_enabled:1; /* ARI forwarding */
unsigned int is_managed:1;
unsigned int is_pcie:1; /* Obsolete. Will be removed.
  Use pci_is_pcie() instead */
unsigned int    needs_freset:1; /* Dev requires fundamental reset */
unsigned int state_saved:1;
unsigned int is_physfn:1;
unsigned int is_virtfn:1;
unsigned int reset_fn:1;
unsigned int    is_hotplug_bridge:1;
unsigned int    __aer_firmware_first_valid:1;
unsigned int __aer_firmware_first:1;
pci_dev_flags_t dev_flags;
atomic_t enable_cnt; /* pci_enable_device has been called */


u32 saved_config_space[16]; /* config space saved at suspend time */
struct hlist_head saved_cap_space;
struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
int rom_attr_enabled; /* has display of the rom attribute been enabled? */
struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
#ifdef CONFIG_PCI_MSI
struct list_head msi_list;
#endif
struct pci_vpd *vpd;
#ifdef CONFIG_PCI_IOV
union {
struct pci_sriov *sriov; /* SR-IOV capability related */
struct pci_dev *physfn; /* the PF this VF is associated with */
};
struct pci_ats *ats; /* Address Translation Service */
#endif
}


4、PCI头部寄存器定义在include/linux/pci_regs.h中


5、pci_ops结构体
是PCI总线使用的配置空间访问操作的具体实现
定义在include/linux/pci.h中
struct pci_ops {
int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val);
int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
};


二、PCI设备驱动的组成
一个通过PCI总线与系统连接的设备驱动应包括PCI驱动、设备本身的驱动;
1、pci_driver结构体
定义在include/linux/pci.h中
struct pci_driver {
struct list_head node;
const char *name;
const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */
int  (*probe)  (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
int  (*suspend) (struct pci_dev *dev, pm_message_t state); /* Device suspended */
int  (*suspend_late) (struct pci_dev *dev, pm_message_t state);
int  (*resume_early) (struct pci_dev *dev);
int  (*resume) (struct pci_dev *dev);                /* Device woken up */
void (*shutdown) (struct pci_dev *dev);
struct pci_error_handlers *err_handler;
struct device_driver driver;
struct pci_dynids dynids;
};


2、PCI驱动程序模板
static struct pci_device_id xxx_pci_tbl[] __initdate={
{
PCI_VENDOR_IO_DEMO,
PCI_DEVICE_ID_DEMO,
...
}
}
static void xxx_interrupt(int irq,coid *dev_id,strutc pt_reg *reg)
{
...
}
static int xxx_open(struct inode *indoe,struct file *file)
{
request_irq(xxx_irq,&xxx_interrupt,...);//申请呢中断
...
}
static int xxx_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
...
}
//设备文件操作接口
static struct file_operations xxx_fops={
.owner=THIS_MODULE,
.open=xxx_open,
.ioctl=xxx_ioctl
};
//probe方法
static int  xxx_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
pci_enable_device(dev);//启动pci设备
//读取PCI设备信息
iobase=pci_resource_start(dev,i);
...
pci_set_master(dev);//设置成总线DMA模式
pci_request_regions(dev);//申请io资源
//注册字符设备
cdev_init(xxx_dev,&xxx_fops);
register_chardev_region(xxx_dev_no,1..);
cdev_add(xxx_cdev);
return 0;
}
//remove函数
static void (*remove) (struct pci_dev *dev)
{
pci_release_region(dev);//释放io资源
pci_disable_device(dev);//停止PCI设备
unregister_chrdev_region(xxx_dev_no,1...);//释放设备号
cdev_del(&xxx_dev.cdev);//释放字符设备
...
}
//设备模块信息
static struct pci_driver xxx_pci_driver={
.name=xxx_module_name,
.id_table=xxx_pci_tbl,
.probe=xxx_probe,
.remove=xxx_remove
};
static int __init xxx_init_module(void)
{
//注册pci驱动
pci_register_driver(&xxx_pci_driver);
}
static int __exit xxx_exit_module(void)
{
//卸载pci驱动
pci_unregister_driver(&xxx_pci_driver);
}
//驱动加载函数
module_init(xxx_init_module);
//驱动卸载函数
module_exit(xxx_exit_module);

http://www.ppmy.cn/news/274651.html

相关文章

pci驱动框架

PCI 总线架构主要被分成三部分: 1.PCI 设备。符合 PCI 总线标准的设备就被称为 PCI 设备,PCI 总线架构中可以包含多个 PCI 设备。图中的 Audio 、LAN 都是一个 PCI 设备。PCI 设备同时也分为主设备和目标设备两种,主设备是一次访问操作的发…

pci设备驱动

原文地址:https://www.cnblogs.com/xiaoya901109/archive/2012/12/14/2818057.html 一,初始化设备模块 当Linux内核启动并完成对所有PCI设备进行扫描、登录和分配资源等初始化操作的同时,会建立起系统中所有PCI设备的拓扑结构,此后…

PCI驱动开发学习笔记(一)

PCIE简介 PCIe作为串行总线的一种,它的发展必然和另一种总线架构密不可分:并行总线。 像PCIe接口的显卡、声卡、网卡,都属于功能设备,在PCIe规范中,我们统称为Endpoint(简称EP)。还有其他两类设…

Linux PCI总线驱动-1

Linux PCI总线驱动-1 一、PCI总线介绍1. PCI介绍2. PCI接口3. PCI-X介绍4. PCI-E介绍4.1 下图从上到下依次是PCIEX16,X1,X44.2 PCI-E各版本的传输速度4.3 PCI-E不同传输通道数设备的金手指数和长度4.4 三种接口的传输速度比较 二、pci设备基础知识2.1 内…

PCI驱动程序实现

1、数据结构: PCI设备上有三种地址空间:PCI的I/O空间、PCI的存储空间和PCI的配置空间。CPU可以访问PCI设备上的所有地址空间,其中I/O空间和存储空间提供给设备驱动程序使用,而配置空间则由Linux内核中的PCI初始化代码使用。内核在…

vxworks pci驱动解析

PCI驱动分为两种类别: 1.CPU通过io方式访问的PCI设备驱动 2.dma方式的PCI设备驱动 其实就是两种方式 在io方式下访问PCI/SRIO设备 通过outbound寄存器将本地存储器映射到remote端pci设备 --------------------------------IOMMU过程 同时一般需要将CPU物理地址转换成…

PCI驱动使用函数

PCI总线驱动 1.pci驱动注册 pci_register_driver(struct pci_driver *drv) static struct pci_driver hamachi_driver { .name DRV_NAME, .id_table hamachi_pci_tbl, .probe hamachi_init_one, .remove …

linux 查看 pci 设备驱动,如何写linux pci设备驱动程序

PCI总线应用领域及其广泛并且令人惊奇。不同的pci设备有不同的需求以及不同的问题。因此,在linux内核中pci层支持就非常重要啦。本文档就是想为驱动程序设计开发人员解决pci处理中的各种问题。 0.Pci设备驱动程序的结构 现在有两种风格的的pci驱动程序结构:新风格的驱动(即让…