GadgetFS on Allwinner H3 based linux board

1.2k views Asked by At

I have the nanopi-neo which is an Allwinner H3 based linux board. It supports USB OTG mode so I wanted to try and convert it into slave by using GadgetFS.

From what I understand, I am supposed to rebuild the linux kernel provided by them with this option

<*>   USB Gadget Drivers
<*>     Gadget Filesystem

And for the rootfs use this

Package Selection for the target  --->
Hardware handling  --->
    [*] gadgetfs-test

I then proceeded to build and boot the board.

I followed this guide and used these commands

root:/dev> mkdir /dev/gadget  
root:/dev> mount -t gadgetfs gadgetfs /dev/gadget  
[  219.808688] WRN:L2558(drivers/usb/sunxi_usb/udc/sunxi_udc.c):ERR: Error in bind() : -120
[  219.827939] nop sunxi_usb_udc: failed to start (null): -120
root:/dev> ls /dev/gadget/ -l
total 0
-rw-------    1 root     root             0 Jan  1 00:03 sunxi_usb_udc

I am unable to find anything on this error. Most problems people face is regarding insmod but I have inbuilt the module inside the kernel. So I don't have this issue for sure.

I then found this post for sunxi i.e. allwinner sdk asking me to echo some values to otg_role, I did and i got this

echo 1 > /sys/bus/platform/devices/sunxi_usb_udc/otg_role
[  192.310934] sunxi-ehci sunxi-ehci.1: remove, state 4
[  192.326666] usb usb1: USB disconnect, device number 1
[  192.343775] sunxi-ehci sunxi-ehci.1: USB bus 1 deregistered
[  192.370300] sunxi-ohci sunxi-ohci.1: remove, state 4
[  192.385941] usb usb5: USB disconnect, device number 1
[  192.402761] sunxi-ohci sunxi-ohci.1: USB bus 5 deregistered
[  192.444442] sunxi-ehci sunxi-ehci.1: SW USB2.0 'Enhanced' Host Controller (EHCI) Driver
[  192.458113] sunxi-ehci sunxi-ehci.1: new USB bus registered, assigned bus number 1
[  192.471720] sunxi-ehci sunxi-ehci.1: irq 104, io mem 0xf1c1a000
[  192.500050] sunxi-ehci sunxi-ehci.1: USB 0.0 started, EHCI 1.00
[  192.511581] hub 1-0:1.0: USB hub found
[  192.519996] hub 1-0:1.0: 1 port detected
[  192.548993] sunxi-ohci sunxi-ohci.1: SW USB2.0 'Open' Host Controller (OHCI) Driver
[  192.561898] sunxi-ohci sunxi-ohci.1: new USB bus registered, assigned bus number 5
[  192.574365] sunxi-ohci sunxi-ohci.1: irq 105, io mem 0xf1c1a400
[  192.644522] hub 5-0:1.0: USB hub found
[  192.652612] hub 5-0:1.0: 1 port detected

root@kyloren:/$ # echo 2 > /sys/bus/platform/devices/sunxi_usb_udc/otg_role
[  195.940888] sunxi-ehci sunxi-ehci.1: remove, state 4
[  195.956330] usb usb1: USB disconnect, device number 1
[  195.976521] sunxi-ehci sunxi-ehci.1: USB bus 1 deregistered
[  195.997477] sunxi-ohci sunxi-ohci.1: remove, state 4
[  196.007624] usb usb5: USB disconnect, device number 1
[  196.018520] sunxi-ohci sunxi-ohci.1: USB bus 5 deregistered

And I try to mount again but I get the same error.

Can someone guide me on this?

1

There are 1 answers

0
J Evans On

Sometime much later ...

The short answer is you are missing the usermode component which actually instantiates the USB endpoints and handles setup and control requests.

An example of such a beast is to be found in 3 parts, links below.

The long version:

To use the H3 board as a device, you need to modprobe gadgetfs, create a directory mkdir -p /dev/gadget, and then mount the device into that directory with mount -t gadgetfs gadgetfs /dev/gadget.

Finally enable the device role with echo 2 > /sys/bus/platform/devices/sunxi_usb_udc/otg_role.

You will need to add the following to the autoconfig() function in usb.c as that code way predates AllWinner's very existence.

Once the usermode app (usb) is built, simply run it as sudo usb -v for verbose mode. If you are correctly plugged and powered your device should now show up on the host with 2 bulk endpoints and a single interrupt EP.

If you are trying to use mainline you will need to change the name of the controller in the code below (found in /dev/gadget) and add the right spell to the DTS file. Good luck with that as I've yet to get 4.11 to work in device mode on my NanoPi M1 and NanoPi Neo Air boards.

Hope this very belated is of use to someone at some point!

    if (stat(DEVNAME = "sunxi_usb_udc", &statb) == 0)
{
    HIGHSPEED = 1;
    fs_source_desc.bEndpointAddress = hs_source_desc.bEndpointAddress = USB_DIR_IN | 1;
    EP_IN_NAME = "ep1in-bulk";
    fs_sink_desc.bEndpointAddress = hs_sink_desc.bEndpointAddress = USB_DIR_OUT | 1;
    EP_OUT_NAME = "ep1out-bulk";
    source_sink_intf.bNumEndpoints = 3;
    fs_status_desc.bEndpointAddress = hs_status_desc.bEndpointAddress = USB_DIR_IN | 2;
    EP_STATUS_NAME = "ep2in-interrupt";
}

Main usermode driver

USB descriptor strings

Header file for the above