[PATCH v2 00/17] Equivalent of g_ether.ko with configfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux