diff options
Diffstat (limited to 'include/linux/usb')
-rw-r--r-- | include/linux/usb/composite.h | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index dc512c9432d7..3834e3330b23 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -77,6 +77,8 @@ struct usb_configuration; * in interface or class descriptors; endpoints; I/O buffers; and so on. * @unbind: Reverses @bind; called as a side effect of unregistering the * driver which added this function. + * @free_func: free the struct usb_function. + * @mod: (internal) points to the module that created this structure. * @set_alt: (REQUIRED) Reconfigures altsettings; function drivers may * initialize usb_ep.driver data at this time (when it is used). * Note that setting an interface to its current altsetting resets @@ -116,6 +118,7 @@ struct usb_configuration; * two or more distinct instances within the same configuration, providing * several independent logical data links to a USB host. */ + struct usb_function { const char *name; struct usb_gadget_strings **strings; @@ -136,6 +139,8 @@ struct usb_function { struct usb_function *); void (*unbind)(struct usb_configuration *, struct usb_function *); + void (*free_func)(struct usb_function *f); + struct module *mod; /* runtime state management */ int (*set_alt)(struct usb_function *, @@ -432,6 +437,53 @@ static inline u16 get_default_bcdDevice(void) return bcdDevice; } +struct usb_function_driver { + const char *name; + struct module *mod; + struct list_head list; + struct usb_function_instance *(*alloc_inst)(void); + struct usb_function *(*alloc_func)(struct usb_function_instance *inst); +}; + +struct usb_function_instance { + struct usb_function_driver *fd; + void (*free_func_inst)(struct usb_function_instance *inst); +}; + +void usb_function_unregister(struct usb_function_driver *f); +int usb_function_register(struct usb_function_driver *newf); +void usb_put_function_instance(struct usb_function_instance *fi); +void usb_put_function(struct usb_function *f); +struct usb_function_instance *usb_get_function_instance(const char *name); +struct usb_function *usb_get_function(struct usb_function_instance *fi); + +struct usb_configuration *usb_get_config(struct usb_composite_dev *cdev, + int val); +int usb_add_config_only(struct usb_composite_dev *cdev, + struct usb_configuration *config); + +#define DECLARE_USB_FUNCTION(_name, _inst_alloc, _func_alloc) \ + static struct usb_function_driver _name ## usb_func = { \ + .name = __stringify(_name), \ + .mod = THIS_MODULE, \ + .alloc_inst = _inst_alloc, \ + .alloc_func = _func_alloc, \ + }; \ + MODULE_ALIAS("usbfunc:"__stringify(_name)); + +#define DECLARE_USB_FUNCTION_INIT(_name, _inst_alloc, _func_alloc) \ + DECLARE_USB_FUNCTION(_name, _inst_alloc, _func_alloc) \ + static int __init _name ## mod_init(void) \ + { \ + return usb_function_register(&_name ## usb_func); \ + } \ + static void __exit _name ## mod_exit(void) \ + { \ + usb_function_unregister(&_name ## usb_func); \ + } \ + module_init(_name ## mod_init); \ + module_exit(_name ## mod_exit) + /* messaging utils */ #define DBG(d, fmt, args...) \ dev_dbg(&(d)->gadget->dev , fmt , ## args) |