-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
usb: gadget: add a forward pointer from usb_function to its "instance"
We can have multiple usb_functions which origin is the same "instance". Within one USB configuration there should be only one function of an instance. This back pointer helps configfs to recoginze to which instance a given usb_function belongs. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>
- Loading branch information
Sebastian Andrzej Siewior
authored and
Felipe Balbi
committed
Jan 21, 2013
1 parent
59835ad
commit 0062f6e
Showing
2 changed files
with
117 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#include <linux/kernel.h> | ||
#include <linux/slab.h> | ||
#include <linux/module.h> | ||
#include <linux/err.h> | ||
|
||
#include <linux/usb/composite.h> | ||
|
||
static LIST_HEAD(func_list); | ||
static DEFINE_MUTEX(func_lock); | ||
|
||
static struct usb_function_instance *try_get_usb_function_instance(const char *name) | ||
{ | ||
struct usb_function_driver *fd; | ||
struct usb_function_instance *fi; | ||
|
||
fi = ERR_PTR(-ENOENT); | ||
mutex_lock(&func_lock); | ||
list_for_each_entry(fd, &func_list, list) { | ||
|
||
if (strcmp(name, fd->name)) | ||
continue; | ||
|
||
if (!try_module_get(fd->mod)) { | ||
fi = ERR_PTR(-EBUSY); | ||
break; | ||
} | ||
fi = fd->alloc_inst(); | ||
if (IS_ERR(fi)) | ||
module_put(fd->mod); | ||
else | ||
fi->fd = fd; | ||
break; | ||
} | ||
mutex_unlock(&func_lock); | ||
return fi; | ||
} | ||
|
||
struct usb_function_instance *usb_get_function_instance(const char *name) | ||
{ | ||
struct usb_function_instance *fi; | ||
int ret; | ||
|
||
fi = try_get_usb_function_instance(name); | ||
if (!IS_ERR(fi)) | ||
return fi; | ||
ret = PTR_ERR(fi); | ||
if (ret != -ENOENT) | ||
return fi; | ||
ret = request_module("usbfunc:%s", name); | ||
if (ret < 0) | ||
return ERR_PTR(ret); | ||
return try_get_usb_function_instance(name); | ||
} | ||
EXPORT_SYMBOL_GPL(usb_get_function_instance); | ||
|
||
struct usb_function *usb_get_function(struct usb_function_instance *fi) | ||
{ | ||
struct usb_function *f; | ||
|
||
f = fi->fd->alloc_func(fi); | ||
if (IS_ERR(f)) | ||
return f; | ||
f->fi = fi; | ||
return f; | ||
} | ||
EXPORT_SYMBOL_GPL(usb_get_function); | ||
|
||
void usb_put_function_instance(struct usb_function_instance *fi) | ||
{ | ||
struct module *mod; | ||
|
||
if (!fi) | ||
return; | ||
|
||
mod = fi->fd->mod; | ||
fi->free_func_inst(fi); | ||
module_put(mod); | ||
} | ||
EXPORT_SYMBOL_GPL(usb_put_function_instance); | ||
|
||
void usb_put_function(struct usb_function *f) | ||
{ | ||
if (!f) | ||
return; | ||
|
||
f->free_func(f); | ||
} | ||
EXPORT_SYMBOL_GPL(usb_put_function); | ||
|
||
int usb_function_register(struct usb_function_driver *newf) | ||
{ | ||
struct usb_function_driver *fd; | ||
int ret; | ||
|
||
ret = -EEXIST; | ||
|
||
mutex_lock(&func_lock); | ||
list_for_each_entry(fd, &func_list, list) { | ||
if (!strcmp(fd->name, newf->name)) | ||
goto out; | ||
} | ||
ret = 0; | ||
list_add_tail(&newf->list, &func_list); | ||
out: | ||
mutex_unlock(&func_lock); | ||
return ret; | ||
} | ||
EXPORT_SYMBOL_GPL(usb_function_register); | ||
|
||
void usb_function_unregister(struct usb_function_driver *fd) | ||
{ | ||
mutex_lock(&func_lock); | ||
list_del(&fd->list); | ||
mutex_unlock(&func_lock); | ||
} | ||
EXPORT_SYMBOL_GPL(usb_function_unregister); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters