Re: [RFC] Interface proposal to configure gadgets

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

 



Hi,

On Mon, Dec 19, 2011 at 03:33:45PM +0100, Sebastian Andrzej Siewior wrote:
> during the last few weeks/months I've been thinking about a
> configuration interface for the gadget framework. During the development
> of uasp I think I was able to fill some blanks. This is what banging
> through my head so far:
> 
> We have no dedicated configuration API for the gadget framework. What we
> have is a bunch of module parameters. Gadget's which are using the
> composite framework inherit a few of them like iManufacturer or
> idProduct. A few gadgets provide their own (gadget specific) module
> parameters that is cdrom for instance for the storage gadget or use_eem
> for the Ethernet gadget.
> Getting support for multiple gadgets (one gadget for one udc so we have
> two udcs in one system) at the same time will end up with _long_ module
> options and the need for a separator to distinguish between options for
> first udc and the second one. "," might appear handy but the storage
> gadget is using this for multiple lun configuration. *I* would prefer a
> consistent interface for all options. This also extends the kernel
> command line in case one decides to have everything built-in.
> 
> The next problem we have are the multiple-functions gadgets like the
> Nokia gadget which contains a few "different" functions each activated
> by a different configuration. And there seem to come more with different
> mix like serial/ethernet/obex/...
> 
> So what can be done about this? What about this:
> 
> Each gadget is providing nothing else but a function. We use then
> configfs (I had to use this for uasp and it is not that bad) to
> configure a gadget. If your blood pressure is rising please take a break
> and continue reading later :)
> 
> That means we take the folder:
> 
> /sys/kernel/config/gadget_or_what_ever:
> 
> and it contains a file:
>   available_functions
> 
> A cat on this will return bot, uasp, obex, for instance. Creating a new
> gadget would require:
> 
> # create a bare gadget:
>   mkdir FancyStorageGadget
> 
> Upon its creation, the folder will contain a few files representing
> descriptor configurable items like VendorID, DeviceID, Manufactor,
> Serial, ProductName, ...
> 
> Now you create two directories: function0 and function1

it would be nicer to get closer to the hierarchy we have on USB devices
themselves.

A USB device has one or more configurations and each configuration
contains one or more interfaces and each interface one or more
endpoints, so I would suggest something like:

# mkdir FancyGadget
# mkdir FancyGadget/configuration1
# ls FancyGadget/configuration1
maximum_power number_of_interfaces configuration_number

# cat FancyGadget/configuration1/maximum_power
0
# echo 900 > FancyGadget/configuration1/maximum_power
# cat configuration_number
1
# cat number_of_interfaces
0
# mkdir FancyGadget/configuration1/function0
# echo "bot" > FancyGadget/configuration1/function0/name
# cat number_of_interfaces
1

and so on. We need that in order to be able to have gadget with multiple
configurations which is widely used on devices which charge over USB.
They generally provide a High Power (500 on HS, 900 on SS) configuration
and lower power configurations after that. A SS device could have
configuration1 with 900mA, configuration2 with 500mA, configuration3
with 100mA and configuration4 with 8mA (for OTG sessions).

> in functionX you have a file named "name". You
>   echo "bot" > name
> which means function0 is bot. You do
>   echo "uasp" > name
> and you provide uasp for function1.
> 
> In functionX/ you can provide function related configuration. For
> instance have now removable=1 for the storage gadget.
> 
> You could also add a function2 which would provide a serial gadget and
> so on.
> 
> Now your gadget is complete and can go ahead and bind the
> FancyStorageGadget to an udc.
> 
> /sys/kernel/config/gadget_or_what_ever
>         +
>         +->FancyStorageGadget
>             + VendorID
>             + DeviceID
>             +->function0
>                 + name (=> ether)
>                 + qmult
>             +->function2
>                 + name (=> bot)
>             +->function1
>                 + name (=> uasp)
>                 + target_device

You need a way to activate the gadget. IOW, you need to expose the
usb_gadget_connect()/usb_gadget_disconnect() through this interface.
This will allow us to get rid of the usb_function_activate/deactivate
API which isn't solving the problem properly.

The problem I'm talking about is the synchronization between a kernel
pipe and a userland Stack (think OBEX, for instance).

> So. If more than one udc is available in the System they can be
> configured the same way. We can remove the Nokia gadget from the kernel
> and provide a configuration file how to achieve the same gadget with
> this new interface instead. Complex gadget which require bunch of option
> don't require long modprobe strings.
> Once the gadget is complete in terms of its configuration it can be
> bound to an udc and then connected.

sounds good.

> I understand that the echo/mkdir like interface is not perfect for
> everybody. For target there is a python tool that handles it so you/the
> user does not see configfs internals. The problem with python is that
> small users which ship just a busybox as their RFS might consider python
> as too big. Therefore I would suggest a small C program/library and

Yeah, a library is the way to go. It also "standardizes" the usage,
allows for lots of language bindings - so if you want to use
python/ruby/perl/C#/etc you can - and allows the whole thing to go into
products.

> everyone could provide bindings for every language that one needs. And
> if this is library is considered to much, the shell path is still open.

sure

> Those "configration steps" could be saved somewhere and re-used for the
> next time. Somewhere could be a shell script or .cfg file which is
> re-used the next time.

I can already envision some guys writing shell scripts which will get
called by udev directly. That would be cool for devices which only
provide one Gadget driver ;-)

> There is one problem here: I don't see a way how to get this done and
> providing compatibility for the modprobe / global variable way. If
> someone has an idea, I'm all yours.

I'm not against removing that completely. It's a whole bunch of code we
can remove:

drivers/usb/gadget/acm_ms.c       |  256 ------
drivers/usb/gadget/audio.c        |  187 -----
drivers/usb/gadget/cdc2.c         |  257 ------
drivers/usb/gadget/dbgp.c         |  433 ----------
drivers/usb/gadget/ether.c        |  413 ----------
drivers/usb/gadget/hid.c          |  288 -------
drivers/usb/gadget/mass_storage.c |  182 -----
drivers/usb/gadget/multi.c        |  362 ---------
drivers/usb/gadget/ncm.c          |  240 ------
drivers/usb/gadget/nokia.c        |  259 ------
drivers/usb/gadget/printer.c      | 1601 -------------------------------------
drivers/usb/gadget/serial.c       |  283 -------
drivers/usb/gadget/zero.c         |  353 --------
13 files changed, 0 insertions(+), 5114 deletions(-)

> The devel plan would look something like this:
> 
> - Have more people which like this than disagree and prefer the way it
>   is done now.
> - convert remaining gadgets to the composite framework.
> - remove global variables from gadgets/composite
> - make composite one file again and forget the #include
> - start implementing the gadget configfs interface
> - finish it and breath.
> 
> I might have forgotten the one or other point in my simple plan :)

you forgot about the library :-)

Sounds very good to me. It will tackle the issue of all these different
combinations of functions to pop-up (nokia, multi, acm_ms, etc), we can
use to push more stuff out of the kernel and it helps providing a more
stable interface to userland.

I'm in.

-- 
balbi

Attachment: signature.asc
Description: Digital signature


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

  Powered by Linux