summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/core/urb.c8
-rw-r--r--include/linux/usb.h4
2 files changed, 11 insertions, 1 deletions
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 16927fa88fbd..e75115a04a2e 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -7,6 +7,7 @@
#include <linux/usb.h>
#include <linux/wait.h>
#include <linux/usb/hcd.h>
+#include <linux/scatterlist.h>
#define to_urb(d) container_of(d, struct urb, kref)
@@ -413,6 +414,13 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
urb->iso_frame_desc[n].status = -EXDEV;
urb->iso_frame_desc[n].actual_length = 0;
}
+ } else if (dev->speed != USB_SPEED_WIRELESS && urb->num_sgs) {
+ struct scatterlist *sg;
+ int i;
+
+ for_each_sg(urb->sg, sg, urb->num_sgs - 1, i)
+ if (sg->length % max)
+ return -EINVAL;
}
/* the I/O buffer must be mapped/unmapped, except when length=0 */
diff --git a/include/linux/usb.h b/include/linux/usb.h
index a232b7ece1f6..e99b2a114af4 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1258,7 +1258,9 @@ typedef void (*usb_complete_t)(struct urb *);
* the device driver is saying that it provided this DMA address,
* which the host controller driver should use in preference to the
* transfer_buffer.
- * @sg: scatter gather buffer list
+ * @sg: scatter gather buffer list, the buffer size of each element in
+ * the list (except the last) must be divisible by the endpoint's
+ * max packet size
* @num_mapped_sgs: (internal) number of mapped sg entries
* @num_sgs: number of entries in the sg list
* @transfer_buffer_length: How big is transfer_buffer. The transfer may