int ret;
/* TODO: Add some good error handling */
+ if (!socket_name)
+ return -EINVAL;
left = sizeof(buf);
pos = buf;
if (usb_func->function_group ==
USB_FUNCTION_GROUP_WITH_SERVICE) {
- struct usb_function_with_service *fws;
-
- fws = container_of(usb_func,
- struct usb_function_with_service,
- func);
- ret = cfs_prep_ffs_service(usb_func->name,
- usb_func->instance,
- instance,
- fws->service);
- if (ret)
- return ret;
+ if (usb_func->service) {
+ ret = cfs_prep_ffs_service(usb_func->name,
+ usb_func->instance,
+ instance,
+ usb_func->service);
+ if (ret)
+ return ret;
+ }
}
}
int ret;
struct usb_gadget *gadget;
struct cfs_client *cfs_client;
- struct usb_function_with_service *fws;
if (!usb)
return -EINVAL;
if (gadget->funcs[i]->function_group != USB_FUNCTION_GROUP_WITH_POST_SERVICE)
continue;
- fws = container_of(gadget->funcs[i], struct usb_function_with_service, func);
- (void)systemd_start_unit_wait_started(fws->service, ".service", -1);
+ if (gadget->funcs[i]->service)
+ (void)systemd_start_unit_wait_started(gadget->funcs[i]->service, ".service", -1);
}
cfs_free_gadget(gadget);
int ret;
struct usb_gadget *gadget;
struct cfs_client *cfs_client;
- struct usb_function_with_service *fws;
if (!usb)
return -EINVAL;
if (gadget->funcs[i]->function_group != USB_FUNCTION_GROUP_WITH_POST_SERVICE)
continue;
- fws = container_of(gadget->funcs[i], struct usb_function_with_service, func);
- (void)systemd_stop_unit_wait_stopped(fws->service, ".service", -1);
+ if (gadget->funcs[i]->service)
+ (void)systemd_stop_unit_wait_stopped(gadget->funcs[i]->service, ".service", -1);
}
cfs_free_gadget(gadget);
continue;
usb_func = _available_funcs[ret];
- if (usb_func->function_group ==
- USB_FUNCTION_GROUP_WITH_SERVICE) {
- struct usb_function_with_service *fws;
-
- fws = container_of(usb_func,
- struct usb_function_with_service,
- func);
- systemd_stop_unit_wait_stopped(fws->service, ".socket", -1);
- systemd_stop_unit_wait_stopped(fws->service, ".service", -1);
+ if (usb_func->function_group == USB_FUNCTION_GROUP_WITH_SERVICE) {
+ if (usb_func->service) {
+ systemd_stop_unit_wait_stopped(usb_func->service, ".socket", -1);
+ systemd_stop_unit_wait_stopped(usb_func->service, ".service", -1);
+ }
}
}
int val;
int ret;
/* We assume that values received from kernel will be valid */
-#define GET_VALUE_FROM_SYSFS(path, field, type, base) \
- do { \
+#define GET_VALUE_FROM_SYSFS(path, field, type, base) \
+ do { \
ret = get_int_from_file(path, &val, base); \
- if (ret) \
- return ret; \
- \
- gadget->attrs.field = (type)val; \
+ if (ret) \
+ return ret; \
+ \
+ gadget->attrs.field = (type)val; \
} while (0)
GET_VALUE_FROM_SYSFS(LEGACY_CLASS_PATH, bDeviceClass, uint8_t, 0);
int ret;
int i;
struct usb_gadget *gadget;
- struct usb_function_with_service *fws;
ret = sys_set_str(LEGACY_ENABLE_PATH,
LEGACY_ENABLE);
goto disable_gadget;
for (i = 0; gadget->funcs[i]; ++i) {
- if (gadget->funcs[i]->function_group == USB_FUNCTION_GROUP_SIMPLE)
- continue;
-
- fws = container_of(gadget->funcs[i], struct usb_function_with_service, func);
- (void)systemd_start_unit_wait_started(fws->service, ".service", -1);
+ if (gadget->funcs[i]->service)
+ (void)systemd_start_unit_wait_started(gadget->funcs[i]->service, ".service", -1);
}
legacy_free_gadget(gadget);
int ret;
int i;
struct usb_gadget *gadget;
- struct usb_function_with_service *fws;
ret = legacy_get_current_gadget(usb, &gadget);
if (ret < 0)
return ret;
for (i = 0; gadget->funcs[i]; ++i) {
- if (gadget->funcs[i]->function_group == USB_FUNCTION_GROUP_SIMPLE)
- continue;
-
- fws = container_of(gadget->funcs[i], struct usb_function_with_service, func);
- (void)systemd_stop_unit_wait_stopped(fws->service, ".service", -1);
+ if (gadget->funcs[i]->service)
+ (void)systemd_stop_unit_wait_stopped(gadget->funcs[i]->service, ".service", -1);
}
ret = sys_set_str(LEGACY_ENABLE_PATH, LEGACY_DISABLE);
/* Count number of trailing zeros using Dean Gaudet's algorithm */
#define _HELPER_CTZ(mask) \
((_HELPER_Y(mask) ? 0 : 1) + \
- ((_HELPER_Y(mask) & 0x0000FFFF) ? 0 : 16) + \
- ((_HELPER_Y(mask) & 0x00FF00FF) ? 0 : 8) + \
- ((_HELPER_Y(mask) & 0x0F0F0F0F) ? 0 : 4) + \
- ((_HELPER_Y(mask) & 0x33333333) ? 0 : 2) + \
- ((_HELPER_Y(mask) & 0x55555555) ? 0 : 1))
+ ((_HELPER_Y(mask) & 0x0000FFFF) ? 0 : 16) + \
+ ((_HELPER_Y(mask) & 0x00FF00FF) ? 0 : 8) + \
+ ((_HELPER_Y(mask) & 0x0F0F0F0F) ? 0 : 4) + \
+ ((_HELPER_Y(mask) & 0x33333333) ? 0 : 2) + \
+ ((_HELPER_Y(mask) & 0x55555555) ? 0 : 1))
/* Function IDX in array is number of trailing zeros */
#define FUNC_IDX_FROM_MASK(mask) _HELPER_CTZ(mask)
const char *name;
const char *instance;
+ const char *service;
+
int (*clone)(struct usb_function *func, struct usb_function **_clone);
void (*free_func)(struct usb_function *func);
};
-struct usb_function_with_service {
- struct usb_function func;
- const char *service;
-};
-
struct usb_configuration_attributes {
uint8_t bmAttributs;
int MaxPower;
};
typedef enum {
- USB_FUNCTION_NONE = 0,
+ USB_FUNCTION_NONE = 0,
USB_FUNCTION_MTP = 1 << 0,
USB_FUNCTION_ACM = 1 << 1,
USB_FUNCTION_SDB = 1 << 2,
USB_FUNCTION_RMNET = 1 << 7,
} usb_function_e;
-static void free_simple_func_content(struct usb_function *func)
-{
- free((void *)func->name);
- free((void *)func->instance);
-}
-
static void free_simple_func(struct usb_function *func)
{
- free_simple_func_content(func);
- free(func);
-}
-
-static int clone_simple_func_to(struct usb_function *func,
- struct usb_function *other)
-{
- *other = *func;
- other->name = strdup(func->name);
- other->instance = strdup(func->instance);
-
- if (!other->name || !other->instance)
- goto free_strs;
-
- return 0;
-free_strs:
- free((void *)other->name);
- free((void *)other->instance);
- return -ENOMEM;
+ if (func) {
+ free((void *)func->name);
+ free((void *)func->instance);
+ free((void *)func->service);
+ free(func);
+ }
}
static int clone_simple_func(struct usb_function *func,
struct usb_function **clone)
{
struct usb_function *other;
- int ret;
if (!func || !clone)
return -EINVAL;
- other = (struct usb_function *)malloc(sizeof(*other));
+ other = (struct usb_function *)calloc(1, sizeof(struct usb_function));
if (!other)
- goto out;
+ return -ENOMEM;
- ret = clone_simple_func_to(func, other);
- if (ret)
- goto free_other;
+ *other = *func;
- *clone = other;
- return 0;
-free_other:
- free(other);
-out:
- return -ENOMEM;
-}
+ other->name = strdup(func->name);
+ other->instance = strdup(func->instance);
+ if (!other->name || !other->instance)
+ goto out_nomem;
-#define DEFINE_SIMPLE_USB_FUNCTION(_id, _name) \
- static struct usb_function _##_name##_function = { \
- .function_group = USB_FUNCTION_GROUP_SIMPLE, \
- .id = _id, \
- .name = #_name, \
- .instance = "default", \
- .clone = clone_simple_func, \
- .free_func = free_simple_func, \
+ if (func->service) {
+ other->service = strdup(func->service);
+ if (!other->service)
+ goto out_nomem;
}
-DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_DIAG, diag);
-DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_RMNET, rmnet);
-DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_DM, dm);
-DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_CONN_GADGET, conn_gadget);
-
-#undef DEFINE_SIMPLE_USB_FUNCTION
-
-static void free_func_with_service(struct usb_function *func)
-{
- struct usb_function_with_service *fws;
-
- fws = container_of(func, struct usb_function_with_service, func);
+ *clone = other;
+ return 0;
- free_simple_func_content(func);
- free((void *)fws->service);
- free(fws);
+out_nomem:
+ free_simple_func(other);
+ return -ENOMEM;
}
-static int clone_func_with_service(struct usb_function *func,
- struct usb_function **clone)
-{
- struct usb_function_with_service *fws;
- struct usb_function_with_service *other;
- int ret;
-
- if (!func || !clone)
- return -EINVAL;
-
- other = (struct usb_function_with_service *)malloc(sizeof(*other));
- if (!other)
- goto out;
+#define DEFINE_USB_FUNCTION(_group, _id, _name, _service) \
+ static struct usb_function _##_name##_function = { \
+ .function_group = _group, \
+ .id = _id, \
+ .name = #_name, \
+ .instance = "default", \
+ .service = _service, \
+ .clone = clone_simple_func, \
+ .free_func = free_simple_func, \
+ }
- ret = clone_simple_func_to(func, &other->func);
- if (ret)
- goto free_other;
+#define DEFINE_USB_FUNCTION_NO_SERVICE(_id, _name) \
+ DEFINE_USB_FUNCTION(USB_FUNCTION_GROUP_SIMPLE, _id, _name, NULL)
- fws = container_of(func, struct usb_function_with_service, func);
- if (fws->service) {
- other->service = strdup(fws->service);
- if (!other->service)
- goto free_content;
- } else {
- other->service = NULL;
- }
+#define DEFINE_USB_FUNCTION_WITH_SERVICE(_id, _name, _service) \
+ DEFINE_USB_FUNCTION(USB_FUNCTION_GROUP_WITH_SERVICE, _id, _name, _service)
- *clone = &other->func;
- return 0;
-free_content:
- free_simple_func_content(&other->func);
-free_other:
- free(other);
-out:
- return -ENOMEM;
-}
+#define DEFINE_USB_FUNCTION_WITH_POST_SERVICE(_id, _name, _service) \
+ DEFINE_USB_FUNCTION(USB_FUNCTION_GROUP_WITH_POST_SERVICE, _id, _name, _service)
-#define DEFINE_USB_FUNCTION_WITH_SERVICE(_id, _name, _service) \
- static struct usb_function_with_service _##_name##_function = { \
- .func = { \
- .function_group = USB_FUNCTION_GROUP_WITH_SERVICE, \
- .id = _id, \
- .name = #_name, \
- .instance = "default", \
- .clone = clone_func_with_service, \
- .free_func = free_func_with_service, \
- }, \
- .service = _service, \
- }
+DEFINE_USB_FUNCTION_NO_SERVICE(USB_FUNCTION_DIAG, diag);
+DEFINE_USB_FUNCTION_NO_SERVICE(USB_FUNCTION_RMNET, rmnet);
+DEFINE_USB_FUNCTION_NO_SERVICE(USB_FUNCTION_DM, dm);
+DEFINE_USB_FUNCTION_NO_SERVICE(USB_FUNCTION_CONN_GADGET, conn_gadget);
DEFINE_USB_FUNCTION_WITH_SERVICE(USB_FUNCTION_SDB, sdb, "sdbd");
DEFINE_USB_FUNCTION_WITH_SERVICE(USB_FUNCTION_MTP, mtp, "mtp-responder");
-#define DEFINE_USB_FUNCTION_WITH_POST_SERVICE(_id, _name, _service) \
- static struct usb_function_with_service _##_name##_function = { \
- .func = { \
- .function_group = USB_FUNCTION_GROUP_WITH_POST_SERVICE, \
- .id = _id, \
- .name = #_name, \
- .instance = "default", \
- .clone = clone_func_with_service, \
- .free_func = free_func_with_service, \
- }, \
- .service = _service, \
- }
-
DEFINE_USB_FUNCTION_WITH_POST_SERVICE(USB_FUNCTION_ACM, acm, "data-router");
DEFINE_USB_FUNCTION_WITH_POST_SERVICE(USB_FUNCTION_RNDIS, rndis, "rndis");
#define MAKE_FUNC_AVAILABLE(_name, _vname) \
[FUNC_IDX_FROM_MASK(USB_FUNCTION_##_name)] = &_##_vname##_function
-#define MAKE_FUNC_WS_AVAILABLE(_name, _vname) \
- [FUNC_IDX_FROM_MASK(USB_FUNCTION_##_name)] = &_##_vname##_function.func
-
static struct usb_function *_available_funcs[] = {
- MAKE_FUNC_WS_AVAILABLE(MTP, mtp),
- MAKE_FUNC_WS_AVAILABLE(ACM, acm),
- MAKE_FUNC_WS_AVAILABLE(SDB, sdb),
- MAKE_FUNC_WS_AVAILABLE(RNDIS, rndis),
+ MAKE_FUNC_AVAILABLE(MTP, mtp),
+ MAKE_FUNC_AVAILABLE(ACM, acm),
+ MAKE_FUNC_AVAILABLE(SDB, sdb),
+ MAKE_FUNC_AVAILABLE(RNDIS, rndis),
MAKE_FUNC_AVAILABLE(DIAG, diag),
MAKE_FUNC_AVAILABLE(CONN_GADGET, conn_gadget),
MAKE_FUNC_AVAILABLE(DM, dm),
MAKE_FUNC_AVAILABLE(RMNET, rmnet),
};
+#undef DEFINE_USB_FUNCTION
+#undef DEFINE_USB_FUNCTION_NO_SERVICE
+#undef DEFINE_USB_FUNCTION_WITH_SERVICE
+#undef DEFIND_USB_FUNCTION_WITH_POST_SERVICE
#undef MAKE_FUNC_AVAILABLE
struct usb_gadget_id {