-
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.
yaml --- r: 354651 b: refs/heads/master c: 0062f6e h: refs/heads/master i: 354649: bd407ed 354647: b2170d3 v: v3
- Loading branch information
Sebastian Andrzej Siewior
authored and
Felipe Balbi
committed
Jan 21, 2013
1 parent
c91c514
commit c1ca84b
Showing
3 changed files
with
118 additions
and
1 deletion.
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 |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 59835ad727876f6ce5c18ce075e144a8fa989461 | ||
refs/heads/master: 0062f6e56f70bd2230ba1ebd1667d1b32a1af3b2 |
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