USB Composite Gadget Framework

Hi all,

Let's take a look at the brand new, yet-to-be-merged USB Composite Gadget Framework.

The framework was introduced by Linux USB Developer David Brownell and, thanks to his great work, we're gonna be able to reuse what we now call usb function drivers into another entities, combining them to create a usb composite gadget.

Quoting Dave himself:

We want to split most of the current gadget drivers into reusable/combinable "usb_function" entities, making it easier to set up composite and multi-configuration gadgets.

The framework allowed us to write simpler usb function drivers and glue code between the various kernel APIs and later on, with the framework provided in drivers/usb/gadget/composite.c, create our own composite gadget.

Basically, we just have to provide a struct usb_function with the correct function pointers to the upper layer and that's all. This is how struct usb_function is defined:

struct usb_function {
	const char			*name;
	struct usb_gadget_strings	**strings;
	struct usb_descriptor_header	**descriptors;
	struct usb_descriptor_header	**hs_descriptors;
 
	struct usb_configuration	*config;
 
	int			(*bind)(struct usb_configuration *,
					struct usb_function *);
	void			(*unbind)(struct usb_configuration *,
					struct usb_function *);
	int			(*set_alt)(struct usb_function *,
					unsigned interface, unsigned alt);
	int			(*get_alt)(struct usb_function *,
					unsigned interface);
	void			(*disable)(struct usb_function *);
	int			(*setup)(struct usb_function *,
					const struct usb_ctrlrequest *);
 
	void			(*suspend)(struct usb_function *);
	void			(*resume)(struct usb_function *);
 
	struct list_head		list;
};

Let me explain each member of this structure.

  1. name: give a name to this usb_function
  2. descriptors: fullspeed descriptor headers
  3. hs_descriptors: same as above but with highspeed endpoints
  4. config: the configuration
  5. bind: will be called on an upper layer (likely) to bind this interface and combine it into the device structure, also allocate any needed resources
  6. unbind: release used resources
  7. set_alt: set alternate setting we need to use now
  8. get_alt: get the current alternate setting been used
  9. disable: disable endpoints
  10. setup: setup ep0 functionality
  11. suspend: put the function driver in suspend mode (for pm)
  12. resume: wake function driver up from suspend mode

In Dave's series, he already splitted (the example gadget) and Gadget Serial into reusable function drivers. In the case of Gadget Serial he also wrote the glue code for the TTY over USB.

All of you are invited to help us writing other function drivers and also splitting the existing gadget drivers into reusable entities like it was done for Gadget Serial.

I'm putting together some small tips in this page so feel free to take a look and start hacking the Linux Kernel.

Don't forget to check out linux-usb archives here to keep track of what's happening with this framework.

See y'all

VN:F [1.7.0_948]
Rating: 0.0/5 (0 votes cast)
VN:F [1.7.0_948]
Rating: 0 (from 0 votes)

Tags: , , ,

2 Responses to “USB Composite Gadget Framework”

  1. Martin Rogers says:

    Hello Mr. Balbi,

    you probably don’t remember me, but I used your composite gadget code last year.
    I see that it has been rewritten. I am interested in running it on 2.6.21-7 on ARM
    (another porting exercise… :) ).

    I can’t tell what it’s status is, or how to get the latest. Can you point me in the
    right direction?

    Thanks so much,
    Martin Rogers

    UN:F [1.7.0_948]
    Rating: 0.0/5 (0 votes cast)
    UN:F [1.7.0_948]
    Rating: 0 (from 0 votes)
  2. Felipe Balbi says:

    Sorry for the long time without looking at the blog, but hey. If you want the newest composite framework code, you just need to look into Linux-2.6. Hope it helps you :-)

    UA:F [1.7.0_948]
    Rating: 0.0/5 (0 votes cast)
    UA:F [1.7.0_948]
    Rating: 0 (from 0 votes)

Leave a Reply