📄 composite.h
字号:
/* <linux/usb/composite.h> */
#ifndef __LINUX_USB_COMPOSITE_H
#define __LINUX_USB_COMPOSITE_H
#ifdef __KERNEL__
#include <linux/usb/ch9.h>
#include <linux/usb_gadget.h>
/* Support for composite configs, built from distinct function drivers.
* Example: one offering both network and mass storage functionality.
*/
struct usb_composite_dev;
struct usb_composite_driver;
/**
* struct usb_function - describes one function of a composite configuration
* @name: for diagnostics, identifies the function
* @strings: tables of strings, keyed by identifiers assigned during bind()
* and language IDs provided in control requests
* @descriptors: table of low/full speed descriptors, using interface and
* string identifiers assigned during bind()
* @hs_descriptors: table of high speed descriptors, using interface and
* string identifiers assigned during bind(); or null
* @function: each function is on the usb_composite.function list when the
* composite gadget is initialized, and then places itself in the right
* position(s) in usb_composite.functions[] during bind()
* @bind: before the gadget can register, all of its functions bind() to the
* available resources including identifiers for strings, interfaces,
* and endpoints
* @unbind: before the gadget can unregister, all of its functions unbind()
* the resources they have allocated.
* @setup: used for SET_INTERFACE, SET_CONFIGURATION, and interface-specific
* control requests
* @disconnect: used to notify functions when the host has disconnected
* @suspend: notifies functions when the host stops sending USB traffic
* @disconnect: notifies functions when the host reactivates the USB link
*
* A single USB function uses one or more interfaces, and supports dual speed
* operation on appropriate hardware.
*
* Only one instance of a function may be associated with a given composite
* configuration. Accordingly, data which a function driver needs in order
* to implement any callback can reasonably be static to that driver's module,
* or part of a structure within which the function struct has been embedded.
*/
struct usb_function {
const char *name;
struct usb_gadget_strings **strings;
const struct usb_descriptor_header **descriptors;
const struct usb_descriptor_header **hs_descriptors;
struct list_head function;
void *private_data;
/* REVISIT want multi-config at *same* speed too ...
* e.g. one has RNDIS, another has CDC-Ethernet
* not just high speed versions of each.
*/
int (*bind)(struct usb_composite_dev *,
struct usb_function *);
void (*unbind)(struct usb_composite_dev *,
struct usb_function *);
int (*setup)(struct usb_composite_dev *,
const struct usb_ctrlrequest *,struct usb_function *);
void (*disconnect)(struct usb_composite_dev *,struct usb_function *);
void (*suspend)(struct usb_composite_dev *);
void (*resume)(struct usb_composite_dev *);
};
/**
* struct usb_composite_driver -- groups functions into one gadget config
* @name: for diagnostics, identifies the driver
* @dev: descriptor for the device
* @strings: tables of strings, keyed by identifiers assigned during bind()
* and language IDs provided in control requests
* @bind: Used to build the list of functions, and to allocate for resources
* shared across the whole device such as string IDs. This can update
* device and configuration descriptors before functions bind().
* @unbind: optionally reverses bind()
* @setup: optionally used to delegate class and vendor control requests
*
* As with any gadget driver, there may be only one per system. Data that a
* composite gadget driver needs to implement any callback can reasonably be
* static to that driver's module, or part of a structure within which the
* driver struct has been embedded.
*
* FIXME device descriptor shouldn't be part of a per-config structure...
*/
struct usb_composite_driver {
const char *name;
const struct usb_device_descriptor *dev;
struct usb_gadget_strings **strings;
/* REVISIT want a general "add more descriptors for config N"
* hook; OTG should fall out naturally
*/
int (*bind)(struct usb_composite_dev *);
int (*unbind)(struct usb_composite_dev *);
int (*setup)(struct usb_composite_dev *,
const struct usb_ctrlrequest *);
void (*suspend)(struct usb_composite_dev *);
void (*suspend)(struct usb_composite_dev *);
/* REVISIT disconnect(), suspend(), resume() too ?? */
};
extern int usb_composite_register(struct usb_composite_driver *);
extern void usb_composite_unregister(struct usb_composite_driver *);
#define MAX_COMPOSITE_INTERFACES 8 /* max 16 */
/**
* struct usb_composite_device - represents one composite usb gadget
* @gadget: read-only, abstracts the gadget's usb peripheral controller
* @req: used for control responses; buffer is pre-allocated
* @bufsiz: size of buffer pre-allocated in @req
* @dev: device descriptor
* @functions: each function on this list after driver->bind() returns
* will be bound and initialized
* @config: configuration descriptor; if the device is not configured,
* its bConfigurationValue is zero and other fields are ignored
*
* REVISIT: this represents a composite configuration, and should
* be renamed accordingly...
*/
struct usb_composite_dev {
/* lock protects writes to all fields of this structure */
spinlock_t lock;
struct usb_gadget *gadget;
struct usb_request *req;
unsigned bufsiz;
struct usb_device_descriptor dev;
struct usb_config_descriptor config;
/* REVISIT need per-function state hook ... maybe a
* (void*) returned from bind() and passed to callbacks?
* arguably, interface descriptors are part of that...
*/
struct list_head functions;
struct usb_composite_driver *driver;
/* fields in the config descriptor */
u8 iConfiguration;
u8 bmAttributes;
u8 bMaxPower;
/* INTERNALS -- not for function drivers */
u8 next_string_id;
u8 next_interface_id;
void *current_bind;
struct usb_function *interface[MAX_COMPOSITE_INTERFACES];
struct usb_qualifier_descriptor qual;
};
/* IDs may be assigned ONLY during function driver bind() */
extern int usb_composite_string_id(struct usb_composite_dev *c);
extern int usb_composite_interface_id(struct usb_composite_dev *c);
static inline void
usb_composite_add_function(struct usb_composite_dev *c, struct usb_function *f)
{
list_add_tail(&f->function, &c->functions);
}
#endif /* __KERNEL__ */
#endif /* __LINUX_USB_COMPOSITE_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -