отключить определенное устройство PCI при загрузке

14

Я только что переустановил Debian на своем ноутбуке Sony VAIO, и все мои dmesgи виртуальные консоли снова и снова получают спам с одинаковыми сообщениями.

[   59.662381] hub 1-1:1.0: unable to enumerate USB device on port 2
[   59.901732] usb 1-1.2: new high-speed USB device number 91 using ehci_hcd
[   59.917940] hub 1-1:1.0: unable to enumerate USB device on port 2
[   60.157256] usb 1-1.2: new high-speed USB device number 92 using ehci_hcd

Я полагаю, что эти сообщения поступают с подключенного внутри устройства USB, скорее всего, с веб-камеры (поскольку это единственное, что не работает). Единственный способ, которым я могу закрыть его (не убивая мои действительно полезные порты USB), - отключить один из хост-контроллеров USB:

# echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci_hcd/unbind

Это также снимает мой интерфейс Bluetooth, но я в порядке с этим.

Я бы хотел, чтобы эта настройка сохранялась, чтобы я мог безболезненно снова использовать свою виртуальную консоль в случае необходимости. Я хочу, чтобы моя операционная система (Debian amd64) никогда не разбудила его, но я не знаю, как это сделать. Я пытался внести в черный список псевдоним модуля для устройства PCI, но, похоже, он игнорируется:

$ cat /sys/bus/pci/devices/0000\:00\:1a.0/modalias 
pci:v00008086d00003B3Csv0000104Dsd00009071bc0Csc03i20

$ cat /etc/modprobe.d/blacklist
blacklist pci:v00008086d00003B3Csv0000104Dsd00009071bc0Csc03i20

Как я могу гарантировать, что это конкретное устройство PCI никогда не активируется автоматически, не отключая его драйвер вообще?


-edit- Модуль был недавно переименован, теперь из userland работают следующие:

echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci-pci/unbind

Тем не менее, я ищу способ остановить привязку ядра этим устройством.

Rhymoid
источник
1
Будет ли приемлемый подход отключать это конкретное USB-устройство через шину USB, а не через шину PCI?
SLM
Также вы уверены, что можете занести в черный список, используя строку pci: ... вот так? Я только когда-либо видел черные списки модулей ядра в файле /etc/modprobe.d/blacklist. Не могли бы вы использовать lspci -k, чтобы определить, какой модуль требуется устройству, а затем поместить его в черный список?
Slm
После добавления записи в черный список, вы update-initramfs -u -k all?
Стефан Зайдель
@StefanSeidel: Хороший вопрос. У меня сейчас, но, похоже, это не помогает. Возможно, slm считает, что для внесения в черный список таких модальностей нужен другой синтаксис или метод.
Рифмоид
@slm: я не уверен, смогу ли я заблокировать modaliases через черный список modprobe (кажется, моя система игнорирует строку, которую я дал), но я не могу просто удалить модуль ( ehci_hcd), так как это отключит все USB-хосты на моя система. Я просто хочу отключить это конкретное устройство в зависимости от его производителя, dev, subvendor и subdev.
Рифмоид

Ответы:

4

Я недавно столкнулся с этой проблемой при настройке моего xen box с несколькими USB-устройствами. Я хотел, чтобы один использовался Dom-0, а другой - виртуальной машиной, поэтому мне нужно было, чтобы устройство было доступно для xen-pciback. Тем не менее, драйвер USB был включен в мое ядро, поэтому я не мог просто занести этот драйвер в черный список. Мое решение состояло в том, чтобы создать собственный скрипт initramfs, который связывает определенный порт pci в самом начале процесса загрузки.

Это Ubuntu 2016.04, но он должен работать в более ранних версиях.

Есть три файла. Я назвал их для моего конкретного случая использования, но ymmv:

Первый файл, названный /etc/unbindpcifile, который представляет собой простой CSV-номер с номером устройства pci и драйвером (настройте его здесь):

0000:08:00.0,xhci_hcd
0000:03:00.0,radeon

Второй файл /etc/initramfs-tools/hooks/xenfiles, который копирует вышеуказанный конфиг в initramfs.

#! /bin/bash

if [ -f /etc/unbindpci ]; then
  cp -pP /etc/unbindpci $DESTDIR/etc/unbindpci
fi

Третий файл - это то, что работает во время загрузки, я поместил его в /etc/initramfs-tools/scripts/init-top/unbind-early-pci:

#!/bin/sh

PREREQ=""
prereqs()
{
        echo "$PREREQ"
}
case $1 in
# get pre-requisites
prereqs)
        prereqs
        exit 0
        ;;
esac

# This only executes if in a xen Dom-0.
# Edit if that's not your use case!          
if [ -f /sys/hypervisor/uuid -a -f /etc/unbindpci ]; then
        if [ $(cat /sys/hypervisor/uuid) = "00000000-0000-0000-0000-000000000000" ]; then
                echo "Unbinding pci ports..."
                IFS=,
                while read addr driver; do
                        if [ -f /sys/bus/pci/drivers/$driver/unbind ]; then
                                echo "Unbinding $addr, device $driver"
                                echo $addr > /sys/bus/pci/drivers/$driver/unbind
                        fi
                done < /etc/unbindpci
        fi
fi

Наконец, запустите update-initramfs -k all -uи перезагрузите компьютер.

Я мог бы включить поддержку комментариев в конфигурационном файле, и здесь есть много чего сделать, но это работает для меня.

