As redefinições no PCI Express são um pouco complexas. Existem dois tipos principais de redefinições - redefinição convencional e redefinição no nível da função. Existem também dois tipos de redefinições convencionais, redefinições fundamentais e redefinições não fundamentais. Veja a especificação PCI Express para todos os detalhes.
Uma 'redefinição a frio' é uma redefinição fundamental que ocorre após a energia ser aplicada a um dispositivo PCIe. Parece não haver uma maneira padrão de ativar uma reinicialização a frio, exceto para desligar e ligar o sistema novamente. Nas minhas máquinas, o /sys/bus/pci/slots
diretório está vazio.
Uma 'reinicialização a quente' é uma reinicialização fundamental que é acionada sem desconectar a energia do dispositivo. Parece não haver uma maneira padrão de acionar uma redefinição a quente.
Uma 'redefinição a quente' é uma redefinição convencional que é disparada através de um link PCI Express. Uma reinicialização a quente é acionada quando um link é forçado a inatividade elétrica ou enviando conjuntos ordenados TS1 e TS2 com o bit de reinicialização a quente definido. O software pode iniciar uma redefinição a quente definindo e limpando o bit de redefinição do barramento secundário no registro de controle da ponte no espaço de configuração PCI da porta da ponte a montante do dispositivo.
Uma 'redefinição no nível da função' (FLR) é uma redefinição que afeta apenas uma única função de um dispositivo PCI Express. Não deve redefinir todo o dispositivo PCIe. A implementação de redefinições no nível da função não é exigida pela especificação PCIe. Uma redefinição no nível da função é iniciada definindo o bit de redefinição no nível da função no registro de controle do dispositivo da função na estrutura de capacidade do PCI Express no espaço de configuração do PCI.
O Linux expõe a funcionalidade de redefinição no nível da função na forma de /sys/bus/pci/devices/$dev/reset
. Escrever 1 neste arquivo iniciará uma redefinição no nível da função na função correspondente. Observe que isso afeta apenas a função específica do dispositivo, não o dispositivo inteiro, e os dispositivos não são necessários para implementar redefinições no nível da função, conforme a especificação PCIe.
Não conheço nenhum método 'bom' para acionar uma redefinição a quente (não há entrada sysfs para isso). No entanto, é possível usar o setpci para fazer isso:
#!/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"
Verifique se todos os drivers conectados estão descarregados antes de executar este script. Este script tentará remover o dispositivo PCIe, depois comandará a porta do switch upstream para emitir uma redefinição a quente e, em seguida, tentará verificar novamente o barramento PCIe. Esse script também foi testado apenas em dispositivos com uma única função; portanto, pode ser necessário retrabalhar para dispositivos com várias funções.
reboot -f
? É semelhante a pressionar o botão liga / desliga da CPU.