BBB how to reset USB controller

Hi

I have a product using Beagle Bone Black running Debian GNU/Linux 10, BeagleBoard.org Debian Buster IoT Image 2020-04-06

I have an application and a custom cape using 4 serial com ports (1,2,4,5). I also use the USB-A port to connect to and Arduino board which creates a /dev/ttyUSBx device. I have given my USB port a fixed name “adlTapHub” using the idProduct and idVendor so it doesn’t change every time I reconnect the USB device.

I have shipped 100 units to a customer overseas, and after succcessful SI testing and installation on he first pilot, the second site they have installed has developed a problem where after about a day or 2 operation, my /dev/adlTapHub device disappears. My application continues to run and the 4 serial ports continue working, it only seems to be the ttyUSBx port affected.

I have tried unplugging and replugging the USB cable, and also power cycling the Arduino device (not powered from the USB cable), but this does not fix it.

Rebooting Linux on the BBB (without a power cycle) fixes the problem for another day or 2.

After much chasing my tail, I had the customer swap out the BBB and the problem seems to have gone away.

But I am looking for confirmation that this is just a one off fault BBB versus there being a problem with the BBB USB ports or USB controller driver.

I have read articles about reseting USB devices and controllers.
Experimenting I found can reset the USB device using usb reset eg

usbreset USB2.0-Serial
Resetting USB2.0-Serial … ok

When I do this, my ap temporarily loses the com port and then finds it and successfully reestablishes coms with it, so this works. But the problem is I am losing the device so I can’t reset it. eg if I unplug the USB cable this returns:

adl@adl-pump-controller:~$ sudo usbreset USB2.0-Serial
No such device found

I need to reset the USB Controller, and started following an article at https://www.linux.org/threads/resetting-the-usb-subsystem.10404/ but this does not seem to be compatible with the BBB and debian image.

Can anyone tell me how I can reset the USB controller on my BBB.

Thanks
Michael

Oh @MichaelS it looks like unbind/bind is a mess, some users recommend… usb_modeswitch

debian@BeagleBone:~$ uname -r
5.10.168-ti-r71
debian@BeagleBone:~$ lsusb
Bus 001 Device 018: ID 2e8a:000c Raspberry Pi Debug Probe (CMSIS-DAP)
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
debian@BeagleBone:~$ sudo usb_modeswitch -v 0x2e8a -p 0x000c --reset-usb
Look for default devices ...
 Found devices in default mode (1)
Access device 018 on bus 001
Get the current device configuration ...
Current configuration number is 1
Use interface number 0
 with class 255
Warning: no switching method given. See documentation
Reset USB device .
 Device was reset
-> Run lsusb to note any changes. Bye!
debian@BeagleBone:~$ sudo usb_modeswitch -v 0x2e8a -p 0x000c --reset-usb -W
Take all parameters from the command line


 * usb_modeswitch: handle USB devices with multiple modes
 * Version 2.6.1 (C) Josua Dietze 2017
 * Based on libusb1/libusbx

 ! PLEASE REPORT NEW CONFIGURATIONS !

DefaultVendor=  0x2e8a
DefaultProduct= 0x000c

Look for default devices ...
  found USB ID 2e8a:000c
   vendor ID matched
   product ID matched
  found USB ID 1d6b:0002
 Found devices in default mode (1)
Access device 018 on bus 001
Get the current device configuration ...
Current configuration number is 1
Use interface number 0
 with class 255

USB description data (for identification)
-------------------------
Manufacturer: Raspberry Pi
     Product: Debug Probe (CMSIS-DAP)
  Serial No.: E6614103E73D212F
-------------------------
Warning: no switching method given. See documentation
Reset USB device .
 Device was reset
-> Run lsusb to note any changes. Bye!
[  373.801662] usb 1-1: reset full-speed USB device number 18 using musb-hdrc
[  373.953322] cdc_acm 1-1:1.1: ttyACM0: USB ACM device
[  465.165175] usb 1-1: reset full-speed USB device number 18 using musb-hdrc
[  465.316596] cdc_acm 1-1:1.1: ttyACM0: USB ACM device
[  492.890146] usb 1-1: reset full-speed USB device number 18 using musb-hdrc
[  493.041314] cdc_acm 1-1:1.1: ttyACM0: USB ACM device

Regards,

Hi Robert
Thanks for the quick response.
Have people had problems withlike mine requiring a USB reset?

I ran:

lsusb
Bus 001 Device 004: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

I followed you example reseting 1a86:7523 and this works for resetting the USB-Serial adapter device. The com port disappears briefly and then comes back the same manner as when I run:

sudo usbreset USB2.0-Serial

But the problem I am trying to solve is my serial device disappears. I cant reproduce this here but if I unplug my USB cable so the device disappears and only the root hub show:

lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

If I try to reset the serial device now with it offline I get nothing to do:

sudo usb_modeswitch -v 0x1a86 -p 0x07523 --reset-usb -W
Take all parameters from the command line

  • usb_modeswitch: handle USB devices with multiple modes
  • Version 2.5.2 (C) Josua Dietze 2017
  • Based on libusb1/libusbx

! PLEASE REPORT NEW CONFIGURATIONS !

DefaultVendor= 0x1a86
DefaultProduct= 0x7523

Look for default devices …
found USB ID 1d6b:0002
No devices in default mode found. Nothing to do. Bye!

So I tried to reset the root hub as follows but this didn’t work - as follow:

