From 663a419203cc9690d16502be509ffb8acc40552a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 6 Aug 2009 11:41:17 -0300 Subject: V4L/DVB (13149): uvcvideo: Add a new UVC_TRACE_VIDEO trace level Use the trace level for messages related to video URB buffers allocation and alternate setting selection. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_video.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers/media/video/uvc/uvc_video.c') diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index a6e41d12b22..bb9fed66936 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -781,10 +781,15 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream, if (i == UVC_URBS) { stream->urb_size = psize * npackets; + uvc_trace(UVC_TRACE_VIDEO, "Allocated %u URB buffers " + "of %ux%u bytes each.\n", UVC_URBS, npackets, + psize); return npackets; } } + uvc_trace(UVC_TRACE_VIDEO, "Failed to allocate URB buffers (%u bytes " + "per packet).\n", psize); return 0; } @@ -935,10 +940,12 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) bandwidth = stream->ctrl.dwMaxPayloadTransferSize; if (bandwidth == 0) { - uvc_printk(KERN_WARNING, "device %s requested null " - "bandwidth, defaulting to lowest.\n", - stream->dev->name); + uvc_trace(UVC_TRACE_VIDEO, "Device requested null " + "bandwidth, defaulting to lowest.\n"); bandwidth = 1; + } else { + uvc_trace(UVC_TRACE_VIDEO, "Device requested %u " + "B/frame bandwidth.\n", bandwidth); } for (i = 0; i < intf->num_altsetting; ++i) { @@ -955,8 +962,11 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) break; } - if (i >= intf->num_altsetting) + if (i >= intf->num_altsetting) { + uvc_trace(UVC_TRACE_VIDEO, "No fast enough alt setting " + "for requested bandwidth.\n"); return -EIO; + } ret = usb_set_interface(stream->dev->udev, intfnum, i); if (ret < 0) -- cgit v1.2.3-70-g09d2 From fd1b6bbb4a54a232ae6a1e5e4a6fbe3507ed5142 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Sun, 27 Sep 2009 05:30:34 -0300 Subject: V4L/DVB (13153): uvcvideo: Fix uvc_alloc_urb_buffers() This patch sets stream->urb_size as psize*npackets before calling uvc_alloc_urb_buffers, which may fix a possible failure of usb_buffer_free in case usb_buffer_alloc returns NULL. The patch is based on the ideas below: 1,If usb_buffer_alloc can't allocate a buffer sucessfully, uvc_free_urb_buffers will be called to free the allocated buffers, and stream->urb_size is required to be passed to usb_buffer_free; 2,uvc_free_urb_buffers can reset stream->urb_size. This patch is against linux-v2.6.31-next-20090926. Signed-off-by: Ming Lei Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/video/uvc/uvc_video.c') diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index bb9fed66936..3369200a91d 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -770,8 +770,9 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream, /* Retry allocations until one succeed. */ for (; npackets > 1; npackets /= 2) { for (i = 0; i < UVC_URBS; ++i) { + stream->urb_size = psize * npackets; stream->urb_buffer[i] = usb_buffer_alloc( - stream->dev->udev, psize * npackets, + stream->dev->udev, stream->urb_size, gfp_flags | __GFP_NOWARN, &stream->urb_dma[i]); if (!stream->urb_buffer[i]) { uvc_free_urb_buffers(stream); @@ -780,7 +781,6 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream, } if (i == UVC_URBS) { - stream->urb_size = psize * npackets; uvc_trace(UVC_TRACE_VIDEO, "Allocated %u URB buffers " "of %ux%u bytes each.\n", UVC_URBS, npackets, psize); -- cgit v1.2.3-70-g09d2 From b232a012adfea9f535702e8296ea6b76e691f436 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 9 Oct 2009 20:55:23 -0300 Subject: V4L/DVB (13155): uvcvideo: Add a module parameter to set the streaming control timeout The default streaming control timeout was found by Ondrej Zary to be too low for some Logitech webcams. With kernel 2.6.22 and newer they would timeout during initialization unles the audio function was initialized before the video function. Add a module parameter to set the streaming control timeout and increase the default value from 1000ms to 3000ms to fix the above problem. Thanks to Ondrej Zary for investigating the issue and providing an initial patch. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 3 +++ drivers/media/video/uvc/uvc_video.c | 4 ++-- drivers/media/video/uvc/uvcvideo.h | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/media/video/uvc/uvc_video.c') diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 307d3a6b739..ab4a60102d0 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -46,6 +46,7 @@ unsigned int uvc_no_drop_param; static unsigned int uvc_quirks_param; unsigned int uvc_trace_param; +unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT; /* ------------------------------------------------------------------------ * Video formats @@ -2195,6 +2196,8 @@ module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(quirks, "Forced device quirks"); module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(trace, "Trace level bitmask"); +module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(timeout, "Streaming control requests timeout"); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 3369200a91d..05139a4f14f 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -135,7 +135,7 @@ static int uvc_get_video_ctrl(struct uvc_streaming *stream, ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum, probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, - size, UVC_CTRL_STREAMING_TIMEOUT); + size, uvc_timeout_param); if ((query == UVC_GET_MIN || query == UVC_GET_MAX) && ret == 2) { /* Some cameras, mostly based on Bison Electronics chipsets, @@ -239,7 +239,7 @@ static int uvc_set_video_ctrl(struct uvc_streaming *stream, ret = __uvc_query_ctrl(stream->dev, UVC_SET_CUR, 0, stream->intfnum, probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, - size, UVC_CTRL_STREAMING_TIMEOUT); + size, uvc_timeout_param); if (ret != size) { uvc_printk(KERN_ERR, "Failed to set UVC %s control : " "%d (exp. %u).\n", probe ? "probe" : "commit", diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index dae5f57523d..fb3342ae6d7 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -148,7 +148,7 @@ struct uvc_xu_control { #define UVC_MAX_STATUS_SIZE 16 #define UVC_CTRL_CONTROL_TIMEOUT 300 -#define UVC_CTRL_STREAMING_TIMEOUT 1000 +#define UVC_CTRL_STREAMING_TIMEOUT 3000 /* Devices quirks */ #define UVC_QUIRK_STATUS_INTERVAL 0x00000001 @@ -538,6 +538,7 @@ struct uvc_driver { extern unsigned int uvc_no_drop_param; extern unsigned int uvc_trace_param; +extern unsigned int uvc_timeout_param; #define uvc_trace(flag, msg...) \ do { \ -- cgit v1.2.3-70-g09d2