aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@skynet.be>2009-01-18 15:46:30 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:26 -0400
commitefdc8a9585ce02e70e538e46f235aefd63a3f8da (patch)
treeaf233b7335af3914211348d83da4e32c8459be19 /drivers/media/video/uvc
parentf61d1d8a563b1f3c5f1f55d856278aae3fd3987e (diff)
V4L/DVB (10295): uvcvideo: Retry URB buffers allocation when the system is low on memory.
URB buffers for video transfers are sized to UVC_MAX_PACKETS bulk/isochronous packets by default. If the system is too low on memory try successively smaller numbers of packets until allocation succeeds. Tested-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be> Reviewed-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/uvc')
-rw-r--r--drivers/media/video/uvc/uvc_video.c79
-rw-r--r--drivers/media/video/uvc/uvcvideo.h6
2 files changed, 44 insertions, 41 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);
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 027947ea9b6e..b2639878f9b2 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -296,10 +296,8 @@ struct uvc_xu_control {
296 296
297/* Number of isochronous URBs. */ 297/* Number of isochronous URBs. */
298#define UVC_URBS 5 298#define UVC_URBS 5
299/* Maximum number of packets per isochronous URB. */ 299/* Maximum number of packets per URB. */
300#define UVC_MAX_ISO_PACKETS 40 300#define UVC_MAX_PACKETS 32
301/* Maximum frame size in bytes, for sanity checking. */
302#define UVC_MAX_FRAME_SIZE (16*1024*1024)
303/* Maximum number of video buffers. */ 301/* Maximum number of video buffers. */
304#define UVC_MAX_VIDEO_BUFFERS 32 302#define UVC_MAX_VIDEO_BUFFERS 32
305/* Maximum status buffer size in bytes of interrupt URB. */ 303/* Maximum status buffer size in bytes of interrupt URB. */