20

I've just reinstalled Debian on my Sony VAIO laptop, and my dmesg and virtual consoles all get spammed with the same messages over and over again.

[   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

I believe these messages are coming from an internally connected USB device, most likely the webcam (since that's the only thing that doesn't work). The only way I can seem to have it shut up (without killing my actually useful USB ports) is to disable one of the USB host controllers:

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

This also takes down my Bluetooth interface, but I'm fine with that.

I would like this setting to persist, so that I can painlessly use my virtual console again in case I need it. I want my operating system (Debian amd64) to never wake it up, but I don't know how to do this. I've tried to blacklist the module alias for the PCI device, but it seems to be ignored:

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

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

How do I ensure that this specific PCI device is never automatically activated, without disabling its driver altogether?


-edit- The module was renamed recently, now the following works from userland:

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

Still, I'm looking for a way to stop the kernel from binding that device in the first place.

10
  • 1
    Would an acceptable approach be to disable this particular USB device through the USB bus rather than the PCI bus?
    – slm
    Commented Feb 20, 2013 at 14:06
  • Also are you sure you can blacklist using a pci:... string like that? I've only ever seen kernel modules blacklistable in the /etc/modprobe.d/blacklist file. Couldn't you use lspci -k to identify which module the device wants and then black list that instead?
    – slm
    Commented Feb 20, 2013 at 14:13
  • After adding the entry to the blacklist, did you update-initramfs -u -k all? Commented Feb 21, 2013 at 10:14
  • @StefanSeidel: Good point. I have now, but it doesn't seem to help. Perhaps slm is right in thinking that blacklisting a modalias like this needs a different syntax or method.
    – Rhymoid
    Commented Feb 21, 2013 at 14:55
  • @slm: I'm not sure if I can block modaliases through the modprobe blacklist (my system seems to ignore the line I gave it), but I can't just remove the module (ehci_hcd), since that would disable all USB hosts on my system. I just want to disable this specific device, based on its vendor, dev, subvendor, and subdev.
    – Rhymoid
    Commented Feb 21, 2013 at 14:58

6 Answers 6

5

I recently ran into this issue while configuring my xen box with multiple usb devices. I wanted one to be used by Dom-0, and the other to be used by a VM, so I needed the device to be available to xen-pciback. However, the usb driver was complied into my kernel, so I couldn't just blacklist the driver. My solution was to create a custom initramfs script that unbinds the specific pci port very early in the boot process.

This is Ubuntu 2016.04, but it should work in earlier versions.

There are three files involved. I named them for my specific use case, but ymmv:

The first file, named /etc/unbindpci file which is a simple csv of the pci device number and the driver (configure as needed here):

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

Second file /etc/initramfs-tools/hooks/xenfiles, which copies the above config into the initramfs.

#! /bin/bash

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

Third file is what does the work at boot time, I placed it in /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

Finally, run update-initramfs -k all -u and reboot.

I could include support for comments in the config file, and there is a lot of cleanup to do here, but it works for me.

3
  • It's still a solution where you unbind the PCI device after it was initialised, but hey, it looks better than solving it in /etc/init.d! I'm not using the machine right now, and I might never boot it again with Debian, so I can't test it. However, because it would probably have worked in my case, I'll accept it as an answer.
    – Rhymoid
    Commented Apr 25, 2016 at 20:10
  • Agreed, I still haven't found a solution for preventing the device initialization without blacklisting the module. The "radeon" line is an example of an early attempt at that, actually. Commented Apr 25, 2016 at 20:19
  • Funny I thought udev did all the bus walk through and loading during kernel boot and anything grub did in initramfs was read only and lost. when the kernel is loaded. I had tried to setup setpci in initramfs-tools but gave up and am trying a udev rule now. Commented Nov 29, 2017 at 1:20
11

You can remove a PCI device by adding a udev rule under /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'"

Replace 0000:00:03.0 with the pci device address you want to remove

2
  • This is pretty useful. However, as the OP mentioned, this will result in all USB ports going down. Is there anyway to add a rule for a specific device and vendor id so that the devices works with all other USB ports but will disregard a given device? Commented Jun 3, 2014 at 4:33
  • It's not what OP wanted, but it's exactly what I wanted, was to used to do these udev rules on plugin devices like USB, forgot that i can do it on PCI subsytem as well.
    – Anton Krug
    Commented Apr 22 at 22:46
4

Found this thread on askubuntu:

Using lspci -vv to identify a device's PCI slot that you want to disable, it sounded like you could use this command to turn that slot's device off:

% echo 0 > /sys/bus/pci/slot/$N/power
1
  • 3
    I know how I can disable it at any other time, but I want to stop the kernel from activating it at all. Besides, since this is a hardwired PCI device (like most USB controllers), it has no slot. The machine I'm talking about is a laptop, and the only slot it has (/sys/bus/pci/slots/1) is the ExpressCard slot on the outside, which I can manually vacate.
    – Rhymoid
    Commented Feb 20, 2013 at 8:39
4

None of the answers solved my similar problem, but they did put me on the path to solving it!

My syslog error:

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

This is an internal usb hub-port for a bluetooth option I do not have.

unbind to the pci device just resulted in the hub popping back up as another hub (5 in my case) and flooding syslog further.

By chance I noticed an unbind structure under /sys/bus/usb/drivers/hub. Using examples above I just added the following in rc.local:

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

Result is syslog silence! Now to add kshurig's script example for power management and I should be golden.

3

When you already have echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci_hcd/unbind in /etc/rc.local for boot than you just need to put it into a script for the power management deamon aswell.

Goes like this: Create an executable bash script file named 0_disable_webcam in directory /etc/pm/sleep.d/:

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

It should work instantly. I tried it with an usb thumb drive and it worked (meaning it remained disabled) as long as the drive was plugged. Replugging would need udev rules but since your webcam will not be unplugged it should work. If that does not do the trick I have another suggestion.

1
  • If the above does not work then you have to find the correct usb port. I guess it is "1-1.2" ( otherwise check with tree /sys/bus/pci/devices/0000\:00\:1a.0/ under "usbX" which means the port is a similar number). If it is "1-1.2" instead of your echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci_hcd/unbind the script should have echo "auto" > /sys/bus/usb/devices/1-1.2/power/control; echo -n "1-1.2" > /sys/bus/usb/drivers/usb/unbind.
    – kschurig
    Commented Feb 24, 2013 at 0:01
0

not an answer to your question as much as a work around.

Why not simply suppress the logging of the messages to the console by modifying syslog / (I don't know if you use syslog or rsyslog or something else, so I can't really point you more specifically in the correct directory, but if you search your syslog config files for "console" and "tty", that would give you a good starting place - in fact, you can probably change console to /dev/tty1 [for example] and have messages only log to tty1 rather then all consoles.

The other solution (to answer your question, but I don't like), you could blacklist the ehci_hcd module (if its loaded), or recompile your kernel to use it only a s a module. Have a look at http://www.cyberciti.biz/faq/rhel-redhat-centos-kernel-usb-reset-high-speed-ehci_hcd/ which resolves exactly the question you are asking

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .