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>
This commit is contained in:
Alex Elder 2014-09-24 05:16:13 -05:00 коммит произвёл Greg Kroah-Hartman
Родитель c41a366773
Коммит 877b1ee82e
1 изменённых файлов: 30 добавлений и 49 удалений

Просмотреть файл

@ -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 @@ exit:
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 */
/* 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)