Стив Четти
источник
Это все еще решение, при котором вы отсоединяете PCI-устройство после его инициализации, но эй, это выглядит лучше, чем его решение /etc/init.d! Я не пользуюсь машиной прямо сейчас, и, возможно, я больше никогда не загрузлю ее с Debian, поэтому я не могу проверить ее. Однако, поскольку это, вероятно, сработало бы в моем случае, я приму это как ответ.
Rhymoid
Согласен, я до сих пор не нашел решения для предотвращения инициализации устройства без внесения в черный список модуля. На самом деле линия "radeon" является примером ранней попытки сделать это.
Стив Четти
Забавно, я думал, udevчто все шины проходили и загружались во время загрузки ядра, и все, что делал grub, initramfsбыло только для чтения и потеряно. когда ядро ​​загружено. Я попытался установить setpciв initramfs-toolsно сдался и я пробуя udevправило прямо сейчас.
WinEunuuchs2Unix
4

Ни один из ответов не решил мою похожую проблему, но они помогли мне решить ее!

Моя ошибка системного журнала:

[  334.940158] hub 1-0:1.0: unable to enumerate USB device on port 7

Это внутренний usb-хаб-порт для опции bluetooth у меня нет.

Отключение от устройства pci только что привело к тому, что концентратор снова заработал в качестве другого концентратора (в моем случае 5), а затем заполнил системный журнал.

Случайно я заметил структуру unbind под /sys/bus/usb/drivers/hub. Используя примеры выше, я просто добавил следующее в rc.local:

echo "1-0:1.0" > /sys/bus/usb/drivers/hub/unbind

Результат - системная тишина! Теперь, чтобы добавить пример сценария kshurig для управления питанием, я должен быть золотым.

Kujo770
источник
4

Вы можете удалить устройство PCI, добавив правило udev в /etc/udev/rules.d:

ACTION=="add", KERNEL=="0000:00:03.0", SUBSYSTEM=="pci", RUN+="/bin/sh -c 'echo 1 > /sys/bus/pci/devices/0000:00:03.0/remove'"

Замените 0000:00:03.0на адрес устройства pci, который вы хотите удалить

lunastorm
источник
Это довольно полезно. Однако, как упоминалось в OP, это приведет к отключению всех USB-портов. Есть ли способ добавить правило для определенного устройства и идентификатора поставщика, чтобы устройства работали со всеми другими портами USB, но игнорировали данное устройство?
Мосты Мостачо
2

Нашел эту ветку на аскубунту:

Использование lspci -vvдля определения слота PCI устройства, которое вы хотите отключить, звучало так, как будто вы можете использовать эту команду для выключения устройства этого слота:

% echo 0 > /sys/bus/pci/slot/$N/power
ОДС
источник
1
Я знаю, как я могу отключить его в любое другое время, но я хочу, чтобы ядро ​​вообще не активировало его. Кроме того, поскольку это аппаратное PCI-устройство (как и большинство контроллеров USB), оно не имеет слота. Компьютер, о котором я говорю, - это ноутбук, и единственный слот, который у него есть ( /sys/bus/pci/slots/1), это слот ExpressCard снаружи, который я могу освободить вручную.
Рифмоид
2

Когда вы уже echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci_hcd/unbindв /etc/rc.localтечение загрузки , чем нужно просто поместить его в сценарий для управления питанием Deamon , а также.

Идет следующим образом: Создайте исполняемый файл сценария bash с именем 0_disable_webcamв каталоге /etc/pm/sleep.d/:

#!/bin/sh
case "$1" in
        resume|thaw)
                echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci_hcd/unbind
                ;;
esac

Это должно работать мгновенно. Я попробовал это с USB-накопителем, и он работал (то есть он оставался отключенным), пока диск был подключен. Для повторного подключения потребуются правила udev, но поскольку ваша веб-камера не будет отключена, она должна работать. Если это не помогает, у меня есть другое предложение.

kschurig
источник
Если вышеупомянутое не работает, то вы должны найти правильный порт USB. Я предполагаю, что это «1-1.2» (в противном случае проверьте с помощью tree /sys/bus/pci/devices/0000\:00\:1a.0/«usbX», что означает, что порт является аналогичным номером). Если это «1-1.2» вместо вашего, echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci_hcd/unbindскрипт должен иметь echo "auto" > /sys/bus/usb/devices/1-1.2/power/control; echo -n "1-1.2" > /sys/bus/usb/drivers/usb/unbind.
kschurig
0

не ответ на ваш вопрос, а обходной путь.

Почему бы просто не подавить запись сообщений на консоль, изменив syslog / (я не знаю, используете ли вы syslog или rsyslog или что-то еще, поэтому я не могу указать вам более конкретно в правильном каталоге, но если вы поищите в ваших конфигурационных файлах системного журнала «console» и «tty», что даст вам хорошую отправную точку - на самом деле вы можете изменить консоль на / dev / tty1 [например] и получать сообщения только в tty1, а не во все консолей.

Другое решение (чтобы ответить на ваш вопрос, но мне это не нравится), вы можете занести в черный список модуль ehci_hcd (если он загружен) или перекомпилировать ваше ядро, чтобы использовать его только как модуль. Посмотрите на h ttp: //www.cyberciti.biz/faq/rhel-redhat-centos-kernel-usb-reset-high-speed-ehci_hcd/, который точно решает вопрос, который вы задаете

davidgo
источник