summaryrefslogtreecommitdiff
path: root/libusb/os/linux_usbfs.c
diff options
context:
space:
mode:
authorDaniel Drake <dsd@gentoo.org>2008-11-02 21:45:54 +0000
committerDaniel Drake <dsd@gentoo.org>2008-11-02 21:45:54 +0000
commit914a4e70657c86b5094770aa2d898c978b1cdf41 (patch)
treef059245ca707731b8a3cc91dff92457185e2ef64 /libusb/os/linux_usbfs.c
parentd25b566b3b8febafdda4211de724b4727dd4b7e0 (diff)
downloadlibusb-914a4e70657c86b5094770aa2d898c978b1cdf41.tar.gz
Linux: handle low-level transfer errors
Handle more URB error status codes, thanks to Lou and Alan Stern.
Diffstat (limited to 'libusb/os/linux_usbfs.c')
-rw-r--r--libusb/os/linux_usbfs.c51
1 files changed, 40 insertions, 11 deletions
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index 66d5518..d690511 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -1716,18 +1716,29 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer,
return 0;
}
- if (urb->status == -EPIPE) {
+ switch (urb->status) {
+ case 0:
+ break;
+ case -EPIPE:
usbi_dbg("detected endpoint stall");
status = LIBUSB_TRANSFER_STALL;
goto out;
- } else if (urb->status == -EOVERFLOW) {
+ case -EOVERFLOW:
/* overflow can only ever occur in the last urb */
usbi_dbg("overflow, actual_length=%d", urb->actual_length);
status = LIBUSB_TRANSFER_OVERFLOW;
goto out;
- } else if (urb->status != 0) {
+ case -ETIME:
+ case -EPROTO:
+ case -EILSEQ:
+ usbi_dbg("low level error %d", urb->status);
+ status = LIBUSB_TRANSFER_ERROR;
+ goto out;
+ default:
usbi_warn(ITRANSFER_CTX(itransfer),
"unrecognised urb status %d", urb->status);
+ status = LIBUSB_TRANSFER_ERROR;
+ goto out;
}
/* if we're the last urb or we got less data than requested then we're
@@ -1836,9 +1847,19 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
return 0;
}
- if (urb->status != 0)
+ switch (urb->status) {
+ case 0:
+ 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);
+ break;
+ }
/* if we're the last urb or we got less data than requested then we're
* done */
@@ -1871,20 +1892,28 @@ static int handle_control_completion(struct usbi_transfer *itransfer,
return 0;
}
- if (urb->status == -EPIPE) {
+ switch (urb->status) {
+ case 0:
+ itransfer->transferred = urb->actual_length;
+ status = LIBUSB_TRANSFER_COMPLETED;
+ break;
+ case -EPIPE:
usbi_dbg("unsupported control request");
status = LIBUSB_TRANSFER_STALL;
- goto out;
- } else if (urb->status != 0) {
+ break;
+ case -ETIME:
+ case -EPROTO:
+ case -EILSEQ:
+ usbi_dbg("low-level bus error occurred");
+ status = LIBUSB_TRANSFER_ERROR;
+ break;
+ default:
usbi_warn(ITRANSFER_CTX(itransfer),
"unrecognised urb status %d", urb->status);
status = LIBUSB_TRANSFER_ERROR;
- goto out;
+ break;
}
- itransfer->transferred = urb->actual_length;
- status = LIBUSB_TRANSFER_COMPLETED;
-out:
free(tpriv->urbs);
usbi_handle_transfer_completion(itransfer, status);
return 0;