diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2010-10-05 11:08:40 -0400 |
---|---|---|
committer | Peter Stuge <peter@stuge.se> | 2010-11-26 20:47:24 +0100 |
commit | efc29733ad31f81883a7ac51a6cc6cda9ad4feb9 (patch) | |
tree | c63e8254ee4e3c3a34965f109a83cf700adf4a28 | |
parent | bd267cf92269e0c4cd8eef795b91eefb2c63452e (diff) | |
download | libusb-efc29733ad31f81883a7ac51a6cc6cda9ad4feb9.tar.gz |
Linux: improve detection of BULK_CONTINUATION kernel support
Clarify the comments describing the BULK_CONTINATION flag, and improve
the subroutine that checks whether the flag is supported by making it
"future-proof", i.e., by working properly with kernel version numbers
higher than 2.6.
-rw-r--r-- | libusb/os/linux_usbfs.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index 5c2a6e8..bf5d634 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -74,18 +74,18 @@ static const char *usbfs_path = NULL; /* Linux 2.6.32 adds support for a bulk continuation URB flag. this basically * allows us to mark URBs as being part of a specific logical transfer when - * we submit them to the kernel. then, on any error error except a - * cancellation, all URBs within that transfer will be cancelled with the - * endpoint is disabled, meaning that no more data can creep in during the - * time it takes to cancel the remaining URBs. + * we submit them to the kernel. then, on any error except a cancellation, all + * URBs within that transfer will be cancelled and no more URBs will be + * accepted for the transfer, meaning that no more data can creep in. * * The BULK_CONTINUATION flag must be set on all URBs within a bulk transfer * (in either direction) except the first. - * For IN transfers, we must also set SHORT_NOT_OK on all the URBs. - * For OUT transfers, SHORT_NOT_OK must not be set. The effective behaviour - * (where an OUT transfer does not complete, the rest of the URBs in the - * transfer get cancelled) is already in effect, and setting this flag is - * disallowed (a kernel with USB debugging enabled will reject such URBs). + * For IN transfers, we must also set SHORT_NOT_OK on all URBs except the + * last; it means that the kernel should treat a short reply as an error. + * For OUT transfers, SHORT_NOT_OK must not be set. it isn't needed (OUT + * transfers can't be short unless there's already some sort of error), and + * setting this flag is disallowed (a kernel with USB debugging enabled will + * reject such URBs). */ static int supports_flag_bulk_continuation = -1; @@ -221,17 +221,25 @@ static clockid_t find_monotonic_clock(void) static int check_flag_bulk_continuation(void) { struct utsname uts; - int sublevel; + int major, minor, sublevel; if (uname(&uts) < 0) return -1; if (strlen(uts.release) < 4) return 0; - if (strncmp(uts.release, "2.6.", 4) != 0) + if (sscanf(uts.release, "%d.%d.%d", &major, &minor, &sublevel) != 3) return 0; - - sublevel = atoi(uts.release + 4); - return sublevel >= 32; + if (major < 2) + return 0; + if (major == 2) { + if (minor < 6) + return 0; + if (minor == 6) { + if (sublevel < 32) + return 0; + } + } + return 1; } static int op_init(struct libusb_context *ctx) @@ -1826,6 +1834,7 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer, * 2. we receive a short URB which marks the early completion condition, * so we start cancelling the remaining URBs. however, we're too * slow and another URB completes (or at least completes partially). + * (this can't happen since we always use BULK_CONTINUATION.) * * When this happens, our objectives are not to lose any "surplus" data, * and also to stick it at the end of the previously-received data |