USB power cycling poblem on RPI

I am having a problem with cycling USB bus power on the RPI B+ (3.18.7+).

Each time I power the USB bus off and on, a device plugged into it gets a higher Device number, and eventually the bus crashes (does not enumerate new devices any more)

As a demonstration, I wrote the python script at the bottom, which just turns the bus on and off and runs lsusb in an infinite loop.
I had trouble with a USB GSM modem, but even when I plug a simple TI launchpad (MSP430 experimenter board) in the bus, it will disappear after some cycles.

I have the impression that the USB controller or software thinks there are 82 devices on the bus, which is probably why it crashes.
Is there a way to completely reset the USB bus software/hardware so it will start counting from zero again?
Another solution would be a command that removes the device from the bus before I turn it off, so it would probably get the same Device number when it is switched on again.
I have tried without success:

  • Increasing the sleep times in the script
  • Running "/etc/init.d/udev restart"
  • turning the entire hub off and on with "hub-ctrl -h 0 -p 0/1"
  • �echo '1-1' | tee /sys/bus/usb/drivers/usb/unbind� (and re-bind afterwards)

The output of the python script when it starts to fail (after about 80 cycles) is:

Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 081: ID 0451:f432 Texas Instruments, Inc. eZ430 Development Tool
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 082: ID 0451:f432 Texas Instruments, Inc. eZ430 Development Tool
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

the script itself is:

#!/usr/bin/python
from subprocess import call
import time

while True:
call(["hub-ctrl", "-h", "0", "-P", "2", "-p", "0"]) # turn off the USB modem
time.sleep(1)
call(["hub-ctrl", "-h", "0", "-P", "2", "-p", "1"]) # turn off the USB modem
time.sleep(2)
call(["lsusb"]) # print

When it (the modem) fails, I get the 4 lines below in the /var/log/messages file after unplugging and re plugging the device ONCE:

Feb 19 15:32:43 aardbei kernel: [ 8195.531922] usb 1-1.5: new full-speed USB device number 82 using dwc_otg
Feb 19 15:32:43 aardbei kernel: [ 8195.991933] usb 1-1.5: new full-speed USB device number 83 using dwc_otg
Feb 19 15:32:43 aardbei kernel: [ 8196.451884] usb 1-1.5: new full-speed USB device number 84 using dwc_otg
Feb 19 15:32:44 aardbei kernel: [ 8196.951966] usb 1-1.5: new full-speed USB device number 85 using dwc_otg

Posts: 20Joined: Wed Mar 05, 2014 9:32 am

It may be possible, if you compile your USB controllers etc. drivers as modules. Then you could rmmod them and modprobe them to reload.

I know it's difficult to get a listing of a crash from the kernel after it's crashed, but it would be interesting to see it if you could manage a photograph.

Most USB controllers can't do this, I'm not surprised there are bugs or pitfalls. Perhaps there's something that needs to be done first, before you force it off.

...and you certainly do not need all of Python to do this. Just do this:

#!/bin/sh

while true
do
        hub-ctrl -h 0 -P 2 -p 0
        sleep 1
        hub-ctrl -h 0 -P 2 -p 1
        sleep 1
        lsusb
done

Thanks for the help,
The kernel doesn't crash, only the USB part does (not detecting new devices that are plugged in).

I thought of using modules as well, but then I have to get the sourcecode, recompile the kernel and on the next RPI upgrade the problem will reappear.
I think it is unavoidable that I will have to reboot each time this happens (which will probably be about once a day)

I always thought the advantage of Linux over windows was that you didn't have to reboot to resolve silly problems like this...

Can you even do this in Windows?

Anyway, you know a method that may help and refuse to use it. And don't seem to be reporting the bug to kernel.org either, which would be another thing that might help.