usb: gsmd: Free usb ep req if req staus is cable disconnection

USB ep request is being added to the list and being freed later
w/o deleting from the list when usb cable is disonnected. This
is causing memory corruption and kernel panic in other function
drivers. Fix the issue by not adding the request to list during
cable disconnection

CRs-Fixed: 301905
Signed-off-by: Vamsi Krishna <vskrishn@codeaurora.org>
diff --git a/drivers/usb/gadget/u_smd.c b/drivers/usb/gadget/u_smd.c
index bdcbdd7..c4a5ce4 100644
--- a/drivers/usb/gadget/u_smd.c
+++ b/drivers/usb/gadget/u_smd.c
@@ -363,9 +363,10 @@
 	}
 
 	spin_lock(&port->port_lock);
-	if (!test_bit(CH_OPENED, &port->pi->flags)) {
-		gsmd_free_req(ep, req);
+	if (!test_bit(CH_OPENED, &port->pi->flags) ||
+			req->status == -ESHUTDOWN) {
 		spin_unlock(&port->port_lock);
+		gsmd_free_req(ep, req);
 		return;
 	}
 
@@ -388,30 +389,20 @@
 	}
 
 	spin_lock(&port->port_lock);
-	if (!test_bit(CH_OPENED, &port->pi->flags)) {
-		gsmd_free_req(ep, req);
+	if (!test_bit(CH_OPENED, &port->pi->flags) ||
+			req->status == -ESHUTDOWN) {
 		spin_unlock(&port->port_lock);
+		gsmd_free_req(ep, req);
 		return;
 	}
 
-	list_add(&req->list, &port->write_pool);
-
-	switch (req->status) {
-	default:
+	if (req->status)
 		pr_warning("%s: port:%p port#%d unexpected %s status %d\n",
 				__func__, port, port->port_num,
 				ep->name, req->status);
-		/* FALL THROUGH */
-	case 0:
-		queue_work(gsmd_wq, &port->pull);
-		break;
 
-	case -ESHUTDOWN:
-		/* disconnect */
-		pr_debug("%s: %s shutdown\n", __func__, ep->name);
-		gsmd_free_req(ep, req);
-		break;
-	}
+	list_add(&req->list, &port->write_pool);
+	queue_work(gsmd_wq, &port->pull);
 	spin_unlock(&port->port_lock);
 
 	return;
@@ -848,11 +839,15 @@
 				"cbits_to_modem:  %u\n"
 				"cbits_to_laptop: %u\n"
 				"n_read: %u\n"
+				"smd_read_avail: %d\n"
+				"smd_write_avail: %d\n"
 				"CH_OPENED: %d\n"
 				"CH_READY: %d\n",
 				i, port->nbytes_tolaptop, port->nbytes_tomodem,
 				port->cbits_to_modem, port->cbits_to_laptop,
 				port->n_read,
+				smd_read_avail(port->pi->ch),
+				smd_write_avail(port->pi->ch),
 				test_bit(CH_OPENED, &port->pi->flags),
 				test_bit(CH_READY, &port->pi->flags));
 		spin_unlock_irqrestore(&port->port_lock, flags);