Как сбросить / отключить питание устройства PCIe?
У меня есть устройство PCIe, которое работает правильно только тогда, когда компьютер полностью выключен, а затем снова включен. Появление простой команды reboot или reboot -p команды не приводит к отключению питания карты PCIe, что приводит к тому, что она не работает после перезагрузки.
Есть ли способ из операционной системы отключить питание устройства в слоте PCIe? Я могу найти это в /sys/bus/pci/devices/0000*/ , но я не могу понять, как правильно сбросить плату. Похоже, что переключающая сила — единственный путь.
За исключением этого, могу ли я изменить настройку где-нибудь, что вызовет полный цикл питания для reboot команды?
Кстати, я использую Ubuntu 12.10.
Потенциальный метод № 1
Я думаю, что вы можете сделать это с помощью этих команд:
отключить
включить
Где $NUMBER номер слота PCI.
lspci -vv может помочь идентифицировать устройство. Это не очень хорошо задокументировано .
Потенциальный метод № 2
Я сталкивался с этой веткой на U & L , похожая проблема: есть некоторые ответы на этот вопрос, которые говорят, что вы можете сбросить с помощью этой команды:
Однако я бы прочитал ответы там! Есть условия, чтобы делать это таким образом! Конкретно я бы прочитал этот ответ !
Потенциальный метод № 3
Существует команда Unix setpci , которая может дать вам способ сброса устройства на шине PCI.
Я не видел никаких конкретных примеров с этой командой, поэтому вам придется поискать примеры в Google и просмотреть страницу руководства . Я бы слегка пошагнул с этой командой, пока вы не будете уверены в ее использовании. Из того, что я читал об этом, он напрямую манипулирует оборудованием, поэтому всегда есть риск сделать это самостоятельно, а не использовать инструмент, который демонстрирует этот тип функциональности!
remove и rescan позволит ядру циклически запитывать устройство PCI без reboot :
Сброс в PCI Express немного сложен. Существует два основных типа сброса: обычный сброс и сброс на уровне функций. Есть также два типа обычных сбросов: фундаментальные и неосновные. См. Спецификацию PCI Express для всех деталей.
«Холодный сброс» — это фундаментальный сброс, который происходит после подачи питания на устройство PCIe. Похоже, не существует стандартного способа холодного сброса, за исключением выключения и повторного включения системы. На моих машинах /sys/bus/pci/slots каталог пуст.
«Теплый сброс» — это основной сброс, который запускается без отключения питания устройства. Похоже, не существует стандартного способа запуска «горячего» сброса.
«Горячий сброс» — это обычный сброс, который запускается по каналу PCI Express. Горячий сброс запускается, когда канал принудительно переключается в электрический режим, или путем отправки упорядоченных наборов TS1 и TS2 с установленным битом горячего сброса. Программное обеспечение может инициировать «горячий» сброс, установив, а затем сбросив бит сброса вторичной шины в регистре управления мостом в пространстве конфигурации PCI порта моста перед устройством.
«Сброс на уровне функций» (FLR) — это сброс, который влияет только на одну функцию устройства PCI Express. Он не должен сбрасывать все устройство PCIe. Реализация сброса на уровне функций не требуется в спецификации PCIe. Сброс на уровне функций инициируется установкой бита инициализации сброса на уровне функций в регистре управления устройством функции в структуре возможностей PCI Express в пространстве конфигурации PCI.
Linux предоставляет функциональность сброса на уровне функций в форме /sys/bus/pci/devices/$dev/reset . Запись 1 в этот файл инициирует сброс уровня функции для соответствующей функции. Обратите внимание, что это влияет только на эту конкретную функцию устройства, а не на все устройство, и устройства не обязаны выполнять сброс на уровне функций согласно спецификации PCIe.
Я не знаю ни одного «хорошего» метода для запуска «горячего» сброса (для этого нет записи sysfs). Однако для этого можно использовать setpci:
Убедитесь, что все подключенные драйверы выгружены перед запуском этого скрипта. Этот сценарий попытается удалить устройство PCIe, затем подать команду на порт вышестоящего коммутатора для выполнения горячего сброса, а затем попытаться выполнить повторное сканирование шины PCIe. Этот сценарий также был протестирован только на устройствах с одной функцией, поэтому может потребоваться доработка для устройств с несколькими функциями.
Источник
PCIe Hot Reset on Linux
Resets in PCI express are a bit complex. There are two main types of resets — conventional reset, and function-level reset. There are also two types of conventional resets, fundamental resets and non-fundamental resets. See the PCI express specification for all of the details.
A ‘cold reset’ is a fundamental reset that takes place after power is applied to a PCIe device. There appears to be no standard way of triggering a cold reset, save for turning the system off and back on again. On my machines, the /sys/bus/pci/slots directory is empty.
A ‘warm reset’ is a fundamental reset that is triggered without disconnecting power from the device. There appears to be no standard way of triggering a warm reset.
A ‘hot reset’ is a conventional reset that is triggered across a PCI express link. A hot reset is triggered either when a link is forced into electrical idle or by sending TS1 and TS2 ordered sets with the hot reset bit set. Software can initiate a hot reset by setting and then clearing the secondary bus reset bit in the bridge control register in the PCI configuration space of the bridge port upstream of the device.
A ‘function-level reset’ (FLR) is a reset that affects only a single function of a PCI express device. It must not reset the entire PCIe device. Implementing function-level resets is not required by the PCIe specification. A function-level reset is initiated by setting the initiate function-level reset bit in the function’s device control register in the PCI express capability structure in the PCI configuration space.
Linux exposes the function-level reset functionality in the form of /sys/bus/pci/devices/$dev/reset . Writing a 1 to this file will initiate a function-level reset on the corresponding function. Note that this only affects that specific function of the device, not the whole device, and devices are not required to implement function-level resets as per the PCIe specification.
I am not aware of any ‘nice’ method for triggering a hot reset (there is no sysfs entry for that). However, it is possible to use setpci to do so with the following script:
Ensure that all attached drivers are unloaded before running this script. This script will attempt to remove the PCIe device, then command the upstream switch port to issue a hot reset, then attempt to rescan the PCIe bus. This script has also only been tested on devices with a single function, so it may need some reworking for devices with multiple functions.
Источник
Сброс устройства PCI в Linux
Существует ли общий способ сброса устройства PCI в Linux из командной строки? То есть заставить шину PCI выдавать команду сброса.
в соответствии с http://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-pci вы можете сбросить отдельные функции устройства, если это поддерживается:
Самое близкое, что имеет шина PCI к сбросу уровня устройства, — это изменение состояния питания на D3 и обратно на D0. После выгрузки драйвера (было бы плохо сбросить аппаратное обеспечение из-под драйвера), вы можете использовать его setpci для записи в управляющие регистры для изменения состояния питания, но я считаю, что это происходит автоматически при выгрузке драйвера.
Поскольку универсальное устройство PCI не поддерживает горячее подключение, не будет способа сбросить его и заставить ядро пересчитать его.
Какие бы проблемы вы не пытались решить, несомненно, есть лучший способ, чем просто сбросить его.
Проблема с вышеупомянутыми решениями состоит в том, что они требуют совместимости устройства; однако в большинстве сценариев причиной сброса является именно его неработоспособность.
Однако, как описано здесь , есть еще один, более сложный способ сброса его на уровне PCI: мы удаляем его с шины PCI и затем повторно вставляем его путем повторного сканирования.
/remove , Мы можем найти его PCI ID с помощью lspci команды.
У меня здесь глючное устройство pci, иногда сброс на уровне PCI, иногда этот трюк удаления-чтения исправляет это. Я собираюсь написать сценарий, чтобы сделать это автоматически. 🙂
Источник
Перезагрузка PCI-устройства
Подскажите, Есть удалённый Linux-комп. В нём некое устройство PCI, которое иногда подвисает. Комп просто перестаёт его видеть. Перезагрузка компа не помогает. Помогает только передёргивание питания компа. Может есть какая команда которая на аппаратном уровне гасит PCI и заводит заново?
На этом устройстве в разрыв цепей питания вставь реле.
> На этом устройстве в разрыв цепей питания
Видел как AVGN протирает ножевой разъём ватной палочкой. Может, с PCI это тоже работает?
У меня был компьютер — Celeron 1300. Там был USB 1.1. поэтому я вставил PCI-платку с USB 2.0. В Windows и Linux она работала хорошо. Но в одном дистрибутиве Linux выпадала. Даже появлялось иксовое окно с сообщением dmesg об этом! Что интересно, дистр — не что попало, а CentOS 5.11.
Современные версии ядра Linux поддерживают технологию PCI hotplug. Я не знаю как ей пользоваться, но подозреваю что в случайный момент вставлять нельзя. И вытаскивать, очевидно, тоже: отбиндить надо. Я даже задавал вопрос на форуме на эту тему.
От материнки идет PERST, вот не уверен что им можно управлять. Но идея что hotplug-опция вероятно поможет — правильная, ведь после вставки карточки налету она должна быть как-то сброшена. Но должно ли это поддерживаться материнкой — не знаю, вроде должно, разве нет? И если у тебя обычный комп — ничего не сделаешь. По идее ребут компа (без выключения) и должен приводить к вызову этого сброса, если устройство спроектировано верно (проблема отсутствия сброса была в первых моих поделках) — это ты самопальщину запускаешь, или всё-таки покупную карту какую-то?
Источник
Linux reset pci device
No definitions found in this file.
- Go to file T
- Go to line L
- Go to definition R
- Copy path
- Copy permalink
Copy raw contents
Copy raw contents
#!/usr/bin/python |
«»»pci_reset — does an unbind/bind of an entire device»»» |
import sys |
import argparse |
import os |
from os . path import realpath |
from systools import sleep_with_countdown , lspci , lspci_lookup , bind , unbind |
if __name__ == «__main__» : |
## let’s restrict ourselves to USB controllers for now. |
# 00:14.0 USB controller: Intel Corporation Wildcat Point-LP USB xHCI Controller (rev 03) |
# 00:1d.0 USB controller: Intel Corporation Wildcat Point-LP USB EHCI Controller (rev 03) |
# UHCI: USB 1.x |
# EHCI: USB 2.0 |
# XHCI: USB 3.x |
parser = argparse . ArgumentParser ( description = __doc__ , formatter_class = argparse . RawDescriptionHelpFormatter ) |
parser . add_argument ( «—pci-bus» , default = «0000» ) |
parser . add_argument ( «—pci-id» , «-s» , help = «raw PCI id (no checking)» ) |
parser . add_argument ( «—usb2» , «-2» , action = «store_true» , help = «Find one usb2(ehci) controller and whack it» ) |
parser . add_argument ( «—usb3» , «-3» , action = «store_true» , help = «Find one usb3(xhci) controller and whack it» ) |
args = parser . parse_args () |
if args . pci_id : |
if args . usb2 or args . usb3 : |
sys . exit ( «id *or* controller, not both» ) |
pci_id = args . pci_id |
slots = lspci (). keys () |
if pci_id not in slots : |
sys . exit ( «<> not found in » . format ( pci_id , slots )) |
elif args . usb2 : |
if args . usb3 : |
sys . exit ( «only reset one controller at a time» ) |
pci_id = lspci_lookup ( «USB controller» , «EHCI» ) # class 0x0c03 |
elif args . usb3 : |
if args . usb2 : |
sys . exit ( «only reset one controller at a time» ) |
pci_id = lspci_lookup ( «USB controller» , «xHCI» ) # class 0x0c03 |
else : |
sys . exit ( «specify some pci slot» ) |
full_pci_id = «<>:<>» . format ( args . pci_bus , pci_id ) |
print «id:» , full_pci_id |
driver = realpath ( «/sys/bus/pci/devices/<>/driver» . format ( full_pci_id )) |
print «driver:» , driver |
assert os . path . exists ( driver ), «<> not found» . format ( driver ) |
raw_input ( «Press RETURN to unbind, sleep 5, and rebind: » ) |
print «Unbinding» , full_pci_id |
unbind ( driver , full_pci_id ) |
sleep_with_countdown ( 5 ) |
print «Rebinding» , full_pci_id |
bind ( driver , full_pci_id ) |
sleep_with_countdown ( 3 ) |
print lspci (). get ( pci_id , «<> not found after rebind!» . format ( pci_id )) |
# TODO: catch any added lines in kern.log for signs of activity |
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Источник