linux下 usb 和pci设备的reset

1. 什么是设备的reset

设备的reset是为了让设备的寄存器恢复初始状态

设备的寄存器

设备的寄存器分为两种,一种是不可改变的,静态寄存器;一种是可改变的,动态寄存器。
静态寄存器的恢复初始状态只能通过完全断电来完成
动态寄存器的恢复初始状态可以通过向reset寄存器写值,来完成动态寄存器的恢复。
上面两种reset 分别叫做cold reset 和 hot reset。

设备的结构体

reset和设备的新发现是完全不一样的,其本质在于reset会保持为这个设备分配的资源不变,包含为这个设备生成的一系列结构体和分配的内存空间等,只是重置动态寄存器。

usb device reset

开门见山, usb 设备的reset是通过对usb设备所连接的hub 的port 重新init来完成的,重新枚举了一次usb设备。
函数调用顺序:usb_reset_device->usb_reset_and_verify_device->hub_port_init->hub_port_reset

pci device reset

pci 设备的reset 比较复杂,主要是因为pci device 有很多不同层次的reset,它会一个个尝试,程度从浅到深,哪个层次的reset成功就直接返回,不会执行更深层次的reset。

pci 设备的function, slot, bus

pci设备可以是个复合设备,比如usb2.0 主机控制器,就是一个usb1.1 主机控制器和一个usb2.0 主机控制器集成在一起,成了一个复合设备。每个主控是一个function,合在一起成了一个device,对与linux内核来说,就是两个设备。
因此对pci设备的复位,其实对pci function的复位。对整个device reset,就需要复位这个device所在pci插槽进行复位,即对slot进行复位。
如果一个pci设备是一个pci bridge,那么对这个设备的复位,必然会导致对连在这个bridge(bus)上所有设备reset。

pci function reset

函数的调用堆栈是
pci_reset_function->__pci_reset_function_locked

__pci_reset_function_locked 是重点

int __pci_reset_function_locked(struct pci_dev *dev)
{
        int rc;

        might_sleep();

        /*   
         * A reset method returns -ENOTTY if it doesn't support this device
         * and we should try the next method.
         *
         * If it returns 0 (success), we're finished.  If it returns any
         * other error, we're also finished: this indicates that further
         * reset mechanisms might be broken on the device.
         */
        rc = pci_dev_specific_reset(dev, 0);
        if (rc != -ENOTTY)
                return rc;
        if (pcie_has_flr(dev)) {
                rc = pcie_flr(dev);
                if (rc != -ENOTTY)
                        return rc;
        }    
        rc = pci_af_flr(dev, 0);
        if (rc != -ENOTTY)
                return rc;
        rc = pci_pm_reset(dev, 0);
        if (rc != -ENOTTY)
                return rc;
        rc = pci_dev_reset_slot_function(dev, 0);
        if (rc != -ENOTTY)
                return rc;
        return pci_parent_bus_reset(dev, 0);
}
EXPORT_SYMBOL_GPL(__pci_reset_function_locked);

pci_dev_specific_reset
pcie_flr
pci_af_flr
pci_pm_reset
pci_dev_reset_slot_function
pci_parent_bus_reset
上面的都是function的重置函数,只要满足一个就可以直接返回,其程度逐渐加深

pci_dev_specific_reset 是驱动工程师为这款设备,写的特定的reset方式
pcie_has_flr 设备是否与FLR 能力,就是读取Function Level Reset Capability
pci_pm_reset 让设备进入D3 hot 再返回D0
pci_dev_reset_slot_function 调用pci_reset_hotplug_slot,重置slot,该函数会重置整个pci device,而不只pci function
pci_parent_bus_reset 调用 pci_bridge_secondary_bus_reset,会修改该pci device 所连接的pci briage的配置空间,让他reset下游的pci device。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值