Скидання в PCI express трохи складні. Існує два основні типи скидання - звичайний скидання та скидання на рівні функцій. Існують також два типи звичайних скидів, основні та не основні. Всі деталі див. У специфікації PCI Express.
"Холодний скидання" - це основне скидання, яке відбувається після подачі живлення на пристрій PCIe. Здається, не існує стандартного способу запуску холодного скидання, за винятком вимкнення та повторного ввімкнення системи. На моїх машинах /sys/bus/pci/slots
каталог порожній.
"Тепле скидання" - це основне скидання, яке спрацьовує без відключення живлення від пристрою. Здається, не існує стандартного способу запуску теплового скидання.
"Гаряче скидання" - це звичайне скидання, яке спрацьовує через експрес-посилання PCI. Гаряче скидання спрацьовує або при змушенні зв'язку в електричному холостому ході, або шляхом надсилання упорядкованих наборів TS1 і TS2 з набором біт гарячого скидання. Програмне забезпечення може ініціювати гаряче скидання, встановивши, а потім очистивши біт скидання вторинної шини в регістрі управління мостом у просторі конфігурації PCI мостового порту вище за течією пристрою.
"Скидання рівня функцій" (FLR) - це скидання, яке впливає лише на одну функцію пристрою експресу PCI. Він не повинен скидати весь пристрій PCIe. Спеціалізація PCIe не потребує здійснення скидання на рівні функцій. Скидання рівня функцій ініціюється встановленням ініціюючого біта скидання рівня функції в регістрі управління пристроєм функції в структурі можливостей PCI Express в просторі конфігурації PCI.
Linux виставляє функцію скидання на рівні функцій у вигляді /sys/bus/pci/devices/$dev/reset
. Запис 1 у цей файл ініціює скидання рівня функції відповідної функції. Зауважте, що це впливає лише на конкретну функцію пристрою, а не на весь пристрій, і пристрої не потребують для здійснення скидання рівня функцій відповідно до специфікації PCIe.
Я не знаю жодного «приємного» методу для запуску гарячого скидання (для цього немає запису sysfs). Однак для цього можна скористатися 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"
Переконайтеся, що всі додані драйвери вивантажені перед запуском цього сценарію. Цей скрипт спробує видалити пристрій PCIe, потім надати команду порту комутатора вище, щоб видати гаряче скидання, а потім спробувати змінити шину PCIe. Цей сценарій також протестований лише на пристроях з однією функцією, тому може знадобитися певна переробка для пристроїв з декількома функціями.
reboot -f
? Це схоже на натискання кнопки живлення процесора.