summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Drake <dan@reactivated.net>2010-04-22 18:12:51 -0300
committerMichael Plante <michael.plante@gmail.com>2010-04-24 11:24:54 +0100
commit8c7b772f617366c2cf6c7e1e3c1c109ee80d837b (patch)
treefa15b361c65e20a59db776459fe4fbc3a4630722
parentbd62c472c4dfec5640f12662f1b01bd3ef41d1f4 (diff)
downloadlibusb-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.c27
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;