From d250b6bf0e02a9c40298d080b00fb650b644de26 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 6 Jun 2017 14:47:29 +0300 Subject: [PATCH] BACKPORT: usb: gadget: composite: make sure to reactivate function on unbind If a function sets bind_deactivated flag, upon removal we will be left with an unbalanced deactivation. Let's make sure that we conditionally call usb_function_activate() from usb_remove_function() and make sure usb_remove_function() is called from remove_config(). Change-Id: I4d7a70560961da90561a7999ac4e58a294c1a0cf Signed-off-by: Felipe Balbi Signed-off-by: William Wu (cherry picked from commit 0e3e97526a850f97c9fe8b646937b3a2bef58290) --- drivers/usb/gadget/composite.c | 11 +++++------ drivers/usb/gadget/configfs.c | 3 +++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 49b8adbf7ace..3b2863a697a4 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -263,6 +263,9 @@ void usb_remove_function(struct usb_configuration *c, struct usb_function *f) list_del(&f->list); if (f->unbind) f->unbind(c, f); + + if (f->bind_deactivated) + usb_function_activate(f); } EXPORT_SYMBOL_GPL(usb_remove_function); @@ -866,12 +869,8 @@ static void remove_config(struct usb_composite_dev *cdev, f = list_first_entry(&config->functions, struct usb_function, list); - list_del(&f->list); - if (f->unbind) { - DBG(cdev, "unbind function '%s'/%p\n", f->name, f); - f->unbind(config, f); - /* may free memory for "f" */ - } + + usb_remove_function(config, f); } list_del(&config->list); if (config->unbind) { diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index f58afe5b92ad..567be635a458 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1255,6 +1255,9 @@ static void purge_configs_funcs(struct gadget_info *gi) " '%s'/%p\n", f->name, f); f->unbind(c, f); } + + if (f->bind_deactivated) + usb_function_activate(f); } c->next_interface_id = 0; memset(c->interface, 0, sizeof(c->interface));