This is a note to let you know that I've just added the patch titled usb: gadget: udc-core: Rescan pending list on driver unbind to the 4.10-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: usb-gadget-udc-core-rescan-pending-list-on-driver-unbind.patch and it can be found in the queue-4.10 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 8236800da115a3e24b9165c573067343f51cf5ea Mon Sep 17 00:00:00 2001 From: Krzysztof Opasiak <k.opasiak@xxxxxxxxxxx> Date: Mon, 16 Jan 2017 08:40:57 +0100 Subject: usb: gadget: udc-core: Rescan pending list on driver unbind From: Krzysztof Opasiak <k.opasiak@xxxxxxxxxxx> commit 8236800da115a3e24b9165c573067343f51cf5ea upstream. Since: commit 855ed04a3758 ("usb: gadget: udc-core: independent registration of gadgets and gadget drivers") if we load gadget module but there is no free udc available then it will be stored on a pending gadgets list. $ modprobe g_zero.ko $ modprobe g_ether.ko [] udc-core: couldn't find an available UDC - added [g_ether] to list of pending drivers We scan this list each time when new UDC appears in system. But we can get a free UDC each time after gadget unbind. This commit add scanning of that list directly after unbinding gadget from udc. Thanks to this, when we unload first gadget: $ rmmod g_zero.ko gadget which is pending is automatically attached to that UDC (if name matches). Fixes: 855ed04a3758 ("usb: gadget: udc-core: independent registration of gadgets and gadget drivers") Signed-off-by: Krzysztof Opasiak <k.opasiak@xxxxxxxxxxx> Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/usb/gadget/udc/core.c | 45 ++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1080,6 +1080,24 @@ static void usb_udc_nop_release(struct d dev_vdbg(dev, "%s\n", __func__); } +/* should be called with udc_lock held */ +static int check_pending_gadget_drivers(struct usb_udc *udc) +{ + struct usb_gadget_driver *driver; + int ret = 0; + + list_for_each_entry(driver, &gadget_driver_pending_list, pending) + if (!driver->udc_name || strcmp(driver->udc_name, + dev_name(&udc->dev)) == 0) { + ret = udc_bind_to_driver(udc, driver); + if (ret != -EPROBE_DEFER) + list_del(&driver->pending); + break; + } + + return ret; +} + /** * usb_add_gadget_udc_release - adds a new gadget to the udc class driver list * @parent: the parent device to this udc. Usually the controller driver's @@ -1093,7 +1111,6 @@ int usb_add_gadget_udc_release(struct de void (*release)(struct device *dev)) { struct usb_udc *udc; - struct usb_gadget_driver *driver; int ret = -ENOMEM; udc = kzalloc(sizeof(*udc), GFP_KERNEL); @@ -1136,17 +1153,9 @@ int usb_add_gadget_udc_release(struct de udc->vbus = true; /* pick up one of pending gadget drivers */ - list_for_each_entry(driver, &gadget_driver_pending_list, pending) { - if (!driver->udc_name || strcmp(driver->udc_name, - dev_name(&udc->dev)) == 0) { - ret = udc_bind_to_driver(udc, driver); - if (ret != -EPROBE_DEFER) - list_del(&driver->pending); - if (ret) - goto err5; - break; - } - } + ret = check_pending_gadget_drivers(udc); + if (ret) + goto err5; mutex_unlock(&udc_lock); @@ -1356,14 +1365,22 @@ int usb_gadget_unregister_driver(struct return -EINVAL; mutex_lock(&udc_lock); - list_for_each_entry(udc, &udc_list, list) + list_for_each_entry(udc, &udc_list, list) { if (udc->driver == driver) { usb_gadget_remove_driver(udc); usb_gadget_set_state(udc->gadget, - USB_STATE_NOTATTACHED); + USB_STATE_NOTATTACHED); + + /* Maybe there is someone waiting for this UDC? */ + check_pending_gadget_drivers(udc); + /* + * For now we ignore bind errors as probably it's + * not a valid reason to fail other's gadget unbind + */ ret = 0; break; } + } if (ret) { list_del(&driver->pending); Patches currently in stable-queue which might be from k.opasiak@xxxxxxxxxxx are queue-4.10/usb-gadget-f_hid-fix-move-in-request-allocation-to-set_alt.patch queue-4.10/usb-gadget-f_hid-use-spinlock-instead-of-mutex.patch queue-4.10/usb-gadget-f_hid-fix-free-out-requests.patch queue-4.10/usb-gadget-f_hid-fix-prevent-accessing-released-memory.patch queue-4.10/usb-gadget-udc-core-rescan-pending-list-on-driver-unbind.patch