Як скинути / переключити живлення на пристрій PCIe?


20

У мене є пристрій PCIe, який працює правильно лише тоді, коли комп'ютер повністю вимкнено, а потім знову увімкнено. Видача простої rebootабо reboot -pкоманди не здається, що передає живлення на картку PCIe, через що вона не працює після перезавантаження.

Чи існує спосіб відключити живлення від ОС до пристрою в слоті PCIe? Я можу його знайти /sys/bus/pci/devices/0000*/, але не можу зрозуміти, як правильно скинути плату. Боротьба з силою здається єдиним способом.

Якщо це заборонити, чи можу я десь змінити налаштування, яке спричинить повний цикл живлення rebootкоманди?

До речі, я запускаю Ubuntu 12.10.


Ви пробували reboot -f? Це схоже на натискання кнопки живлення процесора.
ктан

1
Два роки тому ОП зазначила, що софт rebootне працює. Ви reboot -fвсе ще є м'яким перезавантаженням.
roaima

Відповіді:


16

Потенційний метод №1

Я думаю, ви можете це зробити за допомогою цих команд:

відключити

echo 0 > /sys/bus/pci/slots/$NUMBER/power

включити

echo 1 > /sys/bus/pci/slots/$NUMBER/power

Де $NUMBERномер слота PCI.

lspci -vvможе допомогти визначити пристрій. Це не дуже добре задокументовано ...

Потенційний метод №2

Я натрапив на цю тему на U&L , схожу проблему: є кілька відповідей на це запитання, в яких сказано, що ви можете скинути цю команду:

echo "1" > /sys/bus/pci/devices/$NUMBER/reset

Однак я б там прочитав відповіді! Існують умови навколо цього робити це! Конкретно я прочитав би цю відповідь !

Потенційний метод №3

Існує команда Unix setpci, яка може дати вам спосіб скидання пристрою в шині PCI.

Я не бачив жодних конкретних прикладів з цією командою, тому вам доведеться переглядати приклади в Google і переглядати сторінку man . Я б злегка ступав з цією командою, поки не будете впевнені в її використанні. З того, що я читав про це, це безпосередньо маніпулювати обладнанням, тому завжди є ризики зробити це самостійно, порівняно з використанням інструменту, який піддається впливу цього типу функціональності!


1
Ніщо не з’являється в слотах, навіть якщо у мене підключено декілька карт. У мене є каталог живлення /sys/bus/pci/devices/$NUMBER/. Але ніщо не гарантує встановлення 0 або 1
zachd1_618

1
Я натрапив на цю тему на U&L , схожу проблему: є кілька відповідей на це питання, які говорять, що ви можете скинути це: echo "1"> / sys / bus / pci / devices / $ NUMBER / reset. Читайте, що Q, хоча існують умови, щоб зробити це саме так!
slm

Дякуємо за посилання Проте я це спробував, але, здається, нічого не зробить. Зокрема, пристрій не працює, і система все ще знає, що він є. (Коли карта увімкнена та підключена, у пристрої / Dev є пристрої, які я можу дивитись). Вони не зникають, коли я echo "1" > ....
zachd1_618

1
Ви вивантажуєте модулі ядра для цієї картки перед циклом живлення? Я думаю, що ти повинен це зробити і ти.
slm

1
Я думаю, я перевірю вихідний код ядра, щоб побачити, чи зміна powerнасправді ставить його в D3.
ліс

7

removeі rescanдозволить ядро ​​циклічно живити пристрій PCI без reboot:

echo "1" > /sys/bus/pci/devices/DDDD\:BB\:DD.F//remove
sleep 1
echo "1" > /sys/bus/pci/rescan

де DDDD.BB.DD.F = Домен: Шина: Device.Function


echo "1"> / sys / bus / pci / rescan працює для мене у слоті lenovo g560 mini pci. Я підключив USB 3.0 minipci карту. Система - Ubuntu 16.04 x64
kodmanyagha

Він працює не на всіх пристроях. У мене є мережний адаптер Cavium, який не вимкнений цим методом, оскільки я все ще можу отримати доступ до його u-boot при використанні послідовної лінії.
Ерік

7

Скидання в 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. Цей сценарій також протестований лише на пристроях з однією функцією, тому може знадобитися певна переробка для пристроїв з декількома функціями.


Цей сценарій працював на моєму AMD RX480. Контекст: PCI переходить до гостя Win10, а потім вимикає або перезавантажує гостя. Якщо запустити гостя ще раз (не використовуючи цей скрипт), зависає, якщо GPU все-таки приєднаний. Запуск цього сценарію між фіксованою випуску
小太郎
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.