|
@@ -1438,6 +1438,26 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers)
|
|
|
uvc_free_urb_buffers(stream);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Compute the maximum number of bytes per interval for an endpoint.
|
|
|
+ */
|
|
|
+static unsigned int uvc_endpoint_max_bpi(struct usb_device *dev,
|
|
|
+ struct usb_host_endpoint *ep)
|
|
|
+{
|
|
|
+ u16 psize;
|
|
|
+
|
|
|
+ switch (dev->speed) {
|
|
|
+ case USB_SPEED_SUPER:
|
|
|
+ return ep->ss_ep_comp.wBytesPerInterval;
|
|
|
+ case USB_SPEED_HIGH:
|
|
|
+ psize = usb_endpoint_maxp(&ep->desc);
|
|
|
+ return (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
|
|
|
+ default:
|
|
|
+ psize = usb_endpoint_maxp(&ep->desc);
|
|
|
+ return psize & 0x07ff;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Initialize isochronous URBs and allocate transfer buffers. The packet size
|
|
|
* is given by the endpoint.
|
|
@@ -1450,8 +1470,7 @@ static int uvc_init_video_isoc(struct uvc_streaming *stream,
|
|
|
u16 psize;
|
|
|
u32 size;
|
|
|
|
|
|
- psize = le16_to_cpu(ep->desc.wMaxPacketSize);
|
|
|
- psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
|
|
|
+ psize = uvc_endpoint_max_bpi(stream->dev->udev, ep);
|
|
|
size = stream->ctrl.dwMaxVideoFrameSize;
|
|
|
|
|
|
npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags);
|
|
@@ -1506,7 +1525,7 @@ static int uvc_init_video_bulk(struct uvc_streaming *stream,
|
|
|
u16 psize;
|
|
|
u32 size;
|
|
|
|
|
|
- psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff;
|
|
|
+ psize = usb_endpoint_maxp(&ep->desc) & 0x7ff;
|
|
|
size = stream->ctrl.dwMaxPayloadTransferSize;
|
|
|
stream->bulk.max_payload_size = size;
|
|
|
|
|
@@ -1567,7 +1586,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
|
|
|
|
|
|
if (intf->num_altsetting > 1) {
|
|
|
struct usb_host_endpoint *best_ep = NULL;
|
|
|
- unsigned int best_psize = 3 * 1024;
|
|
|
+ unsigned int best_psize = UINT_MAX;
|
|
|
unsigned int bandwidth;
|
|
|
unsigned int uninitialized_var(altsetting);
|
|
|
int intfnum = stream->intfnum;
|
|
@@ -1595,8 +1614,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
|
|
|
continue;
|
|
|
|
|
|
/* Check if the bandwidth is high enough. */
|
|
|
- psize = le16_to_cpu(ep->desc.wMaxPacketSize);
|
|
|
- psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
|
|
|
+ psize = uvc_endpoint_max_bpi(stream->dev->udev, ep);
|
|
|
if (psize >= bandwidth && psize <= best_psize) {
|
|
|
altsetting = alts->desc.bAlternateSetting;
|
|
|
best_psize = psize;
|