usb: diag_bridge: call bridge callbacks even for -EPROTO.

The diagfwd_hsic driver acts as a client of the bridge and must
have its read/write callbacks called so it can properly free its
memory buffers. In the case of the HSIC device being disconnected,
the URB status is -EPROTO but the callback was withheld, which
led to lost buffers when the HSIC device is disconnected. Fix this
by always calling the callbacks, while continuing to treat -EPROTO
as a special case by returning -ENODEV on subsequent reads and
writes. Also fix a major but tiny gotcha in diagfwd's read function
in which the 'err' variable is additionally declared and used in a
local scope but is read outside it.

CRs-fixed: 394401
Signed-off-by: Jack Pham <jackp@codeaurora.org>

Conflicts:

	drivers/usb/misc/diag_bridge.c

Change-Id: Ic40e43555ba557ac0caf3abfd3b8e372eb522003
Signed-off-by: Neha Pandey <nehap@codeaurora.org>
diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c
index 38e7786..c4dc695 100644
--- a/drivers/usb/misc/diag_bridge.c
+++ b/drivers/usb/misc/diag_bridge.c
@@ -98,20 +98,16 @@
 	dev_dbg(&dev->ifc->dev, "%s: status:%d actual:%d\n", __func__,
 			urb->status, urb->actual_length);
 
+        /* save error so that subsequent read/write returns ENODEV */
+        if (urb->status == -EPROTO)
+     	dev->err = urb->status;
+
 	if (cbs && cbs->read_complete_cb)
 		cbs->read_complete_cb(cbs->ctxt,
 			urb->transfer_buffer,
 			urb->transfer_buffer_length,
 			urb->status < 0 ? urb->status : urb->actual_length);
 
-	if (urb->status == -EPROTO) {
-		dev_err(&dev->ifc->dev, "%s: proto error\n", __func__);
-		/* save error so that subsequent read/write returns ENODEV */
-		dev->err = urb->status;
-		kref_put(&dev->kref, diag_bridge_delete);
-		return;
-	}
-
 	dev->bytes_to_host += urb->actual_length;
 	dev->pending_reads--;
 	kref_put(&dev->kref, diag_bridge_delete);
@@ -204,13 +200,9 @@
 
 	usb_autopm_put_interface_async(dev->ifc);
 
-	if (urb->status == -EPROTO) {
-		dev_err(&dev->ifc->dev, "%s: proto error\n", __func__);
-		/* save error so that subsequent read/write returns ENODEV */
+	/* save error so that subsequent read/write returns ENODEV */
+	if (urb->status == -EPROTO)
 		dev->err = urb->status;
-		kref_put(&dev->kref, diag_bridge_delete);
-		return;
-	}
 
 	if (cbs && cbs->write_complete_cb)
 		cbs->write_complete_cb(cbs->ctxt,