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