Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 354640
b: refs/heads/master
c: de53c25
h: refs/heads/master
v: v3
  • Loading branch information
Sebastian Andrzej Siewior authored and Felipe Balbi committed Jan 21, 2013
1 parent e600ee8 commit 866463c
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 78f46f09a80a39fe646fe415a21435f2a05df6c2
refs/heads/master: de53c25447117eae6b3f8952f663f08a09e0dbb7
2 changes: 1 addition & 1 deletion trunk/drivers/usb/gadget/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG
obj-$(CONFIG_USB_GADGET) += udc-core.o
obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o
libcomposite-y := usbstring.o config.o epautoconf.o
libcomposite-y += composite.o
libcomposite-y += composite.o functions.o
obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o
obj-$(CONFIG_USB_NET2272) += net2272.o
obj-$(CONFIG_USB_NET2280) += net2280.o
Expand Down
47 changes: 30 additions & 17 deletions trunk/drivers/usb/gadget/composite.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,31 @@ static int set_config(struct usb_composite_dev *cdev,
return result;
}

int usb_add_config_only(struct usb_composite_dev *cdev,
struct usb_configuration *config)
{
struct usb_configuration *c;

if (!config->bConfigurationValue)
return -EINVAL;

/* Prevent duplicate configuration identifiers */
list_for_each_entry(c, &cdev->configs, list) {
if (c->bConfigurationValue == config->bConfigurationValue)
return -EBUSY;
}

config->cdev = cdev;
list_add_tail(&config->list, &cdev->configs);

INIT_LIST_HEAD(&config->functions);
config->next_interface_id = 0;
memset(config->interface, 0, sizeof(config->interface));

return 0;
}
EXPORT_SYMBOL_GPL(usb_add_config_only);

/**
* usb_add_config() - add a configuration to a device.
* @cdev: wraps the USB gadget
Expand All @@ -703,30 +728,18 @@ int usb_add_config(struct usb_composite_dev *cdev,
int (*bind)(struct usb_configuration *))
{
int status = -EINVAL;
struct usb_configuration *c;

if (!bind)
goto done;

DBG(cdev, "adding config #%u '%s'/%p\n",
config->bConfigurationValue,
config->label, config);

if (!config->bConfigurationValue || !bind)
status = usb_add_config_only(cdev, config);
if (status)
goto done;

/* Prevent duplicate configuration identifiers */
list_for_each_entry(c, &cdev->configs, list) {
if (c->bConfigurationValue == config->bConfigurationValue) {
status = -EBUSY;
goto done;
}
}

config->cdev = cdev;
list_add_tail(&config->list, &cdev->configs);

INIT_LIST_HEAD(&config->functions);
config->next_interface_id = 0;
memset(config->interface, 0, sizeof(config->interface));

status = bind(config);
if (status < 0) {
while (!list_empty(&config->functions)) {
Expand Down
52 changes: 52 additions & 0 deletions trunk/include/linux/usb/composite.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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 *,
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 866463c

Please sign in to comment.