aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc/uvc_video.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/uvc/uvc_video.c')
-rw-r--r--drivers/media/video/uvc/uvc_video.c79
1 files changed, 42 insertions, 37 deletions
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 9bc4705be78d..7ebb89539c36 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -699,27 +699,47 @@ static void uvc_free_urb_buffers(struct uvc_video_device *video)
699 * already allocated when resuming from suspend, in which case it will 699 * already allocated when resuming from suspend, in which case it will
700 * return without touching the buffers. 700 * return without touching the buffers.
701 * 701 *
702 * Return 0 on success or -ENOMEM when out of memory. 702 * Limit the buffer size to UVC_MAX_PACKETS bulk/isochronous packets. If the
703 * system is too low on memory try successively smaller numbers of packets
704 * until allocation succeeds.
705 *
706 * Return the number of allocated packets on success or 0 when out of memory.
703 */ 707 */
704static int uvc_alloc_urb_buffers(struct uvc_video_device *video, 708static int uvc_alloc_urb_buffers(struct uvc_video_device *video,
705 unsigned int size) 709 unsigned int size, unsigned int psize, gfp_t gfp_flags)
706{ 710{
711 unsigned int npackets;
707 unsigned int i; 712 unsigned int i;
708 713
709 /* Buffers are already allocated, bail out. */ 714 /* Buffers are already allocated, bail out. */
710 if (video->urb_size) 715 if (video->urb_size)
711 return 0; 716 return 0;
712 717
713 for (i = 0; i < UVC_URBS; ++i) { 718 /* Compute the number of packets. Bulk endpoints might transfer UVC
714 video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, 719 * payloads accross multiple URBs.
715 size, GFP_KERNEL, &video->urb_dma[i]); 720 */
716 if (video->urb_buffer[i] == NULL) { 721 npackets = DIV_ROUND_UP(size, psize);
717 uvc_free_urb_buffers(video); 722 if (npackets > UVC_MAX_PACKETS)
718 return -ENOMEM; 723 npackets = UVC_MAX_PACKETS;
724
725 /* Retry allocations until one succeed. */
726 for (; npackets > 1; npackets /= 2) {
727 for (i = 0; i < UVC_URBS; ++i) {
728 video->urb_buffer[i] = usb_buffer_alloc(
729 video->dev->udev, psize * npackets,
730 gfp_flags | __GFP_NOWARN, &video->urb_dma[i]);
731 if (!video->urb_buffer[i]) {
732 uvc_free_urb_buffers(video);
733 break;
734 }
735 }
736
737 if (i == UVC_URBS) {
738 video->urb_size = psize * npackets;
739 return npackets;
719 } 740 }
720 } 741 }
721 742
722 video->urb_size = size;
723 return 0; 743 return 0;
724} 744}
725 745
@@ -753,29 +773,19 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
753{ 773{
754 struct urb *urb; 774 struct urb *urb;
755 unsigned int npackets, i, j; 775 unsigned int npackets, i, j;
756 __u16 psize; 776 u16 psize;
757 __u32 size; 777 u32 size;
758 778
759 /* Compute the number of isochronous packets to allocate by dividing
760 * the maximum video frame size by the packet size. Limit the result
761 * to UVC_MAX_ISO_PACKETS.
762 */
763 psize = le16_to_cpu(ep->desc.wMaxPacketSize); 779 psize = le16_to_cpu(ep->desc.wMaxPacketSize);
764 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); 780 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
765
766 size = video->streaming->ctrl.dwMaxVideoFrameSize; 781 size = video->streaming->ctrl.dwMaxVideoFrameSize;
767 if (size > UVC_MAX_FRAME_SIZE)
768 return -EINVAL;
769 782
770 npackets = DIV_ROUND_UP(size, psize); 783 npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags);
771 if (npackets > UVC_MAX_ISO_PACKETS) 784 if (npackets == 0)
772 npackets = UVC_MAX_ISO_PACKETS; 785 return -ENOMEM;
773 786
774 size = npackets * psize; 787 size = npackets * psize;
775 788
776 if (uvc_alloc_urb_buffers(video, size) < 0)
777 return -ENOMEM;
778
779 for (i = 0; i < UVC_URBS; ++i) { 789 for (i = 0; i < UVC_URBS; ++i) {
780 urb = usb_alloc_urb(npackets, gfp_flags); 790 urb = usb_alloc_urb(npackets, gfp_flags);
781 if (urb == NULL) { 791 if (urb == NULL) {
@@ -814,25 +824,20 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
814 struct usb_host_endpoint *ep, gfp_t gfp_flags) 824 struct usb_host_endpoint *ep, gfp_t gfp_flags)
815{ 825{
816 struct urb *urb; 826 struct urb *urb;
817 unsigned int pipe, i; 827 unsigned int npackets, pipe, i;
818 __u16 psize; 828 u16 psize;
819 __u32 size; 829 u32 size;
820 830
821 /* Compute the bulk URB size. Some devices set the maximum payload
822 * size to a value too high for memory-constrained devices. We must
823 * then transfer the payload accross multiple URBs. To be consistant
824 * with isochronous mode, allocate maximum UVC_MAX_ISO_PACKETS per bulk
825 * URB.
826 */
827 psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff; 831 psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff;
828 size = video->streaming->ctrl.dwMaxPayloadTransferSize; 832 size = video->streaming->ctrl.dwMaxPayloadTransferSize;
829 video->bulk.max_payload_size = size; 833 video->bulk.max_payload_size = size;
830 if (size > psize * UVC_MAX_ISO_PACKETS)
831 size = psize * UVC_MAX_ISO_PACKETS;
832 834
833 if (uvc_alloc_urb_buffers(video, size) < 0) 835 npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags);
836 if (npackets == 0)
834 return -ENOMEM; 837 return -ENOMEM;
835 838
839 size = npackets * psize;
840
836 if (usb_endpoint_dir_in(&ep->desc)) 841 if (usb_endpoint_dir_in(&ep->desc))
837 pipe = usb_rcvbulkpipe(video->dev->udev, 842 pipe = usb_rcvbulkpipe(video->dev->udev,
838 ep->desc.bEndpointAddress); 843 ep->desc.bEndpointAddress);