PCI express'teki sıfırlamalar biraz karmaşıktır. İki ana sıfırlama türü vardır: geleneksel sıfırlama ve işlev düzeyinde sıfırlama. Ayrıca iki tür geleneksel sıfırlama vardır: temel sıfırlamalar ve temel olmayan sıfırlamalar. Tüm ayrıntılar için PCI express teknik özelliklerine bakın.
'Soğuk sıfırlama', bir PCIe aygıtına güç uygulandıktan sonra gerçekleştirilen temel bir sıfırlamadır. Soğuk sıfırlamayı tetiklemenin standart bir yolu yok gibi görünüyor, sistemi kapatıp tekrar açmak için kaydedin. Makinelerimde /sys/bus/pci/slots
dizin boş.
'Sıcak sıfırlama', cihazın gücü kesilmeden tetiklenen temel bir sıfırlamadır. Sıcak sıfırlamayı tetiklemenin standart bir yolu yok gibi görünüyor.
'Çalışırken sıfırlama', PCI express bağlantısı üzerinden tetiklenen geleneksel bir sıfırlamadır. Bir bağlantı elektriksel rölantiye zorlandığında veya sıcak sıfırlama biti ayarlanmış TS1 ve TS2 sıralı setler göndererek bir sıcak sıfırlama tetiklenir. Yazılım, aygıtın üstündeki köprü bağlantı noktasının PCI yapılandırma alanındaki köprü kontrol kaydındaki ikincil veri yolu sıfırlama bitini ayarlayıp temizleyerek bir sıcak sıfırlama başlatabilir.
'İşlev düzeyinde sıfırlama' (FLR), PCI express aygıtının yalnızca tek bir işlevini etkileyen bir sıfırlamadır. Tüm PCIe aygıtını sıfırlamamalıdır. PCIe belirtimi için işlev düzeyi sıfırlamaların uygulanması gerekmez. Bir işlev düzeyinde sıfırlama, PCI yapılandırma alanındaki PCI express özellik yapısında işlevin aygıt kontrol kaydında başlatma işlev düzeyi sıfırlama bitini ayarlayarak başlatılır.
Linux, işlev düzeyinde sıfırlama işlevini /sys/bus/pci/devices/$dev/reset
. Bu dosyaya 1 yazıldığında, ilgili işlevde işlev düzeyinde sıfırlama başlatılır. Bunun yalnızca aygıtın değil, aygıtın belirli bir işlevini etkilediğini ve aygıtların PCIe belirtimine göre işlev düzeyi sıfırlamaları uygulamak için gerekli olmadığını unutmayın.
Bir sıcak sıfırlama tetiklemek için herhangi bir 'güzel' yöntem farkında değilim (bunun için sysfs girişi yoktur). Ancak bunu yapmak için setpci kullanmak mümkündür:
#!/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"
Bu komut dosyasını çalıştırmadan önce tüm bağlı sürücülerin kaldırıldığından emin olun. Bu komut dosyası, PCIe aygıtını kaldırmaya çalışacak, ardından yukarı akış anahtarı bağlantı noktasına bir sıcak sıfırlama vermesini isteyecek ve ardından PCIe veri yolunu yeniden taramaya çalışacaktır. Bu komut dosyası yalnızca tek bir işlevi olan aygıtlarda da sınanmıştır, bu nedenle birden çok işlevi olan aygıtlar için yeniden işleme ihtiyaç duyulabilir.
reboot -f
mi Bu, CPU'nun güç düğmesine basmaya benzer.