usb: gadget: uvc: Make video streaming buffer size comply with USB3.0 SS
authorBhupesh Sharma <bhupesh.sharma@st.com>
Fri, 1 Mar 2013 19:46:31 +0000 (20:46 +0100)
committerFelipe Balbi <balbi@ti.com>
Mon, 18 Mar 2013 09:18:22 +0000 (11:18 +0200)
As per the USB3.0 specs, the bandwidth requirements of a UVC's video
streaming endpoint will change to support super-speed. These changes
will be dependent on whether the UVC video streaming endpoint is Bulk or
Isochronous:

- If video streaming endpoint is Isochronous:
  As per Section 4.4.8.2 (Isochronous Transfer Bandwidth Requirements)
  of the USB3.0 specs:

    A SuperSpeed isochronous endpoint can move up to three burst
    transactions of up to 16 maximum sized packets (3 * 16 * 1024 bytes)
    per service interval.

- If video streaming endpoint is Bulk:
  As per 4.4.6.1 (Bulk Transfer Data Packet Size) of the USB3.0 specs:

    An endpoint for bulk transfers shall set the maximum data packet
    payload size in its endpoint descriptor to 1024 bytes. It also
    specifies the burst size that the endpoint can accept from or
    transmit on the SuperSpeed bus. The allowable burst size for a bulk
    endpoint shall be in the range of 1 to 16.

So, in the Isochronous case, we can define the USB request's buffer to
be equal to = (Maximum packet size) * (bMaxBurst + 1) * (Mult + 1), so
that the UDC driver can try to send out this buffer in one Isochronous
service interval.

The same computation will hold good for the Bulk case as the Mult
value is 0 here and we can have a USB request buffer of maximum
16 * 1024 bytes size, which can be sent out by the UDC driver as
per the Bulk bandwidth allocation on the USB3 bus.

This patch adds the above-mentioned support and is also USB2.0 backward
compliant.

Signed-off-by: Bhupesh Sharma <bhupesh.sharma@st.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Bhupesh Sharma <bhupesh.sharma@st.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/gadget/uvc_video.c

index 885c393ee470f39b5e26ef63d46b29321f269981..fac99a97b7824e3a3cb9d40e055b0a6b0f8f87b6 100644 (file)
@@ -229,13 +229,18 @@ uvc_video_free_requests(struct uvc_video *video)
 static int
 uvc_video_alloc_requests(struct uvc_video *video)
 {
+       unsigned int req_size;
        unsigned int i;
        int ret = -ENOMEM;
 
        BUG_ON(video->req_size);
 
+       req_size = video->ep->maxpacket
+                * max_t(unsigned int, video->ep->maxburst, 1)
+                * (video->ep->mult + 1);
+
        for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
-               video->req_buffer[i] = kmalloc(video->ep->maxpacket, GFP_KERNEL);
+               video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL);
                if (video->req_buffer[i] == NULL)
                        goto error;
 
@@ -251,7 +256,8 @@ uvc_video_alloc_requests(struct uvc_video *video)
                list_add_tail(&video->req[i]->list, &video->req_free);
        }
 
-       video->req_size = video->ep->maxpacket;
+       video->req_size = req_size;
+
        return 0;
 
 error: