1
0
Fork 0
mirror of https://github.com/linux-usb-gadgets/libusbgx.git synced 2025-07-22 01:15:05 +03:00

libusbgx: common: Add alloc_inst() and free_inst() callbacks

Those callback can be used by specific function type to allocate
and then free more memory than in raw usbg_function structure.

Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
This commit is contained in:
Krzysztof Opasiak 2015-12-22 23:13:44 +01:00
parent 8c5f9cde66
commit 5ea221a027
10 changed files with 166 additions and 42 deletions

View file

@ -46,6 +46,14 @@ struct usbg_function_type
/* Name of this function type */
char *name;
/* Called to allocate instance of function */
int (*alloc_inst)(struct usbg_function_type *, usbg_function_type,
const char *, const char *, usbg_gadget *,
struct usbg_function **);
/* Called to free memory used by function */
void (*free_inst)(struct usbg_function_type *, struct usbg_function *);
/*
* Called when user would like to remove this function.
* If this callback is provided it will be always called
@ -252,6 +260,55 @@ int usbg_check_dir(const char *path);
#define usbg_config_is_string(node) \
(config_setting_type(node) == CONFIG_TYPE_STRING)
int usbg_init_function(struct usbg_function *f,
struct usbg_function_type *ops,
usbg_function_type type,
const char *type_name,
const char *instance,
const char *path,
struct usbg_gadget *parent);
int usbg_cleanup_function(struct usbg_function *f);
#define GENERIC_ALLOC_INST(prefix, _type, _member) \
static int prefix##_alloc_inst(struct usbg_function_type *type, \
usbg_function_type type_code, \
const char *instance, const char *path, \
struct usbg_gadget *parent, \
struct usbg_function **f) \
{ \
_type *ff; \
int ret; \
\
ff = malloc(sizeof(*ff)); \
if (!ff) \
return USBG_ERROR_NO_MEM; \
\
ret = usbg_init_function(&ff->_member, type, type_code, \
type->name, instance, path, parent); \
if (ret != USBG_SUCCESS) \
goto free_func; \
\
*f = &ff->_member; \
\
return ret; \
\
free_func: \
free(ff); \
out: \
return ret; \
}
#define GENERIC_FREE_INST(prefix, _type, _member) \
static void prefix##_free_inst(struct usbg_function_type *type, \
struct usbg_function *f) \
{ \
_type *ff = container_of(f, _type, _member); \
\
usbg_cleanup_function(&ff->_member); \
free(ff); \
}
typedef int (*usbg_attr_get_func)(const char *, const char *, const char *, void *);
typedef int (*usbg_attr_set_func)(const char *, const char *, const char *, void *);

View file

@ -18,6 +18,14 @@
#include <libconfig.h>
#endif
struct usbg_f_ether {
struct usbg_function func;
};
GENERIC_ALLOC_INST(ether, struct usbg_f_ether, func);
GENERIC_FREE_INST(ether, struct usbg_f_ether, func);
static int ether_set_attrs(struct usbg_function *f,
const usbg_function_attrs *f_attrs)
{
@ -216,6 +224,8 @@ out:
#endif /* HAS_LIBCONFIG */
#define ETHER_FUNCTION_OPTS \
.alloc_inst = ether_alloc_inst, \
.free_inst = ether_free_inst, \
.set_attrs = ether_set_attrs, \
.get_attrs = ether_get_attrs, \
.cleanup_attrs = ether_cleanup_attrs, \

View file

@ -17,6 +17,14 @@
#include <libconfig.h>
#endif
struct usbg_f_fs {
struct usbg_function func;
};
GENERIC_ALLOC_INST(ffs, struct usbg_f_fs, func);
GENERIC_FREE_INST(ffs, struct usbg_f_fs, func);
static int ffs_set_attrs(struct usbg_function *f,
const usbg_function_attrs *f_attrs)
{
@ -72,6 +80,8 @@ static int ffs_libconfig_export(struct usbg_function *f,
struct usbg_function_type usbg_f_type_ffs = {
.name = "ffs",
.alloc_inst = ffs_alloc_inst,
.free_inst = ffs_free_inst,
.set_attrs = ffs_set_attrs,
.get_attrs = ffs_get_attrs,
.cleanup_attrs = ffs_cleanup_attrs,

View file

@ -17,6 +17,14 @@
#include <libconfig.h>
#endif
struct usbg_f_loopback {
struct usbg_function func;
};
GENERIC_ALLOC_INST(loopback, struct usbg_f_loopback, func);
GENERIC_FREE_INST(loopback, struct usbg_f_loopback, func);
static int loopback_set_attrs(struct usbg_function *f,
const usbg_function_attrs *f_attrs)
{
@ -141,6 +149,8 @@ out:
struct usbg_function_type usbg_f_type_loopback = {
.name = "loopback",
.alloc_inst = loopback_alloc_inst,
.free_inst = loopback_free_inst,
.set_attrs = loopback_set_attrs,
.get_attrs = loopback_get_attrs,
#ifdef HAS_LIBCONFIG

View file

@ -18,6 +18,14 @@
#include <libconfig.h>
#endif
struct usbg_f_midi {
struct usbg_function func;
};
GENERIC_ALLOC_INST(midi, struct usbg_f_midi, func);
GENERIC_FREE_INST(midi, struct usbg_f_midi, func);
static int midi_set_attrs(struct usbg_function *f,
const usbg_function_attrs *f_attrs)
{
@ -216,6 +224,8 @@ out:
struct usbg_function_type usbg_f_type_midi = {
.name = "midi",
.alloc_inst = midi_alloc_inst,
.free_inst = midi_free_inst,
.set_attrs = midi_set_attrs,
.get_attrs = midi_get_attrs,
.cleanup_attrs = midi_cleanup_attrs,

View file

@ -21,6 +21,14 @@
#include <libconfig.h>
#endif
struct usbg_f_ms {
struct usbg_function func;
};
GENERIC_ALLOC_INST(ms, struct usbg_f_ms, func);
GENERIC_FREE_INST(ms, struct usbg_f_ms, func);
static inline int lun_select(const struct dirent *dent)
{
int ret;
@ -652,6 +660,8 @@ out:
struct usbg_function_type usbg_f_type_ms = {
.name = "mass_storage",
.alloc_inst = ms_alloc_inst,
.free_inst = ms_free_inst,
.set_attrs = ms_set_attrs,
.get_attrs = ms_get_attrs,
.cleanup_attrs = ms_cleanup_attrs,

View file

@ -18,6 +18,14 @@
#include <libconfig.h>
#endif
struct usbg_f_phonet {
struct usbg_function func;
};
GENERIC_ALLOC_INST(phonet, struct usbg_f_phonet, func);
GENERIC_FREE_INST(phonet, struct usbg_f_phonet, func);
static int phonet_set_attrs(struct usbg_function *f,
const usbg_function_attrs *f_attrs)
{
@ -71,6 +79,8 @@ static int phonet_libconfig_export(struct usbg_function *f,
struct usbg_function_type usbg_f_type_phonet = {
.name = "phonet",
.alloc_inst = phonet_alloc_inst,
.free_inst = phonet_free_inst,
.set_attrs = phonet_set_attrs,
.get_attrs = phonet_get_attrs,
.cleanup_attrs = phonet_cleanup_attrs,

View file

@ -17,6 +17,14 @@
#include <libconfig.h>
#endif
struct usbg_f_serial {
struct usbg_function func;
};
GENERIC_ALLOC_INST(serial, struct usbg_f_serial, func);
GENERIC_FREE_INST(serial, struct usbg_f_serial, func);
static int serial_set_attrs(struct usbg_function *f,
const usbg_function_attrs *f_attrs)
{
@ -92,8 +100,10 @@ static int serial_libconfig_import(struct usbg_function *f,
/* We don' import port_num as it is read only */
#define SERIAL_FUNCTION_OPTS \
.set_attrs = serial_set_attrs, \
.get_attrs = serial_get_attrs, \
.alloc_inst = serial_alloc_inst, \
.free_inst = serial_free_inst, \
.set_attrs = serial_set_attrs, \
.get_attrs = serial_get_attrs, \
SERIAL_LIBCONFIG_DEP_OPS, \
.import = serial_libconfig_import

View file

@ -284,10 +284,8 @@ static inline void usbg_free_binding(usbg_binding *b)
static inline void usbg_free_function(usbg_function *f)
{
free(f->path);
free(f->name);
free(f->label);
free(f);
if (f->ops->free_inst)
f->ops->free_inst(f->ops, f);
}
static void usbg_free_config(usbg_config *c)
@ -426,46 +424,16 @@ out:
return c;
}
static usbg_function *usbg_allocate_function(const char *path,
usbg_function_type type, const char *instance, usbg_gadget *parent)
static usbg_function *
usbg_allocate_function(const char *path, usbg_function_type type,
const char *instance, usbg_gadget *parent)
{
usbg_function *f;
const char *type_name;
int ret;
f = malloc(sizeof(*f));
if (!f)
goto out;
f->label = NULL;
type_name = usbg_get_function_type_str(type);
if (!type_name) {
free(f);
f = NULL;
goto out;
}
ret = asprintf(&(f->name), "%s.%s", type_name, instance);
if (ret < 0) {
free(f);
f = NULL;
goto out;
}
f->instance = f->name + strlen(type_name) + 1;
f->path = strdup(path);
f->parent = parent;
f->type = type;
f->ops = function_types[type];
if (!(f->path)) {
free(f->name);
free(f->path);
free(f);
f = NULL;
}
out:
return f;
ret = function_types[type]->alloc_inst(function_types[type], type,
instance, path, parent, &f);
return ret == 0 ? f : NULL;
}
static usbg_binding *usbg_allocate_binding(const char *path, const char *name,

View file

@ -265,7 +265,30 @@ int usbg_check_dir(const char *path)
return ret;
}
int usbg_init_function(struct usbg_function *f,
struct usbg_function_type *ops,
usbg_function_type type,
const char *type_name,
const char *instance,
const char *path,
struct usbg_gadget *parent)
{
int ret;
ret = asprintf(&(f->name), "%s.%s", type_name, instance);
if (ret < 0)
return USBG_ERROR_NO_MEM;
f->instance = f->name + strlen(type_name) + 1;
f->path = strdup(path);
f->parent = parent;
f->type = type;
f->ops = ops;
f->label = NULL;
memset(&f->fnode, 0, sizeof(f->fnode));
return 0;
}
int usbg_get_ether_addr(const char *path, const char *name,
const char *attr, void *val)
@ -423,3 +446,9 @@ int usbg_set_config_node_ether_addr(config_setting_t *root,
return usbg_set_config_node_string(root, node_name, &ptr);
}
int usbg_cleanup_function(struct usbg_function *f)
{
free(f->path);
free(f->name);
free(f->label);
}