From: INSUN PYO Date: Thu, 12 Mar 2020 07:29:19 +0000 (+0900) Subject: Remove unused usb functions after changing usb mode X-Git-Tag: submit/tizen/20200402.112144~17 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F99%2F227499%2F7;p=platform%2Fcore%2Fsystem%2Flibdevice-node.git Remove unused usb functions after changing usb mode After setting the new usb mode, the configfs functions that was not used remain. For example, changing from rndis mode to sdb mode, /sys/kernel/config/usb_gadget/hal-gadget/rndis.default remains. A functionfs has to do a few extra things. - The socket and service associated with functionfs must be terminated. - Umount /dev/usb-funcs/[sdb|mtp]/default - Delete /dev/usb-funcs/[sdb|mtp]/default recursively Change-Id: I2d66f033babd5bea20cfc74d8bf23eb9a89c3be1 --- diff --git a/hw/usb_cfs_client_common.c b/hw/usb_cfs_client_common.c index 66ca48b..10bed2a 100644 --- a/hw/usb_cfs_client_common.c +++ b/hw/usb_cfs_client_common.c @@ -659,6 +659,64 @@ umount_ffs: return ret; } +static int cfs_cleanup_ffs_service(usbg_function *function) +{ + int ret; + int index; + const char *name; + const char *instance; + char buf[MAX_INSTANCE_LEN]; + struct usb_function *usb_function; + + if (!function) + return -EINVAL; + + instance = usbg_get_function_instance(function); /* Ex: sdb.default */ + name = usbg_get_function_type_str(usbg_get_function_type(function)); /* Fixed: ffs */ + + index = cfs_find_func(name, instance); + if (index < 0) + return index; + + usb_function = _available_funcs[index]; + + /* stop .socket first and stop .service later becuase of socket activation */ + if (usb_function->service) { + (void)systemd_stop_unit_wait_stopped(usb_function->service, ".socket", -1); + (void)systemd_stop_unit_wait_stopped(usb_function->service, ".service", -1); + } + + /* umount /dev/usb-funcs/[sdb|mtp]/default and remove it's directory */ + ret = snprintf(buf, sizeof(buf), "%s%s/%s", USB_FUNCS_PATH, usb_function->name, usb_function->instance); + if (ret < 0) + return ret; + + ret = umount(buf); + if (ret < 0) + return ret; + + ret = rmdir(buf); + if (ret < 0) + return ret; + + /* remove /dev/usb-funcs/[sdb|mtp] directory */ + ret = snprintf(buf, sizeof(buf), "%s%s", USB_FUNCS_PATH, usb_function->name); + if (ret < 0) + return ret; + + ret = rmdir(buf); + if (ret < 0 && errno != ENOTEMPTY) + return ret; + + /* remove /dev/usb-funcs/ directory */ + ret = rmdir(USB_FUNCS_PATH); + if (ret < 0 && errno != ENOTEMPTY) + return ret; + + return 0; +} + + static int cfs_set_rndis_mac_addr(usbg_gadget *gadget, usbg_function *func) { int i, ret; @@ -796,6 +854,50 @@ static int cfs_cleanup_left_configs(struct cfs_client *cfs_client, return 0; } +static int cfs_function_is_binded(struct usbg_gadget *gadget, struct usbg_function *func) +{ + usbg_binding *b; + usbg_config *config; + + usbg_for_each_config(config, gadget) + usbg_for_each_binding(b, config) + if (usbg_get_binding_target(b) == func) + return 1; + + return 0; +} + +static int cfs_cleanup_unused_function(usbg_gadget *gadget) +{ + int ret; + usbg_function *function; + + if (!gadget) + return -EINVAL; + +restart: + usbg_for_each_function(function, gadget) { + if(cfs_function_is_binded(gadget, function)) + continue; + + if (usbg_get_function_type(function) == USBG_F_FFS) { + ret = cfs_cleanup_ffs_service(function); + if (ret) + return ret; + } + + ret = usbg_rm_function(function, USBG_RM_RECURSE); + if (ret) + return ret; + + /* You cannot delete a usbg_function directly in an iterator. */ + goto restart; + } + + return 0; +} + + static int cfs_reconfigure_gadget(struct usb_client *usb, struct usb_gadget *gadget) { @@ -827,10 +929,12 @@ static int cfs_reconfigure_gadget(struct usb_client *usb, } ret = cfs_cleanup_left_configs(cfs_client, i); + if(ret) + goto out; + + /* Cleanup things which are left after previous gadget */ + ret = cfs_cleanup_unused_function(cfs_client->gadget); - /* TODO - * Cleanup things which are left after previous gadget - */ out: return ret; }