sudo usb_modeswitch -v 0x1d6b -p 0x0002 --reset-usb -W
Take all parameters from the command line

  • usb_modeswitch: handle USB devices with multiple modes
  • Version 2.5.2 (C) Josua Dietze 2017
  • Based on libusb1/libusbx

! PLEASE REPORT NEW CONFIGURATIONS !

DefaultVendor= 0x1d6b
DefaultProduct= 0x0002

Look for default devices …
found USB ID 1a86:7523
found USB ID 1d6b:0002
vendor ID matched
product ID matched
Found devices in default mode (1)
Access device 001 on bus 001
Get the current device configuration …
Current configuration number is 1
Use interface number 0
with class 9

USB description data (for identification)

Manufacturer: Linux 4.19.94-ti-r42 musb-hcd
Product: MUSB HDRC host driver
Serial No.: musb-hdrc.1

Warning: no switching method given. See documentation
Reset USB device libusb: error [op_reset_device] reset failed error -1 errno 21
.libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
.libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
.libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
.libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
.libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
.libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
.libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
.libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
.libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
.libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
libusb: error [op_reset_device] reset failed error -1 errno 21
.
Device reset failed.
→ Run lsusb to note any changes. Bye!

I ran into a similar problem involving the BBB not having reasonably clean power coming in. I’m not going to get deeper into the details other than to say that when the 5V coming in dips below the minimum USB voltage (but not low enough to crash the BBB), the driver will shut off the USB-A. It does throw fault messages in /var/log/syslog. Kernel 4.19 would report it as “over-current” and 5.10 would be more specific and complain about USB undervoltage. In both cases, it would shut off the port.

I wound doing a brute-force detection/recovery action on the problem.
I polled the status and would do an unbind-bind action on the driver.

RCN’s method looks a lot more elegant, and I’ll have to give it a shot, but I’ll put my rather inelegant code stub here for your “entertainment”

		{
			FILE* usb1vbus =
				fopen("/sys/devices/platform/ocp/47400000.target-module/47401c00.usb/musb-hdrc.1/vbus", "r");

			fread(tempInputLine, sizeof(char), 1023, usb1vbus);
			fclose(usb1vbus);
			if ((strstr(tempInputLine, "bus off") > 0))
			{
				syslog(LOG_INFO, "USB-A Vbus shut off. Attempting reset of musb driver.\n");
				usb1vbus = fopen("/sys/bus/platform/drivers/musb-dsps/unbind", "w");
				if (usb1vbus != NULL)
				{
					fwrite("47401c00.usb", sizeof(char), strlen("47401c00.usb"), usb1vbus);
					fflush(usb1vbus);
					fclose(usb1vbus);
				}
				usb1vbus = fopen("/sys/bus/platform/drivers/musb-dsps/bind", "w");
				if (usb1vbus != NULL)
				{
					fwrite("47401c00.usb", sizeof(char), strlen("47401c00.usb"), usb1vbus);
					fflush(usb1vbus);
					fclose(usb1vbus);
				}
			}
		}

Hi John
Thanks for your help. Very helpful to know it is a low voltage issue. The cape I developed has a 5v 15W RECOM SMPS which is then summed with a Lithium battery before going into a Buck/Boost regulator which can provide 5V out to the BBB on P9 pins 6 & 6 with a battery voltage as low as 2.7V, and my tests show its is clean with extremely low ripple.

I powered a standalone BBB from a bench power supply via P9 pins 5&6 to test low voltage. I had to wind my 5V down to 3.9V for it to fault which is very low.
So maybe there is a fault with the hardware on the second affected pilot site.

Anyway now I have a way to reproduce the problem which is great.

Your software to restart the USB seems to work great. One issue though is the location of the vbus file to check the status seems to have changed.
Your source had it at:

“/sys/devices/platform/ocp/47400000.target-module/47401c00.usb/musb-hdrc.1/vbus”

On my image this does not exist and with a bit of exploration I found it at

“/sys/devices/platform/ocp/47400000.usb/47401c00.usb/musb-hdrc.1/vbus”

so “47400000.target-module” has been renamed “47400000.usb”

Any advice on finding this file more safely? I will make the file name and path configurable in case is changes in future.

Interesting when I wind the 5V down, serial coms stops but I don’t get any read or write errors from the USB com port even though the ttyUSBx port has disappeared.
Whereas when the USB is running ok, if I unplug the USB cable, I get write errors immediately.
If I close the serial port and try to reopen it, then I get an error on the open.
So I do need to monitor the USB status from the vbus file to know when to restart the USB.

Let me know how you go testing Roberts suggestion. I could only get this to reset the USB com device not the USB controller.
Thanks a lot for you help.
Michael

Just grep for that, “*.target-module” was something that changed in later kernels…

Regards,

Periodic polling of the of the status is what I did. My application involves users jamming usb storage devices into usb1, and power instability using the internal boost regulator on a poorly tuned MAX77818 battery management IC.

On the usb status file location movement thing:
The good news is that the path only changes with the kernel version, which means you can do a table based on what /proc/version tells you. In the worst case, you could use popen(3) with a call to find & grep to hunt down the location. Some of the interim revisions of the kernel shuffled the gpio port enumeration.

I may not get to trying out RCN’s thing right away. The current thing stymieing me is trying to figure out what device tree parameter for the FT5336 (or /sys interface trigger) I need to tweak to let Kernel 5.10.65 know that I want it to set the AM3358 gpio0[27] as a wake-up from standby trigger when i set it to go to sleep.
You may see a post for that in a few.