Resetowanie w PCI Express jest nieco skomplikowane. Istnieją dwa główne typy resetowania - reset tradycyjny i reset na poziomie funkcji. Istnieją również dwa rodzaje resetu konwencjonalnego: resetowania podstawowego i resetowania nie fundamentalnego. Zobacz wszystkie szczegóły w specyfikacji PCI express.
„Zimny reset” to podstawowy reset, który ma miejsce po podłączeniu zasilania do urządzenia PCIe. Wydaje się, że nie ma standardowego sposobu wyzwalania zimnego resetu, z wyjątkiem wyłączenia i ponownego włączenia systemu. Na moich komputerach /sys/bus/pci/slots
katalog jest pusty.
„Ciepły reset” to podstawowy reset, który jest uruchamiany bez odłączania zasilania od urządzenia. Wydaje się, że nie ma standardowego sposobu wyzwalania ciepłego resetu.
„Hot reset” to konwencjonalny reset uruchamiany przez łącze PCI Express. Gorący reset jest uruchamiany albo wtedy, gdy łącze jest zmuszone do bezczynności elektrycznej, albo przez wysłanie zestawów TS1 i TS2 z zestawem bitów gorącego resetu. Oprogramowanie może zainicjować gorący reset poprzez ustawienie, a następnie wyczyszczenie bitu resetu wtórnej magistrali w rejestrze kontrolnym mostu w przestrzeni konfiguracyjnej PCI portu mostka przed urządzeniem.
„Reset na poziomie funkcji” (FLR) to reset, który wpływa tylko na jedną funkcję urządzenia PCI express. Nie może resetować całego urządzenia PCIe. Implementacja resetowania na poziomie funkcji nie jest wymagana przez specyfikację PCIe. Resetowanie na poziomie funkcji jest inicjowane przez ustawienie bitu inicjującego resetowanie na poziomie funkcji w rejestrze kontrolnym urządzenia funkcji w strukturze zdolności PCI express w przestrzeni konfiguracji PCI.
Linux udostępnia funkcję resetowania na poziomie funkcji w postaci /sys/bus/pci/devices/$dev/reset
. Zapisanie 1 do tego pliku zainicjuje resetowanie poziomu funkcji dla odpowiedniej funkcji. Należy pamiętać, że wpływa to tylko na tę konkretną funkcję urządzenia, a nie na całe urządzenie, a urządzenia nie są wymagane do implementacji resetowania na poziomie funkcji zgodnie ze specyfikacją PCIe.
Nie znam żadnej „ładnej” metody wyzwalania gorącego resetu (nie ma na to wpisu sysfs). Można jednak użyć do tego setpci:
#!/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"
Upewnij się, że wszystkie podłączone sterowniki są rozładowane przed uruchomieniem tego skryptu. Ten skrypt podejmie próbę usunięcia urządzenia PCIe, a następnie wyda polecenie przywrócenia portu przełącznika w celu wykonania gorącego resetu, a następnie spróbuje ponownie przeskanować magistralę PCIe. Ten skrypt został przetestowany tylko na urządzeniach z jedną funkcją, więc może wymagać przeróbki dla urządzeń z wieloma funkcjami.
reboot -f
? Jest to podobne do naciskania przycisku zasilania procesora.