USB: gadget: diag: cleanup connect event processing
USB connect event is notified to DIAG in process context. The
process context is achieved by scheduling a work in connect
interrupt. But the disconnect event is notified from disconnect
interrupt context. This is leading to synchronization problems
during fast cable connect and disconnect scenarios.
Notify the connect event from interrupt context. Updating
product and serial number for every cable connect is redundant.
Move this to bind time and remove config work completely.
CRs-Fixed: 475955
Change-Id: I9d6685f64e0348a63dd88ea36297198ca1fd4596
Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index a2ee182..3ba5916 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -96,9 +96,6 @@
* @out_desc: USB OUT endpoint descriptor struct
* @read_pool: List of requests used for Rx (OUT ep)
* @write_pool: List of requests used for Tx (IN ep)
- * @config_work: Work item schedule after interface is configured to notify
- * CONNECT event to diag char driver and updating product id
- * and serial number to MODEM/IMEM.
* @lock: Spinlock to proctect read_pool, write_pool lists
* @cdev: USB composite device struct
* @ch: USB diag channel
@@ -110,7 +107,6 @@
struct usb_ep *in;
struct list_head read_pool;
struct list_head write_pool;
- struct work_struct config_work;
spinlock_t lock;
unsigned configured;
struct usb_composite_dev *cdev;
@@ -128,17 +124,12 @@
return container_of(f, struct diag_context, function);
}
-static void usb_config_work_func(struct work_struct *work)
+static void diag_update_pid_and_serial_num(struct diag_context *ctxt)
{
- struct diag_context *ctxt = container_of(work,
- struct diag_context, config_work);
struct usb_composite_dev *cdev = ctxt->cdev;
struct usb_gadget_strings *table;
struct usb_string *s;
- if (ctxt->ch.notify)
- ctxt->ch.notify(ctxt->ch.priv, USB_DIAG_CONNECT, NULL);
-
if (!ctxt->update_pid_and_serial_num)
return;
@@ -553,7 +544,6 @@
usb_ep_disable(dev->in);
return rc;
}
- schedule_work(&dev->config_work);
dev->dpkts_tolaptop = 0;
dev->dpkts_tomodem = 0;
@@ -563,6 +553,9 @@
dev->configured = 1;
spin_unlock_irqrestore(&dev->lock, flags);
+ if (dev->ch.notify)
+ dev->ch.notify(dev->ch.priv, USB_DIAG_CONNECT, NULL);
+
return rc;
}
@@ -614,6 +607,7 @@
/* copy descriptors, and track endpoint copies */
f->hs_descriptors = usb_copy_descriptors(hs_diag_desc);
}
+ diag_update_pid_and_serial_num(ctxt);
return 0;
fail:
if (ctxt->out)
@@ -660,7 +654,6 @@
spin_lock_init(&dev->lock);
INIT_LIST_HEAD(&dev->read_pool);
INIT_LIST_HEAD(&dev->write_pool);
- INIT_WORK(&dev->config_work, usb_config_work_func);
ret = usb_add_function(c, &dev->function);
if (ret) {