|
@@ -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)
|