diff options
author | Daniel Drake <dsd@gentoo.org> | 2008-05-05 01:00:31 +0100 |
---|---|---|
committer | Daniel Drake <dsd@gentoo.org> | 2008-05-05 01:00:31 +0100 |
commit | 7da521954ba661d3f537440c31a84b66e974d56b (patch) | |
tree | d273a0e06399f8aced15884dcaa58d62da247af5 /libusb/os/linux_usbfs.c | |
parent | 470b1bc42bf53373ce678fc76bab9160a54d6881 (diff) | |
download | libusb-7da521954ba661d3f537440c31a84b66e974d56b.tar.gz |
Linux: fix logical URB allocation
We were allocating the wrong number of URBs for transfers of size
multiples of 16k.
Diffstat (limited to 'libusb/os/linux_usbfs.c')
-rw-r--r-- | libusb/os/linux_usbfs.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index 40a32f1..ec7907f 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -598,7 +598,13 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer, * into smaller units to meet such restriction, then fire off all the * units at once. it would be simpler if we just fired one unit at a time, * but there is a big performance gain through doing it this way. */ - int num_urbs = (transfer->length / MAX_BULK_BUFFER_LENGTH) + 1; + int num_urbs = transfer->length / MAX_BULK_BUFFER_LENGTH; + int last_urb_partial = 0; + + if ((transfer->length % MAX_BULK_BUFFER_LENGTH) > 0) { + last_urb_partial = 1; + num_urbs++; + } usbi_dbg("need %d urbs for new transfer with length %d", num_urbs, transfer->length); alloc_size = num_urbs * sizeof(struct usbfs_urb); @@ -618,7 +624,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 (i == num_urbs - 1) + if (i == num_urbs - 1 && last_urb_partial) urb->buffer_length = transfer->length % MAX_BULK_BUFFER_LENGTH; else urb->buffer_length = MAX_BULK_BUFFER_LENGTH; |