Commit 6fd90db8 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

[media] uvcvideo: Support super speed endpoints

Compute the maximum number of bytes per interval using the burst and
multiplier values for super speed endpoints.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent da2cd767
...@@ -1438,6 +1438,26 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers) ...@@ -1438,6 +1438,26 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers)
uvc_free_urb_buffers(stream); 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 * Initialize isochronous URBs and allocate transfer buffers. The packet size
* is given by the endpoint. * is given by the endpoint.
...@@ -1450,8 +1470,7 @@ static int uvc_init_video_isoc(struct uvc_streaming *stream, ...@@ -1450,8 +1470,7 @@ static int uvc_init_video_isoc(struct uvc_streaming *stream,
u16 psize; u16 psize;
u32 size; u32 size;
psize = le16_to_cpu(ep->desc.wMaxPacketSize); psize = uvc_endpoint_max_bpi(stream->dev->udev, ep);
psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
size = stream->ctrl.dwMaxVideoFrameSize; size = stream->ctrl.dwMaxVideoFrameSize;
npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags); npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags);
...@@ -1506,7 +1525,7 @@ static int uvc_init_video_bulk(struct uvc_streaming *stream, ...@@ -1506,7 +1525,7 @@ static int uvc_init_video_bulk(struct uvc_streaming *stream,
u16 psize; u16 psize;
u32 size; u32 size;
psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff; psize = usb_endpoint_maxp(&ep->desc) & 0x7ff;
size = stream->ctrl.dwMaxPayloadTransferSize; size = stream->ctrl.dwMaxPayloadTransferSize;
stream->bulk.max_payload_size = size; stream->bulk.max_payload_size = size;
...@@ -1567,7 +1586,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) ...@@ -1567,7 +1586,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
if (intf->num_altsetting > 1) { if (intf->num_altsetting > 1) {
struct usb_host_endpoint *best_ep = NULL; struct usb_host_endpoint *best_ep = NULL;
unsigned int best_psize = 3 * 1024; unsigned int best_psize = UINT_MAX;
unsigned int bandwidth; unsigned int bandwidth;
unsigned int uninitialized_var(altsetting); unsigned int uninitialized_var(altsetting);
int intfnum = stream->intfnum; int intfnum = stream->intfnum;
...@@ -1595,8 +1614,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) ...@@ -1595,8 +1614,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
continue; continue;
/* Check if the bandwidth is high enough. */ /* Check if the bandwidth is high enough. */
psize = le16_to_cpu(ep->desc.wMaxPacketSize); psize = uvc_endpoint_max_bpi(stream->dev->udev, ep);
psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
if (psize >= bandwidth && psize <= best_psize) { if (psize >= bandwidth && psize <= best_psize) {
altsetting = alts->desc.bAlternateSetting; altsetting = alts->desc.bAlternateSetting;
best_psize = psize; best_psize = psize;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment