Zurücksetzen in PCI Express ist etwas komplex. Es gibt zwei Haupttypen von Zurücksetzungen - herkömmliche Zurücksetzungen und Zurücksetzungen auf Funktionsebene. Es gibt auch zwei Arten von konventionellen Rücksetzungen, Grundrücksetzungen und nicht-Grundrücksetzungen. Alle Details finden Sie in der PCI-Express-Spezifikation.
Ein "Kaltstart" ist ein grundlegender Neustart, der nach dem Einschalten eines PCIe-Geräts erfolgt. Es scheint keine Standardmethode zum Auslösen eines Kaltstartens zu geben, außer zum Aus- und Wiedereinschalten des Systems. Auf meinen Rechnern ist das /sys/bus/pci/slots
Verzeichnis leer.
Ein "Warm-Reset" ist ein grundlegender Reset, der ausgelöst wird, ohne dass die Stromversorgung des Geräts unterbrochen wird. Es scheint keine Standardmethode zu geben, um einen Warmstart auszulösen.
Ein "Hot-Reset" ist ein herkömmlicher Reset, der über eine PCI-Express-Verbindung ausgelöst wird. Ein Hot-Reset wird entweder ausgelöst, wenn eine Verbindung in den Leerlauf geschaltet wird, oder indem von TS1 und TS2 bestellte Sätze mit gesetztem Hot-Reset-Bit gesendet werden. Die Software kann einen Hot-Reset einleiten, indem sie das Reset-Bit für den sekundären Bus im Bridge-Steuerregister im PCI-Konfigurationsbereich des Bridge-Ports vor dem Gerät setzt und anschließend löscht.
Ein "Function Level Reset" (FLR) ist ein Reset, der nur eine einzelne Funktion eines PCI-Express-Geräts betrifft. Es darf nicht das gesamte PCIe-Gerät zurückgesetzt werden. Das Implementieren von Zurücksetzungen auf Funktionsebene ist in der PCIe-Spezifikation nicht erforderlich. Ein Zurücksetzen auf Funktionsebene wird eingeleitet, indem das Bit zum Zurücksetzen auf Funktionsebene im Gerätesteuerregister der Funktion in der PCI-Express-Fähigkeitsstruktur im PCI-Konfigurationsbereich gesetzt wird.
Linux stellt die Funktionalität zum Zurücksetzen auf Funktionsebene in Form von zur Verfügung /sys/bus/pci/devices/$dev/reset
. Wenn Sie eine 1 in diese Datei schreiben, wird die entsprechende Funktion auf Funktionsebene zurückgesetzt. Beachten Sie, dass dies nur die spezifische Funktion des Geräts betrifft, nicht das gesamte Gerät, und dass Geräte nicht zur Implementierung von Zurücksetzungen auf Funktionsebene gemäß der PCIe-Spezifikation erforderlich sind.
Mir ist keine "nette" Methode bekannt, um einen Hot-Reset auszulösen (dafür gibt es keinen sysfs-Eintrag). Es ist jedoch möglich, setpci zu verwenden:
#!/bin/bash
dev=$1
if [ -z "$dev" ]; then
echo "Error: no device specified"
exit 1
fi
if [ ! -e "/sys/bus/pci/devices/$dev" ]; then
dev="0000:$dev"
fi
if [ ! -e "/sys/bus/pci/devices/$dev" ]; then
echo "Error: device $dev not found"
exit 1
fi
port=$(basename $(dirname $(readlink "/sys/bus/pci/devices/$dev")))
if [ ! -e "/sys/bus/pci/devices/$port" ]; then
echo "Error: device $port not found"
exit 1
fi
echo "Removing $dev..."
echo 1 > "/sys/bus/pci/devices/$dev/remove"
echo "Performing hot reset of port $port..."
bc=$(setpci -s $port BRIDGE_CONTROL)
echo "Bridge control:" $bc
setpci -s $port BRIDGE_CONTROL=$(printf "%04x" $(("0x$bc" | 0x40)))
sleep 0.01
setpci -s $port BRIDGE_CONTROL=$bc
sleep 0.5
echo "Rescanning bus..."
echo 1 > "/sys/bus/pci/devices/$port/rescan"
Stellen Sie sicher, dass alle angehängten Treiber entladen sind, bevor Sie dieses Skript ausführen. In diesem Skript wird versucht, das PCIe-Gerät zu entfernen. Anschließend wird der Upstream-Switch-Port angewiesen, einen Hot-Reset durchzuführen. Anschließend wird versucht, den PCIe-Bus erneut zu scannen. Dieses Skript wurde auch nur auf Geräten mit einer einzigen Funktion getestet. Daher muss es möglicherweise für Geräte mit mehreren Funktionen überarbeitet werden.
reboot -f
? Dies ist vergleichbar mit dem Drücken des Netzschalters der CPU.