bool res;
int ret;
- if (!func->ffs_service) {
+ if (!func->is_functionfs) {
ret = usbg_lookup_function_type(func->name);
res = ret >= 0;
} else {
int type;
usbg_function *func;
- if (!usb_func->ffs_service) {
+ if (!usb_func->is_functionfs) {
type = usbg_lookup_function_type(usb_func->name);
if (strlen(usb_func->instance) >= MAX_INSTANCE_LEN)
return -ENAMETOOLONG;
if (usbg_get_function_type(func) == USBG_F_RNDIS)
(void)cfs_set_rndis_mac_addr(cfs_client->gadget, func); /* A random value is used if fails */
- if (usb_func->ffs_service) {
+ if (usb_func->is_functionfs) {
ret = cfs_prep_ffs_service(usb_func->name,
usb_func->instance,
instance,
- usb_func->ffs_service);
+ usb_func->service);
if (ret)
return ret;
}
goto out;
}
- /* Workaround for enabling extcon notification */
- /* ******************************************* */
- /* ******************************************* */
- {
- const char *ARTIK_UDC_NAME = "c0040000.dwc2otg";
- const char *udc_name = usbg_get_udc_name(cfs_client->udc);
- if (udc_name && !strncmp(udc_name, ARTIK_UDC_NAME, strlen(ARTIK_UDC_NAME))) {
- ret = usbg_enable_gadget(cfs_client->gadget, cfs_client->udc);
- if (ret)
- goto out;
- }
- }
- /* ******************************************* */
- /* ******************************************* */
- /* ******************************************* */
-
ret = cfs_cleanup_left_configs(cfs_client, i);
/* TODO
if (func->handler)
func->handler(1);
- if (func->service)
+ /* functionfs service is automatically started by socket activation */
+ if (!func->is_functionfs && func->service)
(void)systemd_start_unit_wait_started(func->service, ".service", -1);
}
for (i = 0; gadget->funcs[i]; ++i) {
func = gadget->funcs[i];
- if (func->service)
+ if (!func->is_functionfs && func->service)
(void)systemd_stop_unit_wait_stopped(func->service, ".service", -1);
if (func->handler)
func->handler(0);
}
+ cfs_client = container_of(usb, struct cfs_client, client);
+ ret = usbg_disable_gadget(cfs_client->gadget); /* ignore error checking */
+
+ /*
+ * Since functionfs service works with socket activation, you must stop it after disabling gadget.
+ * If usb data may come in after stopping functionfs service and before disabling gadget,
+ * functionfs service wakes up again by socket activation.
+ */
+ for (i = 0; gadget->funcs[i]; ++i) {
+ func = gadget->funcs[i];
+
+ if (func->is_functionfs && func->service)
+ (void)systemd_stop_unit_wait_stopped(func->service, ".service", -1);
+ }
+
cfs_free_gadget(gadget);
- cfs_client = container_of(usb, struct cfs_client, client);
- return usbg_disable_gadget(cfs_client->gadget);
+ return ret;
}
EXPORT
continue;
usb_func = _available_funcs[ret];
- if (usb_func->ffs_service) {
- systemd_stop_unit_wait_stopped(usb_func->ffs_service, ".socket", -1);
- systemd_stop_unit_wait_stopped(usb_func->ffs_service, ".service", -1);
+
+ if (usb_func->is_functionfs && usb_func->service) {
+ (void)systemd_stop_unit_wait_stopped(usb_func->service, ".socket", -1);
+ (void)systemd_stop_unit_wait_stopped(usb_func->service, ".service", -1);
}
}