From 877b1ee82e4eb5d0fa56ff5eef310c75556c8762 Mon Sep 17 00:00:00 2001
From: Alex Elder <elder@linaro.org>
Date: Wed, 24 Sep 2014 05:16:13 -0500
Subject: [PATCH] greybus: encapsulate URB status checking

Define a new common function check_urb_status() that looks at the
status in a completed URB (containing incoming data) and issues
warnings in a consistent way.  It returns -EAGAIN to signal an
unrecognized status was seen, so the caller can ignore it and
re-post the URB to receive the next incoming data.  This
consolidates three blocks of code into one.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
---
 drivers/staging/greybus/es1-ap-usb.c | 79 +++++++++++-----------------
 1 file changed, 30 insertions(+), 49 deletions(-)

diff --git a/drivers/staging/greybus/es1-ap-usb.c b/drivers/staging/greybus/es1-ap-usb.c
index dfe96cb36a4e..7ce3a7743e58 100644
--- a/drivers/staging/greybus/es1-ap-usb.c
+++ b/drivers/staging/greybus/es1-ap-usb.c
@@ -227,17 +227,16 @@ static struct greybus_host_driver es1_driver = {
 	.submit_gbuf		= submit_gbuf,
 };
 
-/* Callback for when we get a SVC message */
-static void svc_callback(struct urb *urb)
+/* Common function to report consistent warnings based on URB status */
+static int check_urb_status(struct urb *urb)
 {
-	struct es1_ap_dev *es1 = urb->context;
 	struct device *dev = &urb->dev->dev;
 	int status = urb->status;
-	int retval;
 
 	switch (status) {
 	case 0:
-		break;
+		return 0;
+
 	case -EOVERFLOW:
 		dev_err(dev, "%s: overflow actual length is %d\n",
 			__func__, urb->actual_length);
@@ -246,11 +245,25 @@ static void svc_callback(struct urb *urb)
 	case -ESHUTDOWN:
 	case -EILSEQ:
 		/* device is gone, stop sending */
-		return;
-	default:
-		dev_err(dev, "%s: unknown status %d\n", __func__, status);
-		goto exit;
+		return status;
 	}
+	dev_err(dev, "%s: unknown status %d\n", __func__, status);
+
+	return -EAGAIN;
+}
+
+/* Callback for when we get a SVC message */
+static void svc_in_callback(struct urb *urb)
+{
+	struct es1_ap_dev *es1 = urb->context;
+	struct device *dev = &urb->dev->dev;
+	int status = check_urb_status(urb);
+	int retval;
+
+	if (status == -EAGAIN)
+		goto exit;
+	if (status)
+		return;
 
 	/* We have a message, create a new message structure, add it to the
 	 * list, and wake up our thread that will process the messages.
@@ -268,27 +281,15 @@ static void cport_in_callback(struct urb *urb)
 {
 	struct device *dev = &urb->dev->dev;
 	struct es1_ap_dev *es1 = urb->context;
-	int status = urb->status;
+	int status = check_urb_status(urb);
 	int retval;
 	u8 cport;
 	u8 *data;
 
-	switch (status) {
-	case 0:
-		break;
-	case -EOVERFLOW:
-		dev_err(dev, "%s: overflow actual length is %d\n",
-			__func__, urb->actual_length);
-	case -ECONNRESET:
-	case -ENOENT:
-	case -ESHUTDOWN:
-	case -EILSEQ:
-		/* device is gone, stop sending */
-		return;
-	default:
-		dev_err(dev, "%s: unknown status %d\n", __func__, status);
+	if (status == -EAGAIN)
 		goto exit;
-	}
+	if (status)
+		return;
 
 	/* The size has to be more then just an "empty" transfer */
 	if (urb->actual_length <= 2) {
@@ -318,35 +319,15 @@ static void cport_in_callback(struct urb *urb)
 
 static void cport_out_callback(struct urb *urb)
 {
-	struct device *dev = &urb->dev->dev;
 	struct gbuf *gbuf = urb->context;
 	struct es1_ap_dev *es1 = gbuf->hdpriv;
 	unsigned long flags;
-	int status = urb->status;
 	int i;
 
-	/* do we care about errors going back up? */
-	switch (status) {
-	case 0:
-		break;
-	case -EOVERFLOW:
-		dev_err(dev, "%s: overflow actual length is %d\n",
-			__func__, urb->actual_length);
-	case -ECONNRESET:
-	case -ENOENT:
-	case -ESHUTDOWN:
-	case -EILSEQ:
-		/* device is gone, stop sending */
-		goto exit;
-	default:
-		dev_err(dev, "%s: unknown status %d\n", __func__, status);
-		goto exit;
-	}
-
-	/* Tell the core the gbuf is properly sent */
-	greybus_gbuf_finished(gbuf);
+	/* If no error, tell the core the gbuf is properly sent */
+	if (!check_urb_status(urb))
+		greybus_gbuf_finished(gbuf);
 
-exit:
 	/*
 	 * See if this was an urb in our pool, if so mark it "free", otherwise
 	 * we need to free it ourselves.
@@ -443,7 +424,7 @@ static int ap_probe(struct usb_interface *interface,
 
 	usb_fill_int_urb(es1->svc_urb, udev,
 			 usb_rcvintpipe(udev, es1->svc_endpoint),
-			 es1->svc_buffer, ES1_SVC_MSG_SIZE, svc_callback,
+			 es1->svc_buffer, ES1_SVC_MSG_SIZE, svc_in_callback,
 			 es1, svc_interval);
 	retval = usb_submit_urb(es1->svc_urb, GFP_KERNEL);
 	if (retval)
-- 
2.30.9