From f7f3dfda5967198b2219450a907047c4e6e8a692 Mon Sep 17 00:00:00 2001 From: Vijayavardhan Vennapusa Date: Mon, 30 Oct 2017 14:33:51 +0530 Subject: [PATCH] USB: configfs: Don't send DISCONNECT uevent during unbind while testing composition switch from UI, composite driver sending disconnect event to userspace from function unbind path or from the bus reset. As per the none composition rules in init.msm.usb.configfs.rc unbind should happen first and sending the disconnect event to userspace. Userspace code will starts 1 sec timer for enumeration. In some cases where adbd is enabled, adbd taking more than 1sec to restart and causing delay in next composition enumeration. Another case is in RNDIS composition switch. Where rndis function is taking more time in unbind path and causing delay for next composition switch. This results in userpsace timeout (1 second) causing actual composition enumeration failure and falls back to default composition. Workaround the issue by not sending disconnect event to userspace on composition switch from unbind path. Instead send the disconnect event from USB bus reset so that userspace enable timer starts from bus reset. Change-Id: I2d1fcaa0704e369204fbba4eceb8ba9b1c525b41 Signed-off-by: Vijayavardhan Vennapusa Signed-off-by: Mayank Rana Signed-off-by: Pratham Pratap --- drivers/usb/gadget/configfs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 6709a66db61f..ca93bb65edc4 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -85,6 +85,7 @@ struct gadget_info { struct usb_composite_driver composite; struct usb_composite_dev cdev; bool use_os_desc; + bool unbinding; char b_vendor_code; char qw_sign[OS_STRING_QW_SIGN_LEN]; spinlock_t spinlock; @@ -277,9 +278,12 @@ static int unregister_gadget(struct gadget_info *gi) if (!gi->composite.gadget_driver.udc_name) return -ENODEV; + gi->unbinding = true; ret = usb_gadget_unregister_driver(&gi->composite.gadget_driver); if (ret) return ret; + + gi->unbinding = false; kfree(gi->composite.gadget_driver.udc_name); gi->composite.gadget_driver.udc_name = NULL; return 0; @@ -1629,7 +1633,8 @@ static void android_disconnect(struct usb_gadget *gadget) acc_disconnect(); #endif gi->connected = 0; - schedule_work(&gi->work); + if (!gi->unbinding) + schedule_work(&gi->work); composite_disconnect(gadget); }