I ripristini in PCI express sono un po 'complessi. Esistono due tipi principali di ripristini: il ripristino convenzionale e il ripristino a livello di funzione. Esistono anche due tipi di ripristini convenzionali, ripristini fondamentali e ripristini non fondamentali. Vedi le specifiche PCI Express per tutti i dettagli.
Un "ripristino a freddo" è un ripristino fondamentale che ha luogo dopo che l'alimentazione è stata applicata a un dispositivo PCIe. Sembra che non ci sia un modo standard di innescare un ripristino a freddo, tranne per spegnere e riaccendere il sistema. Sul mio computer, la /sys/bus/pci/slots
directory è vuota.
Un "ripristino a caldo" è un ripristino fondamentale che viene attivato senza scollegare l'alimentazione dal dispositivo. Sembra che non ci sia un modo standard di innescare un ripristino a caldo.
Un "hot reset" è un reset convenzionale che viene attivato attraverso un collegamento PCI Express. Un ripristino a caldo viene attivato quando un collegamento viene forzato in inattivo elettrico o inviando i set ordinati TS1 e TS2 con il bit di ripristino a caldo impostato. Il software può avviare un ripristino a caldo impostando e quindi cancellando il bit di ripristino del bus secondario nel registro di controllo del ponte nello spazio di configurazione PCI della porta del ponte a monte del dispositivo.
Un "reset a livello di funzione" (FLR) è un reset che interessa solo una singola funzione di un dispositivo PCI Express. Non deve ripristinare l'intero dispositivo PCIe. L'implementazione dei ripristini a livello di funzione non è richiesta dalla specifica PCIe. Un ripristino a livello di funzione viene avviato impostando il bit di ripristino di avvio a livello di funzione nel registro di controllo del dispositivo della funzione nella struttura di capacità PCI Express nello spazio di configurazione PCI.
Linux espone la funzionalità di ripristino a livello di funzione sotto forma di /sys/bus/pci/devices/$dev/reset
. La scrittura di un 1 in questo file avvierà un ripristino a livello di funzione sulla funzione corrispondente. Si noti che ciò influisce solo su quella specifica funzione del dispositivo, non dell'intero dispositivo, e i dispositivi non sono tenuti ad implementare ripristini a livello di funzione secondo le specifiche PCIe.
Non sono a conoscenza di alcun metodo "carino" per innescare un ripristino a caldo (non esiste una voce sysfs per quello). Tuttavia, è possibile utilizzare setpci per farlo:
#!/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"
Assicurarsi che tutti i driver collegati siano scaricati prima di eseguire questo script. Questo script tenterà di rimuovere il dispositivo PCIe, quindi comanda alla porta dello switch upstream di eseguire un ripristino a caldo, quindi tenta di ripetere la scansione del bus PCIe. Questo script è stato testato solo su dispositivi con una singola funzione, quindi potrebbe essere necessario rielaborarli per dispositivi con più funzioni.
reboot -f
? Questo è simile alla pressione del pulsante di accensione della CPU.