Is there a generic way to reset a PCI device in Linux from the command line? That is, cause the PCI bus to issue a reset command.
according to http://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-pci you can reset individual functions of the device if that's supported:
What: /sys/bus/pci/devices/.../reset Description: Some devices allow an individual function to be reset without affecting other functions in the same device. For devices that have this support, a file named reset will be present in sysfs. Writing 1 to this file will perform reset.
The closest thing the PCI bus has to a device level reset is changing the power state to D3 and back to D0. After unloading the driver ( it would be bad to reset the hardware out from under the driver ), you can use
setpci to write to the control registers to change the power state, but I believe this happens automatically when you unload the driver.
The problem with the solutions above is that they require the cooperativity of the device; however in most scenarios the reason to reset it is exactly its non-cooperativity.
However, as it is described here, there is another, "harder" way to reset it on the PCI level: we remove it from the PCI bus and then re-insert it by a rescan.
echo 1 >/sys/bus/pci/<pci-id-of-device>/remove. We can find its PCI ID with an
echo 1 >/sys/bus/pci/rescan
I have here a buggy pci device, sometimes PCI-level reset, sometimes this removal-readd trick fixes it. I am about to write a script to do it automagically. :-)