@@ -823,9 +823,7 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream,
/* Compute the number of packets. Bulk endpoints might transfer UVC
* payloads across multiple URBs.
*/
- npackets = DIV_ROUND_UP(size, psize);
- if (npackets > UVC_MAX_PACKETS)
- npackets = UVC_MAX_PACKETS;
+ npackets = size / psize;
/* Retry allocations until one succeed. */
for (; npackets > 1; npackets /= 2) {
@@ -888,8 +886,25 @@ static int uvc_init_video_isoc(struct uvc_streaming *stream,
u32 size;
psize = le16_to_cpu(ep->desc.wMaxPacketSize);
- psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
- size = stream->ctrl.dwMaxVideoFrameSize;
+
+ if (stream->dev->udev->speed == USB_SPEED_FULL) {
+ /* (8000 >> 3) = 1000 FPS */
+ psize = (psize & 0x07ff);
+ size = (UVC_MAX_PACKETS >> 3) * psize;
+ } else {
+ /* 1000 - 8000 FPS, figure out */
+ psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
+ size = ep->desc.bInterval;
+ if (size > 0)
+ size --;
+ if (size > 3)
+ size = 3;
+ size = (UVC_MAX_PACKETS >> size) * psize;
+ }
+
+ /* avoid division by zero */
+ if (psize == 0)
+ return -EINVAL;
npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags);
if (npackets == 0)
@@ -943,6 +958,19 @@ static int uvc_init_video_bulk(struct uvc_streaming *stream,
size = stream->ctrl.dwMaxPayloadTransferSize;
stream->bulk.max_payload_size = size;
+ /* avoid division by zero */
+ if (psize == 0)
+ return -EINVAL;
+
+ /* roughly compute size for buffers */
+ if (stream->dev->udev->speed == USB_SPEED_FULL) {
+ size = 4096;
+ } else {
+ size = 16384;
+ }
+ /* align to packet boundary */
+ size += (psize - (size % psize)) % psize;
+
npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags);
if (npackets == 0)
return -ENOMEM;
@@ -161,9 +161,9 @@ struct uvc_xu_control {
#define DRIVER_VERSION "v1.0.0"
/* Number of isochronous URBs. */
-#define UVC_URBS 5
+#define UVC_URBS 2U
/* Maximum number of packets per URB. */
-#define UVC_MAX_PACKETS 32
+#define UVC_MAX_PACKETS 128U /* at 8000 FPS */
/* Maximum number of video buffers. */
#define UVC_MAX_VIDEO_BUFFERS 32
/* Maximum status buffer size in bytes of interrupt URB. */