USB OTG and Ethernet dongles

Hi,

For development, we are using an NFS root filesystem on the
BeagleBoard, using a USB-Ethernet dongle connected through a powered
USB hub to the USB OTG port of the BeagleBoard (which is also the only
USB port we have on a rev B7). The kernel tree used is based on the
linux-omap-2.6 tree (with the PM branch merged in), version 2.6.29.1.

In USB host mode, it works very nicely. The kernel is loaded from the
SD card and boots. We had to integrate a small change in net/ipv4/
ipconfig.c to re-open the net devices after a DHCP timeout since USB
enumeration is an asynchronous process and can complete after the
kernel IP autoconfiguration has started. But the dongle in finally
detected, initialized, and the DHCP request gets an IP, allowing the
system to complete its boot process.

In USB OTG mode though, it's a completely different story. We have the
following config:

CONFIG_USB=y
CONFIG_USB_SUSPEND=y
CONFIG_USB_OTG=y

CONFIG_USB_MUSB_HDRC=y
CONFIG_USB_MUSB_SOC=y

CONFIG_USB_MUSB_OTG=y
CONFIG_USB_GADGET_MUSB_HDRC=y
CONFIG_USB_MUSB_HDRC_HCD=y
CONFIG_USB_INVENTRA_DMA=y

CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_SELECTED=y
CONFIG_USB_ETH=y

CONFIG_TWL4030_USB=y

And the following behavior is experienced:

  - On a cold boot, USB gets enumerated, the hub and the attached
Ethernet dongle are found and initialized. Everything is well and goes
very much like while in full host mode as described above.
  - But after one warm reset (either by system reboot, or pressing
reset), the hub and dongle are not detected anymore, and the USB Hub
driver goes to suspend and never wakes up. But on the next reset, it
works again. And on the next one, it doesn't work, and so on. It's a
very stable once every two boot failure (or success, depending on how
you see it).

Entirely disabling power management (CONFIG_PM not set) solves the
problem, but that's not really an acceptable solution. Simply
disabling USB_SUSPEND does not, though, make things better.

We first though of a VBUS detection problem, but VBUS is detected the
same way (same linkstat value in drivers/usb/otg/twl4030-usb.c),
regardless of the outcome of the boot attempt. USB probing could have
been a problem as well, as we're running with CONFIG_PREEMPT=y (see
drivers/usb/otg/twl4030-usb.c#twl4030_usb_probe), but disabling kernel
preemption didn't help either.

The fact that it works once every two boots makes this look like a
state problem, like some register that's not reset properly and it
needs an additional cycle to get right, but I must say this goes out
of my very small USB and/or low-level knowledge.

Was this problem experienced by other people? I couldn't find posts
about a similar issue, nor could find any solution :\

Thanks in advance for your help,
- Maxime

Continuing to look into this problem, it seems on boots that fail the
MUSB_DEVCTL register contains the MUSB_DEVCTL_VBUS bit, thus
preventing musb_start() to set the MUSB_DEVCTL_SESSION bit to this
register (drivers/usb/musb/musb_core.c:394). On successful boot
attempts, the _VBUS bit is not set.

Since the failed attempts happen after one successful boot, I suspect
the USB controller is not reset properly and the _VBUS bit is either
left on from the previous boot, or not cleared during the
initialization phase.

I haven't been able to locate more precisely the problem so far
though.

Still no one with ideas ? :slight_smile:

TIA!

I think I've gto a similar problem on my rev. C2 Beagleboard, a
MOSCHIP USB-ethernet dongle and the current Angström image. My
personal workaround is to unmount any NFS shares, run ifdown -a and
reboot afterwards. In this case, the Beagleboard reboots with the
static IP I've configured.
Of course, this is impossible to do if your root filesystem resides on
NFS. Maybe the solution described for Pegasus USB-ethernet adapters on
the James project page is better than my approach:
http://elinux.org/BeagleBoard/James#Configuring_the_image

Regards,

Samotian