【80】PCIe EP driver初始化

   1. How To Write Linux PCI Drivers — The Linux Kernel documentation

PCI LIB相关API

PCI Support Library — The Linux Kernel documentation

    任何一个PCIe EP的功能都分成两部分,其中一部分是PCIe功能,另外一部门是自己的域内的功能(比如网卡、FC、SAS、NVMe、GPU),其中PCIe域内的功能的初始化都是套路。主要涉及下面几个方面:

    1、准备一个数据static struct pci_driver xxx_driver,该数据结构主要包括:

struct pci_driver定义见

pci.h - include/linux/pci.h - Linux source code (v5.15.1) - Bootlin

(1)const struct pci_device_id(存放EP的device和vendorid)

(2)int  (*probe)(struct pci_dev *dev, const struct pci_device_id *id); EP的probe函数  

(3)void (*remove)(struct pci_dev *dev);    EP的remove函数
(4)int  (*suspend)(struct pci_dev *dev, pm_message_t state);   EP进入低功耗的suspend函数
(5)int  (*resume)(struct pci_dev *dev);  EP从低功耗唤醒的resume函数  
(6)void (*shutdown)(struct pci_dev *dev);    reboot时调用的EP的shutdown函数

(7)const struct pci_error_handlers *err_handler  错误处理相关函数
(8)struct device_driver driver.pm power management相关的OPS

其中(1)、(2)、(3)是必须的。

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  (*resume)(struct pci_dev *dev);	/* Device woken up */
	void (*shutdown)(struct pci_dev *dev);
	int  (*sriov_configure)(struct pci_dev *dev, int num_vfs); /* On PF */
	int  (*sriov_set_msix_vec_count)(struct pci_dev *vf, int msix_vec_count); /* On PF */
	u32  (*sriov_get_vf_total_msix)(struct pci_dev *pf);
	const struct pci_error_handlers *err_handler;
	const struct attribute_group **groups;
	const struct attribute_group **dev_groups;
	struct device_driver	driver;
	struct pci_dynids	dynids;
};

2、init函数调用pci_regiser_driver把static struct pci_driver xxx_driver注册给PCIe EP driver框架

3、exit函数调用pci_unregiser_driver把static struct pci_driver xxx_driver从PCIe EP driver框架卸载

4、在probe函数调用下面函数,使能PCIe相关功能

(1)pci_set_drvdata:设置私有数据

(2)pci_enable_device:写command reg使能memory和io方式访问,wake up设备。

(3)pci_request_regions:使用owner name来mark IO和memory资源。

(4)pci_set_master:写command reg使能master功能,使得EP可以发起memory方式请求。

(5)dma_set_mask_and_coherent:设置DMA mask和coherent mask

(6)pci_iomap:BAR地址ioremp成虚拟地址

(7)pci_alloc_irq_vector:申请 multiple IRQs,并使能对应的中断

     ->pci_enable_msix_range:使能MSI-X功能(如果支持MSI-X中断)

     - >pci_enable_msi_range:使能MSI功能(如果支持MSI中断)

(8)request_irq申请中断

(9)pci_enable_pcie_error_reporting:写device ctrl reg使能PCIe错误上报

(10)pci_save_state保存配置空间

注意:上面的set和enable在失败时都有对应的unset和disable函数,需要调用。

5、在remove函数按照相反顺序把PCIe相关功能disbale。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linjiasen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值