diff options
author | Daniel Drake <dan@reactivated.net> | 2010-04-22 18:12:51 -0300 |
---|---|---|
committer | Michael Plante <michael.plante@gmail.com> | 2010-04-24 11:24:54 +0100 |
commit | 8c7b772f617366c2cf6c7e1e3c1c109ee80d837b (patch) | |
tree | fa15b361c65e20a59db776459fe4fbc3a4630722 | |
parent | bd62c472c4dfec5640f12662f1b01bd3ef41d1f4 (diff) | |
download | libusb-8c7b772f617366c2cf6c7e1e3c1c109ee80d837b.tar.gz |
Linux: don't set SHORT_NOT_OK on bulk out URBs (#20r270
Setting this flag is illegal, and the behaviour we're looking for
is already in place for host-to-device transfers without this flag.
-rw-r--r-- | libusb/os/linux_usbfs.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index 470b511..cf69286 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -72,14 +72,21 @@ static const char *usbfs_path = NULL; -/* Linux 2.6.32 adds support for a bulk continuation URB flag. this should - * be set on all URBs in the transfer except the first. also set the - * SHORT_NOT_OK flag on all of them, to raise error conditions on short - * transfers. - * then, on any error except a cancellation, all URBs until the next - * non-continuation URB will be cancelled with the endpoint disabled, - * meaning that no more data can creep in during the time it takes us to - * cancel the remaining URBs. */ +/* 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. + * + * 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). + */ static int supports_flag_bulk_continuation = -1; /* clock ID for monotonic clock, as not all clock sources are available on all @@ -1334,6 +1341,8 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer, struct linux_device_handle_priv *dpriv = __device_handle_priv(transfer->dev_handle); struct usbfs_urb *urbs; + int is_out = (transfer->endpoint & LIBUSB_ENDPOINT_DIR_MASK) + == LIBUSB_ENDPOINT_OUT; int r; int i; size_t alloc_size; @@ -1372,7 +1381,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer, urb->type = urb_type; urb->endpoint = transfer->endpoint; urb->buffer = transfer->buffer + (i * MAX_BULK_BUFFER_LENGTH); - if (supports_flag_bulk_continuation) + if (supports_flag_bulk_continuation && !is_out) urb->flags = USBFS_URB_SHORT_NOT_OK; if (i == num_urbs - 1 && last_urb_partial) urb->buffer_length = transfer->length % MAX_BULK_BUFFER_LENGTH; |