diff options
author | Daniel Drake <dsd@gentoo.org> | 2008-11-02 21:45:54 +0000 |
---|---|---|
committer | Daniel Drake <dsd@gentoo.org> | 2008-11-02 21:45:54 +0000 |
commit | 914a4e70657c86b5094770aa2d898c978b1cdf41 (patch) | |
tree | f059245ca707731b8a3cc91dff92457185e2ef64 | |
parent | d25b566b3b8febafdda4211de724b4727dd4b7e0 (diff) | |
download | libusb-914a4e70657c86b5094770aa2d898c978b1cdf41.tar.gz |
Linux: handle low-level transfer errors
Handle more URB error status codes, thanks to Lou and Alan Stern.
-rw-r--r-- | libusb/os/linux_usbfs.c | 51 |
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; |