August 12, 2020, 05:24:17 pm


Have you visited the Allwinner Chipset wiki? -

g_ether weirdness

Started by patwood, January 10, 2014, 12:49:02 am

Previous topic - Next topic


Has anyone noticed that with g_ether, you have to plug the cable into the host and CB OTG port before installing the g_ether module?  Otherwise, you get this message:

WRN:L2762(/home/pwood/arm/mk802/linux-sunxi/drivers/usb/sunxi_usb/udc/sw_udc.c):ERR: usb device is not active

and no connection when you plug in the cable?  Sometimes rmmod g_ether/modprobe g_ether works, but the multiple runs of modprobe g_ether also sometimes crash the kernel.

Has anyone found a workaround that either loads g_ether when the a host plugs into the OTG port or lets it wait until one plugs in before finishing loading?


Might it be that it polls the D+/- lanes for a fixed connection before loading as they need to have a 2.5v differential voltage between them?

Don't know for sure though.


I believe it does that, and if nothing is plugged in, the driver generates an error, but it still loads.  If you plug in the device after the driver loads, you get debug messages from the kernel that it's seen a host, but the driver won't recognize it (presumably because it's now in an error state and can't recover).  rmmoding and modprobing the g_ether driver resets it and creates the usb0 properly (or occasionally crashes the kernel), but that's no help if you're trying to connect to the board over OTG.

I was hoping someone had a patch for the g_ether driver or knew of some way to load the driver on OTG plugin.  I checked, and there are no udev or dbus events generated by the kernel when this happens.


I have to admit that this problem also occurred on beagleboards and has -as of yet and as far as I know- not been fixed.

Quickly looking into the usb_gadget driver it looks like it will bind to any registered usb driver with a port available (the first one anyway), no matter what the status, somewhere around line 345 in udc-core.c.

This is probably a two-way error in communication in the usb and gadget driver but as the sunxi usb drivers are mostly Chinese (comments at least) so it's not that easy to check. (And I'm not familiar with the usb drivers in linux)


January 24, 2014, 05:54:49 am #4 Last Edit: January 24, 2014, 06:44:51 am by dexterdidi1
Here is the patch that trigger udev events on udc enable/disable.
I have no way to test "offline" action, but "online" action worked for me.
I hope that this will help.

diff --git a/drivers/usb/sunxi_usb/udc/sw_udc.c b/drivers/usb/sunxi_usb/udc/sw_u
index 283ae4c..bccceef 100644
--- a/drivers/usb/sunxi_usb/udc/sw_udc.c
+++ b/drivers/usb/sunxi_usb/udc/sw_udc.c
@@ -3322,6 +3322,8 @@ int sw_usb_device_enable(void)

        DMSG_INFO_UDC("sw_usb_device_enable end\n");

+       kobject_uevent(&pdev->dev.kobj, KOBJ_ONLINE);
     return 0;

@@ -3382,6 +3384,8 @@ int sw_usb_device_disable(void)

        DMSG_INFO_UDC("sw_usb_device_disable end\n");

+       kobject_uevent(&pdev->dev.kobj, KOBJ_OFFLINE);
        return 0;

I also tried defered gadget bind call inside sw_udc.c (with home-brew patch) but the result was crash because ether.c/eth_bind is declared as __init and is free'd after gadget module initialization.


Thanks a bunch!  That change allows me to auto load/unload the g_ether driver with this rules.d file:

KERNEL=="sw_usb_udc" SUBSYSTEM=="platform", ACTION=="online", RUN+="/sbin/modprobe g_ether"
KERNEL=="sw_usb_udc" SUBSYSTEM=="platform", ACTION=="offline", RUN+="/sbin/rmmod g_ether"

Unfortunately, g_ether is buggy, so it can only be reliably loaded once; it crashes my CT about 50% of the time on the second load, so I've had to disable the unload event for now.  Still, once the driver starts up with a proper OTG connection it can handle unplugging and replugging the OTG port multiple times, so it doesn't ever need to be unloaded.