summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-03-09 11:31:08 +0100
committerPeter Stuge <peter@stuge.se>2012-04-19 06:51:01 +0200
commit7199bc2c9c351b553b6175a588237ee793719281 (patch)
tree75a8b9ae920501bafeb7c9a553662b7e8e205e98
parent98bc7b8d125c2756deadfc889dcefd4e6f2fcd02 (diff)
downloadlibusb-7199bc2c9c351b553b6175a588237ee793719281.tar.gz
Linux: Fix URB return code handling
During testing of my usbredir code I hit a case where EOVERFLOW was not handled in handle_control_completion(). Instead of just fixing this one case I've audited (and fixed where necessary) all handle_foo_completion() functions to know about all errors documented in linux/Documentation/usb/error-codes.txt. Note that for handle_iso_completion() this patch actually removes the handling of some codes, since these can never occur on an iso urb (they can only occur on the iso packets included in the urb, see the next patch in this series). Also, in case an unknown status is encountered on an iso urb this patch sets the urb's status to ERROR rather then leaving it at completed. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r--libusb/os/linux_usbfs.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index 1cc2aae..0bd8742 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -1978,6 +1978,7 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer,
case -ENOENT: /* cancelled */
case -ECONNRESET:
break;
+ case -ENODEV:
case -ESHUTDOWN:
usbi_dbg("device removed");
tpriv->reap_status = LIBUSB_TRANSFER_NO_DEVICE;
@@ -1996,6 +1997,8 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer,
case -ETIME:
case -EPROTO:
case -EILSEQ:
+ case -ECOMM:
+ case -ENOSR:
usbi_dbg("low level error %d", urb->status);
tpriv->reap_action = ERROR;
goto cancel_remaining;
@@ -2107,19 +2110,16 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
case 0:
break;
case -ENOENT: /* cancelled */
+ case -ECONNRESET:
break;
case -ESHUTDOWN:
usbi_dbg("device removed");
status = LIBUSB_TRANSFER_NO_DEVICE;
break;
- case -ETIME:
- case -EPROTO:
- case -EILSEQ:
- usbi_dbg("low-level USB error %d", urb->status);
- break;
default:
usbi_warn(TRANSFER_CTX(transfer),
"unrecognised urb status %d", urb->status);
+ status = LIBUSB_TRANSFER_ERROR;
break;
}
@@ -2165,6 +2165,7 @@ static int handle_control_completion(struct usbi_transfer *itransfer,
case -ENOENT: /* cancelled */
status = LIBUSB_TRANSFER_CANCELLED;
break;
+ case -ENODEV:
case -ESHUTDOWN:
usbi_dbg("device removed");
status = LIBUSB_TRANSFER_NO_DEVICE;
@@ -2173,9 +2174,15 @@ static int handle_control_completion(struct usbi_transfer *itransfer,
usbi_dbg("unsupported control request");
status = LIBUSB_TRANSFER_STALL;
break;
+ case -EOVERFLOW:
+ usbi_dbg("control overflow error");
+ status = LIBUSB_TRANSFER_OVERFLOW;
+ break;
case -ETIME:
case -EPROTO:
case -EILSEQ:
+ case -ECOMM:
+ case -ENOSR:
usbi_dbg("low-level bus error occurred");
status = LIBUSB_TRANSFER_ERROR;
break;