wyłącz określone urządzenie PCI podczas uruchamiania

14

Właśnie przeinstalowałem Debiana na moim laptopie Sony VAIO, a moje dmesgi wirtualne konsole są ciągle spamowane tymi samymi wiadomościami.

[   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

Wierzę, że te wiadomości pochodzą z wewnętrznie podłączonego urządzenia USB, najprawdopodobniej kamery internetowej (ponieważ to jedyna rzecz, która nie działa). Jedynym sposobem, w jaki mogę go zamknąć (bez zabijania moich faktycznie użytecznych portów USB), jest wyłączenie jednego z kontrolerów hosta USB:

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

To także usuwa mój interfejs Bluetooth, ale nic mi nie jest.

Chciałbym, aby to ustawienie pozostało, aby w razie potrzeby móc bezboleśnie korzystać z mojej wirtualnej konsoli. Chcę, aby mój system operacyjny (Debian amd64) nigdy go nie obudził, ale nie wiem, jak to zrobić. Próbowałem umieścić na czarnej liście alias modułu dla urządzenia PCI, ale wydaje się, że jest ignorowany:

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

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

Jak mogę się upewnić, że to konkretne urządzenie PCI nigdy nie zostanie automatycznie aktywowane bez całkowitego wyłączenia sterownika?


-edit- Nazwa modułu została ostatnio przemianowana, teraz następujące prace z przestrzeni użytkownika:

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

Mimo wszystko szukam sposobu, aby powstrzymać jądro od wiązania tego urządzenia.

Rhymoid
źródło
1
Czy dopuszczalnym podejściem byłoby wyłączenie tego konkretnego urządzenia USB za pośrednictwem magistrali USB zamiast magistrali PCI?
slm
Czy jesteś też pewien, że możesz umieścić na czarnej liście za pomocą takiego ciągu pci: ...? Widziałem tylko moduły jądra na czarnej liście w pliku /etc/modprobe.d/blacklist. Czy nie możesz użyć lspci -k do zidentyfikowania modułu, którego chce urządzenie, a następnie czarnej listy?
slm
Czy po dodaniu wpisu do czarnej listy update-initramfs -u -k all?
Stefan Seidel
@StefanSeidel: Dobra uwaga. Mam teraz, ale wydaje się, że to nie pomaga. Być może slm ma rację, sądząc, że umieszczenie na czarnej liście takich modali wymaga innej składni lub metody.
Rhymoid
@slm: Nie jestem pewien, czy mogę zablokować modyfikacje za pomocą czarnej listy modprobe (mój system wydaje się ignorować linię, którą mu podałem), ale nie mogę po prostu usunąć modułu ( ehci_hcd), ponieważ to spowodowałoby wyłączenie wszystkich hostów USB na mój system. Chcę tylko wyłączyć to konkretne urządzenie w oparciu o jego dostawcę, programistę, podwładnego i subdev.
Rhymoid

Odpowiedzi:

4

Niedawno napotkałem ten problem podczas konfigurowania mojego Xen Boxa z wieloma urządzeniami USB. Chciałem, aby jeden był używany przez Dom-0, a drugi przez VM, więc potrzebowałem urządzenia, które będzie dostępne dla Xen-Pcibacka. Jednak sterownik USB był zgodny z moim jądrem, więc nie mogłem po prostu umieścić go na czarnej liście. Moim rozwiązaniem było stworzenie niestandardowego skryptu initramfs, który odwija ​​określony port pci na bardzo wczesnym etapie procesu rozruchu.

To jest Ubuntu 2016.04, ale powinien działać we wcześniejszych wersjach.

W grę wchodzą trzy pliki. Nazwałem je dla mojego konkretnego przypadku użycia, ale ymmv:

Pierwszy plik, nazwany /etc/unbindpciplik, który jest prostym plikiem csv numeru urządzenia pci i sterownika (w razie potrzeby skonfiguruj tutaj):

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

Drugi plik /etc/initramfs-tools/hooks/xenfiles, który kopiuje powyższą konfigurację do initramfs.

#! /bin/bash

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

Trzeci plik jest tym, co działa podczas uruchamiania, umieściłem go w /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

Na koniec uruchom update-initramfs -k all -ui uruchom ponownie.

Mógłbym włączyć obsługę komentarzy w pliku konfiguracyjnym i jest tu wiele do oczyszczenia, ale to działa dla mnie.

Steve Czetty
źródło
To wciąż rozwiązanie, w którym odłączysz urządzenie PCI po jego zainicjowaniu, ale hej, wygląda lepiej niż rozwiązywanie /etc/init.d! Obecnie nie używam tego komputera i mogę już nigdy nie uruchomić go z Debianem, więc nie mogę go przetestować. Ponieważ jednak prawdopodobnie zadziałałoby w moim przypadku, przyjmuję to jako odpowiedź.
Rhymoid,
Zgadzam się, wciąż nie znalazłem rozwiązania zapobiegającego inicjalizacji urządzenia bez umieszczenia modułu na czarnej liście. W rzeczywistości linia „radeon” jest przykładem wczesnej próby tego.
Steve Czetty,
Zabawne, że pomyślałem, udevże cały autobus przeszedł i załadował się podczas rozruchu jądra, a wszystko, co robił grub, initramfsbyło tylko do odczytu i zostało utracone. po załadowaniu jądra. Próbowałem skonfigurować setpciw initramfs-toolsale zrezygnował i staram się udevregułę teraz.
WinEunuuchs2Unix
4

Żadna z odpowiedzi nie rozwiązała mojego podobnego problemu, ale nie postawił mnie na drodze do jego rozwiązania!

Błąd mojego syslog:

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

To jest wewnętrzny hub-port USB dla opcji Bluetooth, której nie mam.

unbind do urządzenia pci spowodowało, że hub wyskoczył z powrotem jako kolejny hub (w moim przypadku 5) i zalał syslog dalej.

Przez przypadek zauważyłem unbind strukturę pod /sys/bus/usb/drivers/hub. Korzystając z powyższych przykładów, właśnie dodałem następujące w rc.local:

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

Rezultatem jest cisza syslog! Dodajmy teraz przykładowy skrypt kshuriga do zarządzania energią i powinienem być złoty.

Kujo770
źródło
4

Możesz usunąć urządzenie PCI, dodając regułę udev w /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'"

Zastąp 0000:00:03.0adres urządzenia PCI, który chcesz usunąć

lunastorm
źródło
To jest bardzo przydatne. Jednak, jak wspomniano PO, spowoduje to uszkodzenie wszystkich portów USB. Czy istnieje możliwość dodania reguły dla konkretnego urządzenia i identyfikatora dostawcy, aby urządzenia współpracowały ze wszystkimi innymi portami USB, ale zignorowałyby dane urządzenie?
Mosty Mostacho,
2

Znaleziono ten wątek na askubuntu:

Używając lspci -vvdo identyfikacji gniazda PCI urządzenia, które chcesz wyłączyć, zabrzmiało to tak, jakbyś mógł użyć tego polecenia, aby wyłączyć urządzenie tego gniazda:

% echo 0 > /sys/bus/pci/slot/$N/power
slm
źródło
1
Wiem, jak mogę to wyłączyć w dowolnym momencie, ale chcę w ogóle zatrzymać aktywację jądra. Poza tym, ponieważ jest to urządzenie przewodowe PCI (jak większość kontrolerów USB), nie ma gniazda. Maszyna, o której mówię, to laptop, a jedynym gniazdem, które ma ( /sys/bus/pci/slots/1), jest gniazdo ExpressCard na zewnątrz, które mogę ręcznie opróżnić.
Rhymoid
2

Gdy masz już echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci_hcd/unbindw /etc/rc.localna starcie niż wystarczy umieścić go w skrypcie do zarządzania zasilaniem deamon również.

Wygląda to tak: Utwórz wykonywalny plik skryptu bash o nazwie 0_disable_webcamw katalogu /etc/pm/sleep.d/:

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

Powinno działać natychmiast. Próbowałem z napędem USB i działało (co oznacza, że ​​pozostało wyłączone), dopóki napęd był podłączony. Zastąpienie wymaga reguł udev, ale ponieważ kamera internetowa nie zostanie odłączona, powinna działać. Jeśli to nie pomoże, mam inną sugestię.

kschurig
źródło
Jeśli powyższe nie działa, musisz znaleźć odpowiedni port USB. Myślę, że jest to „1-1.2” (w przeciwnym razie sprawdź tree /sys/bus/pci/devices/0000\:00\:1a.0/w „usbX”, co oznacza, że ​​port ma podobną liczbę). Jeśli jest to „1-1.2” zamiast twojego, echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci_hcd/unbindskrypt powinien mieć echo "auto" > /sys/bus/usb/devices/1-1.2/power/control; echo -n "1-1.2" > /sys/bus/usb/drivers/usb/unbind.
kschurig
0

nie odpowiedź na twoje pytanie, jak obejście.

Dlaczego nie po prostu ukryć rejestrowanie wiadomości w konsoli, modyfikując syslog / (Nie wiem, czy używasz syslog, rsyslog lub czegoś innego, więc nie mogę tak naprawdę wskazać ci dokładniej katalogu, ale jeśli wyszukaj w plikach konfiguracyjnych syslog „konsola” i „tty”, co dałoby ci dobre miejsce startowe - w rzeczywistości prawdopodobnie możesz zmienić konsolę na / dev / tty1 [na przykład] i wyświetlać tylko wiadomości logujące się do tty1, a nie wszystkich konsole.

Innym rozwiązaniem (aby odpowiedzieć na twoje pytanie, ale mi się nie podoba), możesz umieścić na czarnej liście moduł ehci_hcd (jeśli jest załadowany) lub ponownie skompilować jądro, aby używać go tylko jako modułu. Spójrz na h ttp: //www.cyberciti.biz/faq/rhel-redhat-centos-kernel-usb-reset-high-speed-ehci_hcd/, który rozwiązuje dokładnie zadane pytanie

Davidgo
źródło