Here I present the conversion of everything that is required to provide the equivalent of g_ether.ko with configfs. A branch will be available here (from 28th May 2013, afternoon UTC): git://git.infradead.org/users/kmpark/linux-samsung usb-gadget-configfs v1..v2: - fixed compilation error if RNDIS is not selected - made f_eem build conditionally only if selected in .config - used ERR_CAST instead of ERR_PTR(PTR_ERR(x)) [reported by Fengguag Wu, thank you] - made geth_alloc and rndis_alloc static [reported by Fengguag Wu, thank you] - used memcpy instead of copying individual bytes [reported by Sergei Shtylov, thank you] This series requires the following series to be applied: http://comments.gmane.org/gmane.linux.usb.general/86773 http://comments.gmane.org/gmane.linux.usb.general/86783 http://www.spinics.net/lists/linux-usb/msg85307.html http://comments.gmane.org/gmane.linux.usb.general/86790 The g_ether consists of 4 USB functions, and 3 of them needed to be converted to the new interface and equipped with configfs support (a few patches per function), so this patch series is a bit lengthy (17 patches), but I tried to do the conversion in small, readable steps. BACKWARD COMPATIBILITY ====================== Please note that the old g_ether.ko is still available and works. USING THE NEW "GADGET" ====================== Please refer to this post: http://www.spinics.net/lists/linux-usb/msg76388.html for general information from Sebastian on how to use configfs-based gadgets (*). Here is the description specific to using g_ether.ko equivalent. Original g_ether ---------------- The original g_ether can contain CDC EEM, CDC ECM (or CDC ECM subset for devices which do not support full ECM) and RNDIS, depending on what is set in .config. Even if all of them are selected in .config, only one of them can be used at runtime. The above functions are assigned to two configurations: either EEM or ECM or ECM subset is the only function in one configuration, and RNDIS is the only function in the other. If the EEM/ECM/ECM subset configuration is selected by the host, then depending on the use_eem module parameter either EEM or ECM/ECM subset is used. The decision to use either ECM or ECM subset is made based on the can_support_ecm() static inline function found in u_ether.h. If no idVendor, idProduct module parameters are specified, the gadget uses different default values depending on which function will actually be used. No matter which function is actually used, only one network interface is created and registered. Configfs-based -------------- It is possible to create a gadget which is pretty close to the original g_ether with three exceptions: (1) for each function a new network interface is created, (2) a configuration's composition of a number of functions is done by user creating appropriate symbolic links and (3) idVendor/idProduct must be explicitly specified. What does that mean? As far as (1) is concerned, a gadget which has two configurations, one containing RNDIS and the other containing EEM, will cause two network interfaces to appear on the device(after bind): usb0 and usb1, while in the old gadget only one would be used (which, on the other hand, means that with the old gadget it is impossible to have e.g. EEM and RNDIS at the same time in the same configuration). The two interfaces created here could be an issue, but on the other hand on many (most?) systems udev will handle interfaces naming anyway. As for the (2), configurations in a configfs-based gadget can be composed at will of any available functions, but once a gadget is bound, the composition is fixed. The old gadget created the configuration programmaticaly at gadget's bind and included only one of EEM/ECM/ECM subset depending on the use_eem parameter and can_support_ecm() function's result. In other words, with configfs it is not possible to say "this configuration will contain either this function or that", but rather it is possible to say "this configuration will contain this set of functions". This could be an issue as well, but with configfs the gadgets are composed AT RUNTIME. This makes a huge difference compared to the old approach. The old approach was: if you want a USB gadget which contains this number of configurations and in each configuration it contains these functions, go create a new <supergadget>.c and compile it. Plus, if you want that in mainline, persuade Felipe and Greg to take it. But with configfs you have your building blocks in mainline (hopefully; Felipe?), and out of those you compose the gadget you want, and if you want a gadget which consists of different configurations/functions depending on some circumstances, everything can be achieved at runtime. No need to write C code at all. As far as g_ether.ko's equivalent is concerned, the equivalent of use_eem=1 module parameter boils down to instantiating the EEM function, while the equivalent of use_eem=0 module parameter boils down to having some userspace tool answer the "can_support_ecm()" question and instantiating either ECM or ECM subset. As for the (3), the ids are important for hosts to decide which drivers to use to talk to the interfaces in the newly enumerated gadget. In the old gadget there were some sensible defaults hardcoded and selected together with the functions at gadget's bind. Now the functions selection happens by creating the symlinks, and the idVendor/idProduct must be chosen appropriately, but once we know what functions to instantiate, we know what ids to use. How to use? ----------- With configfs the procedure is as follows, compared to the information mentioned above (*): instead of mkdir functions/acm.ttyS1 do mkdir functions/<ecm|eem|geth|rndis>.<instance name> e.g. mkdir functions/ecm.usb0 In functions/<function>.<instance name> there will be the following attribute files: qmult dev_addr host_addr ifname and after creating the functions/<function>.<instance name> they contain default values: qmult is 5, dev_addr and host_addr are randomly selected. Except for ifname they can be written to until the function is linked to a configuration. The ifname is read-only and contains the name of the interface which was assigned by the net core, e. g. usb0. The rest of the procedure (*) remains the same. An example gadget with two configurations, RNDIS and EEM: $ modprobe libcomposite $ mount none cfg -t configfs $ mkdir cfg/usb_gadget/g1 $ cd cfg/usb_gadget/g1 $ echo 0x0525 > idVendor $ echo 0xa4a2 > idProduct $ mkdir strings/0x409 $ echo Linux > strings/0x409/manufacturer $ echo "Ethernet/RNDIS gadget" > strings/0x409/product $ mkdir configs/c.1 $ echo 100 > configs/c.1/MaxPower $ mkdir configs/c.1/strings/0x409 $ echo "RNDIS" > configs/c.1/strings/0x409/configuration $ mkdir configs/c.2 $ echo 100 > configs/c.2/MaxPower $ mkdir configs/c.2/strings/0x409 $ echo "EEM" > configs/c.2/strings/0x409/configuration $ mkdir functions/rndis.usb0 # use default parameters $ mkdir functions/eem.usb1 # use default parameters ln -s functions/rndis.usb0 configs/c.1 ln -s functions/eem.usb1 configs/c.2 $ echo s3c-hsotg > UDC After unbinding the gadget with echo "" > UDC the symbolic links in the configuration directory can be removed, the strings/* subdirectories in the configuration directory can be removed, the strings/* subdirectories at the gadget level can be removed and the configs/* subdirectories can be removed. The functions/* subdirectories can be removed. After that the gadget directory can be removed. After that the respective modules can be unloaded. TESTING THE FUNCTIONS ===================== eem, ecm, ecm subset, rndis) On the device: ping <host's IP> On the host: ping <device's IP> (In order for ECM subset to activate in the old g_ether.ko, the can_support_ecm() function must be changed to return false unconditionally). Andrzej Pietrasiewicz (17): usb/gadget: u_ether: allow getting binary-form host address usb/gadget: ether: convert to new interface of f_ecm usb/gadget: f_eem: convert to new function interface with backward compatibility usb/gadget: ether: convert to new interface of f_eem usb/gadget: f_eem: remove compatibility layer usb/gadget: f_eem: use usb_gstrings_attach usb/gadget: f_eem: add configfs support usb/gadget: multi: Remove unused include usb/gadget: f_subset: convert to new function interface with backward compatibility usb/gadget: ether: convert to new interface of f_subset usb/gadget: f_subset: use usb_gstrings_attach usb/gadget: f_subset: add configfs support usb/gadget: f_rndis: convert to new function interface with backward compatibility usb/gadget: ether: convert to new interface of f_rndis usb/gadget: rndis: init & exit rndis at module load/unload usb/gadget: f_rndis: use usb_gstrings_attach usb/gadget: f_rndis: add configfs support Documentation/ABI/testing/configfs-usb-gadget-eem | 14 ++ .../ABI/testing/configfs-usb-gadget-rndis | 14 ++ .../ABI/testing/configfs-usb-gadget-subset | 14 ++ drivers/usb/gadget/Kconfig | 54 +++++ drivers/usb/gadget/Makefile | 6 + drivers/usb/gadget/ether.c | 177 +++++++++++--- drivers/usb/gadget/f_eem.c | 195 +++++++++++----- drivers/usb/gadget/f_rndis.c | 245 +++++++++++++++++--- drivers/usb/gadget/f_subset.c | 180 +++++++++++++-- drivers/usb/gadget/g_ffs.c | 2 + drivers/usb/gadget/multi.c | 2 +- drivers/usb/gadget/rndis.c | 4 +- drivers/usb/gadget/rndis.h | 3 - drivers/usb/gadget/u_eem.h | 36 +++ drivers/usb/gadget/u_ether.c | 9 + drivers/usb/gadget/u_ether.h | 11 +- drivers/usb/gadget/u_gether.h | 36 +++ drivers/usb/gadget/u_rndis.h | 41 ++++ 18 files changed, 897 insertions(+), 146 deletions(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-eem create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-rndis create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-subset create mode 100644 drivers/usb/gadget/u_eem.h create mode 100644 drivers/usb/gadget/u_gether.h create mode 100644 drivers/usb/gadget/u_rndis.h -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html