Jak zresetować / zresetować zasilanie urządzenia PCIe?


20

Mam urządzenie PCIe, które działa poprawnie tylko wtedy, gdy komputer jest całkowicie wyłączony, a następnie włączony ponownie. Wydanie polecenia prostego rebootlub reboot -ppolecenia nie wydaje się włączać zasilania karty PCIe, co powoduje, że nie działa ona po ponownym uruchomieniu.

Czy istnieje sposób, aby z systemu operacyjnego włączyć zasilanie urządzenia w gnieździe PCIe? Mogę to znaleźć /sys/bus/pci/devices/0000*/, ale nie mogę wymyślić, jak poprawnie zresetować płytkę. Wydaje się, że przełączanie mocy jest jedynym sposobem.

Pomijając to, czy mogę zmienić ustawienie, które spowoduje pełny cykl zasilania rebootpolecenia?

Nawiasem mówiąc, używam Ubuntu 12.10.


Próbowałeś reboot -f? Jest to podobne do naciskania przycisku zasilania procesora.
ktan

1
Dwa lata temu OP wskazał, że soft rebootnie działa. Twój reboot -fnadal jest miękki restart.
roaima,

Odpowiedzi:


16

Potencjalna metoda nr 1

Myślę, że możesz to zrobić za pomocą następujących poleceń:

wyłączyć

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

włączyć

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

Gdzie $NUMBERjest numer gniazda PCI.

lspci -vvmoże pomóc w identyfikacji urządzenia. Nie jest to zbyt dobrze udokumentowane ...

Potencjalna metoda nr 2

Natknąłem się na ten wątek na temat U&L , podobny problem: istnieją odpowiedzi na to pytanie, które mówią, że można zresetować za pomocą tego polecenia:

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

Jednak czytałbym tam odpowiedzi! Istnieją warunki do zrobienia tego w ten sposób! W szczególności przeczytałbym tę odpowiedź !

Potencjalna metoda nr 3

Istnieje komenda Unix setpci, która może dać ci metodę resetowania urządzenia w szynie PCI.

Nie widziałem żadnych konkretnych przykładów z tym poleceniem, więc będziesz musiał znaleźć przykłady w Google i przejrzeć stronę podręcznika . Z tym poleceniem wykonałbym lekkie kroki, dopóki nie będziesz pewny co do jego użycia. Z tego, co o nim czytałem, bezpośrednio manipuluje sprzętem, więc zawsze jest ryzyko, że zrobisz to sam, a nie przy użyciu narzędzia, które ujawnia ten rodzaj funkcjonalności!


1
Nic nie pojawia się w gniazdach, mimo że mam podłączonych wiele kart. Mam katalog zasilania /sys/bus/pci/devices/$NUMBER/. Ale nic nie wydaje się uzasadniać ustawienia 0 lub 1
zachd1_618

1
Natknąłem się na ten wątek na temat U&L , podobny problem: istnieją odpowiedzi na to pytanie, które mówią, że możesz zresetować za pomocą tego: echo „1”> / sys / bus / pci / devices / $ NUMBER / reset. Przeczytaj to Q, są jednak warunki do zrobienia tego w ten sposób!
slm

Dzięki za link. Próbowałem tego jednak i wydaje się, że to nic nie robi. W szczególności urządzenie nie wyłącza się, a system nadal wie, że tam jest. (Gdy karta jest włączona i podłączona, istnieją urządzenia w / dev, które mogę oglądać). Nie znikają, kiedy ja echo "1" > ....
zachd1_618

1
Czy rozładowujesz moduły jądra dla tej karty przed włączeniem zasilania? Myślę, że ty też musisz to zrobić.
slm

1
Myślę, że sprawdzę kod źródłowy jądra, aby sprawdzić, czy przełączanie powerrzeczywiście wstawia go do D3.
las

7

removei rescanpozwoli jądrze zasilać cyklicznie urządzenie PCI bez reboot:

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

gdzie DDDD.BB.DD.F = Domena: Magistrala: Funkcja urządzenia


echo "1"> / sys / bus / pci / rescan pracuje dla mnie w lenovo g560 mini pci slot. Podłączyłem kartę minipci USB 3.0. System to Ubuntu 16.04 x64
kodmanyagha

Nie działa na wszystkich urządzeniach. Mam kartę sieciową Cavium, która nie wyłącza się tą metodą, ponieważ nadal mogę uzyskać dostęp do jej rozruchu podczas korzystania z linii szeregowej.
Eric

7

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/slotskatalog 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.


Ten skrypt działał na moim AMD RX480. Kontekst: Przekazanie PCI do gościa Win10, a następnie zamknięcie lub ponowne uruchomienie gościa. Ponowne uruchomienie gościa (bez użycia tego skryptu) zawiesiłoby się, gdyby procesor graficzny był nadal podłączony. Uruchomienie tego skryptu pomiędzy rozwiązało problem
小 太郎
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.