aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@skynet.be>2008-11-08 17:14:50 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-29 14:53:31 -0500
commit44f0079ec74330b457d990072c13cbe28b0f1abf (patch)
treea5af6ae41c4ff9dabc882d08cfda79a791d56430 /drivers/media/video/uvc
parent7e21fda17e7f6156e2ad66ca4f76abcbe1063eb2 (diff)
V4L/DVB (9570): uvcvideo: Handle failed video GET_{MIN|MAX|DEF} requests more gracefully
Failed requests will now generate a one-time warning message instead of the usual "Failed to query..." error, which should be more user-friendly. The driver will also recover automatically from failed GET_MIN/GET_MAX requests when the device is half-broken without requiring the MINMAX quirk (fully broken devices still need the quirk). Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/uvc')
-rw-r--r--drivers/media/video/uvc/uvc_driver.c126
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c4
-rw-r--r--drivers/media/video/uvc/uvc_video.c63
-rw-r--r--drivers/media/video/uvc/uvcvideo.h14
4 files changed, 66 insertions, 141 deletions
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 11398ee66320..1e3b4fe5ae93 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1726,24 +1726,6 @@ static int uvc_reset_resume(struct usb_interface *intf)
1726 * though they are compliant. 1726 * though they are compliant.
1727 */ 1727 */
1728static struct usb_device_id uvc_ids[] = { 1728static struct usb_device_id uvc_ids[] = {
1729 /* ALi M5606 (Clevo M540SR) */
1730 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1731 | USB_DEVICE_ID_MATCH_INT_INFO,
1732 .idVendor = 0x0402,
1733 .idProduct = 0x5606,
1734 .bInterfaceClass = USB_CLASS_VIDEO,
1735 .bInterfaceSubClass = 1,
1736 .bInterfaceProtocol = 0,
1737 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1738 /* Creative Live! Optia */
1739 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1740 | USB_DEVICE_ID_MATCH_INT_INFO,
1741 .idVendor = 0x041e,
1742 .idProduct = 0x4057,
1743 .bInterfaceClass = USB_CLASS_VIDEO,
1744 .bInterfaceSubClass = 1,
1745 .bInterfaceProtocol = 0,
1746 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1747 /* Microsoft Lifecam NX-6000 */ 1729 /* Microsoft Lifecam NX-6000 */
1748 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1730 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1749 | USB_DEVICE_ID_MATCH_INT_INFO, 1731 | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1829,15 +1811,6 @@ static struct usb_device_id uvc_ids[] = {
1829 .bInterfaceSubClass = 1, 1811 .bInterfaceSubClass = 1,
1830 .bInterfaceProtocol = 0, 1812 .bInterfaceProtocol = 0,
1831 .driver_info = UVC_QUIRK_STREAM_NO_FID }, 1813 .driver_info = UVC_QUIRK_STREAM_NO_FID },
1832 /* Silicon Motion SM371 */
1833 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1834 | USB_DEVICE_ID_MATCH_INT_INFO,
1835 .idVendor = 0x090c,
1836 .idProduct = 0xb371,
1837 .bInterfaceClass = USB_CLASS_VIDEO,
1838 .bInterfaceSubClass = 1,
1839 .bInterfaceProtocol = 0,
1840 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1841 /* MT6227 */ 1814 /* MT6227 */
1842 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1815 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1843 | USB_DEVICE_ID_MATCH_INT_INFO, 1816 | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1922,105 +1895,6 @@ static struct usb_device_id uvc_ids[] = {
1922 .bInterfaceProtocol = 0, 1895 .bInterfaceProtocol = 0,
1923 .driver_info = UVC_QUIRK_PROBE_MINMAX 1896 .driver_info = UVC_QUIRK_PROBE_MINMAX
1924 | UVC_QUIRK_IGNORE_SELECTOR_UNIT}, 1897 | UVC_QUIRK_IGNORE_SELECTOR_UNIT},
1925 /* Acer OEM Webcam - Unknown vendor */
1926 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1927 | USB_DEVICE_ID_MATCH_INT_INFO,
1928 .idVendor = 0x5986,
1929 .idProduct = 0x0100,
1930 .bInterfaceClass = USB_CLASS_VIDEO,
1931 .bInterfaceSubClass = 1,
1932 .bInterfaceProtocol = 0,
1933 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1934 /* Packard Bell OEM Webcam - Bison Electronics */
1935 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1936 | USB_DEVICE_ID_MATCH_INT_INFO,
1937 .idVendor = 0x5986,
1938 .idProduct = 0x0101,
1939 .bInterfaceClass = USB_CLASS_VIDEO,
1940 .bInterfaceSubClass = 1,
1941 .bInterfaceProtocol = 0,
1942 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1943 /* Acer Crystal Eye webcam - Bison Electronics */
1944 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1945 | USB_DEVICE_ID_MATCH_INT_INFO,
1946 .idVendor = 0x5986,
1947 .idProduct = 0x0102,
1948 .bInterfaceClass = USB_CLASS_VIDEO,
1949 .bInterfaceSubClass = 1,
1950 .bInterfaceProtocol = 0,
1951 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1952 /* Compaq Presario B1200 - Bison Electronics */
1953 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1954 | USB_DEVICE_ID_MATCH_INT_INFO,
1955 .idVendor = 0x5986,
1956 .idProduct = 0x0104,
1957 .bInterfaceClass = USB_CLASS_VIDEO,
1958 .bInterfaceSubClass = 1,
1959 .bInterfaceProtocol = 0,
1960 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1961 /* Acer Travelmate 7720 - Bison Electronics */
1962 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1963 | USB_DEVICE_ID_MATCH_INT_INFO,
1964 .idVendor = 0x5986,
1965 .idProduct = 0x0105,
1966 .bInterfaceClass = USB_CLASS_VIDEO,
1967 .bInterfaceSubClass = 1,
1968 .bInterfaceProtocol = 0,
1969 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1970 /* Medion Akoya Mini E1210 - Bison Electronics */
1971 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1972 | USB_DEVICE_ID_MATCH_INT_INFO,
1973 .idVendor = 0x5986,
1974 .idProduct = 0x0141,
1975 .bInterfaceClass = USB_CLASS_VIDEO,
1976 .bInterfaceSubClass = 1,
1977 .bInterfaceProtocol = 0,
1978 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1979 /* Acer OrbiCam - Bison Electronics */
1980 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1981 | USB_DEVICE_ID_MATCH_INT_INFO,
1982 .idVendor = 0x5986,
1983 .idProduct = 0x0200,
1984 .bInterfaceClass = USB_CLASS_VIDEO,
1985 .bInterfaceSubClass = 1,
1986 .bInterfaceProtocol = 0,
1987 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1988 /* Fujitsu Amilo SI2636 - Bison Electronics */
1989 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1990 | USB_DEVICE_ID_MATCH_INT_INFO,
1991 .idVendor = 0x5986,
1992 .idProduct = 0x0202,
1993 .bInterfaceClass = USB_CLASS_VIDEO,
1994 .bInterfaceSubClass = 1,
1995 .bInterfaceProtocol = 0,
1996 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1997 /* Advent 4211 - Bison Electronics */
1998 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1999 | USB_DEVICE_ID_MATCH_INT_INFO,
2000 .idVendor = 0x5986,
2001 .idProduct = 0x0203,
2002 .bInterfaceClass = USB_CLASS_VIDEO,
2003 .bInterfaceSubClass = 1,
2004 .bInterfaceProtocol = 0,
2005 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2006 /* Bison Electronics */
2007 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2008 | USB_DEVICE_ID_MATCH_INT_INFO,
2009 .idVendor = 0x5986,
2010 .idProduct = 0x0300,
2011 .bInterfaceClass = USB_CLASS_VIDEO,
2012 .bInterfaceSubClass = 1,
2013 .bInterfaceProtocol = 0,
2014 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2015 /* Clevo M570TU - Bison Electronics */
2016 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2017 | USB_DEVICE_ID_MATCH_INT_INFO,
2018 .idVendor = 0x5986,
2019 .idProduct = 0x0303,
2020 .bInterfaceClass = USB_CLASS_VIDEO,
2021 .bInterfaceSubClass = 1,
2022 .bInterfaceProtocol = 0,
2023 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2024 /* Generic USB Video Class */ 1898 /* Generic USB Video Class */
2025 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, 1899 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
2026 {} 1900 {}
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 8361367806a9..624bf74de673 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -252,7 +252,7 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video,
252 if (ret < 0) 252 if (ret < 0)
253 return ret; 253 return ret;
254 254
255 if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0) 255 if ((ret = uvc_commit_video(video, &probe)) < 0)
256 return ret; 256 return ret;
257 257
258 memcpy(&video->streaming->ctrl, &probe, sizeof probe); 258 memcpy(&video->streaming->ctrl, &probe, sizeof probe);
@@ -316,7 +316,7 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
316 return ret; 316 return ret;
317 317
318 /* Commit the new settings. */ 318 /* Commit the new settings. */
319 if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0) 319 if ((ret = uvc_commit_video(video, &probe)) < 0)
320 return ret; 320 return ret;
321 321
322 memcpy(&video->streaming->ctrl, &probe, sizeof probe); 322 memcpy(&video->streaming->ctrl, &probe, sizeof probe);
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index b7bb23820d80..4af94707ef69 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -36,15 +36,22 @@ static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
36{ 36{
37 __u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE; 37 __u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
38 unsigned int pipe; 38 unsigned int pipe;
39 int ret;
40 39
41 pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0) 40 pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0)
42 : usb_sndctrlpipe(dev->udev, 0); 41 : usb_sndctrlpipe(dev->udev, 0);
43 type |= (query & 0x80) ? USB_DIR_IN : USB_DIR_OUT; 42 type |= (query & 0x80) ? USB_DIR_IN : USB_DIR_OUT;
44 43
45 ret = usb_control_msg(dev->udev, pipe, query, type, cs << 8, 44 return usb_control_msg(dev->udev, pipe, query, type, cs << 8,
46 unit << 8 | intfnum, data, size, timeout); 45 unit << 8 | intfnum, data, size, timeout);
46}
47
48int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
49 __u8 intfnum, __u8 cs, void *data, __u16 size)
50{
51 int ret;
47 52
53 ret = __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size,
54 UVC_CTRL_CONTROL_TIMEOUT);
48 if (ret != size) { 55 if (ret != size) {
49 uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u " 56 uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u "
50 "(unit %u) : %d (exp. %u).\n", query, cs, unit, ret, 57 "(unit %u) : %d (exp. %u).\n", query, cs, unit, ret,
@@ -55,13 +62,6 @@ static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
55 return 0; 62 return 0;
56} 63}
57 64
58int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
59 __u8 intfnum, __u8 cs, void *data, __u16 size)
60{
61 return __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size,
62 UVC_CTRL_CONTROL_TIMEOUT);
63}
64
65static void uvc_fixup_buffer_size(struct uvc_video_device *video, 65static void uvc_fixup_buffer_size(struct uvc_video_device *video,
66 struct uvc_streaming_control *ctrl) 66 struct uvc_streaming_control *ctrl)
67{ 67{
@@ -102,8 +102,36 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
102 ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, 102 ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum,
103 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, 103 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
104 UVC_CTRL_STREAMING_TIMEOUT); 104 UVC_CTRL_STREAMING_TIMEOUT);
105 if (ret < 0) 105
106 if ((query == GET_MIN || query == GET_MAX) && ret == 2) {
107 /* Some cameras, mostly based on Bison Electronics chipsets,
108 * answer a GET_MIN or GET_MAX request with the wCompQuality
109 * field only.
110 */
111 uvc_warn_once(video->dev, UVC_WARN_MINMAX, "UVC non "
112 "compliance - GET_MIN/MAX(PROBE) incorrectly "
113 "supported. Enabling workaround.\n");
114 memset(ctrl, 0, sizeof ctrl);
115 ctrl->wCompQuality = le16_to_cpup((__le16 *)data);
116 ret = 0;
106 goto out; 117 goto out;
118 } else if (query == GET_DEF && probe == 1) {
119 /* Many cameras don't support the GET_DEF request on their
120 * video probe control. Warn once and return, the caller will
121 * fall back to GET_CUR.
122 */
123 uvc_warn_once(video->dev, UVC_WARN_PROBE_DEF, "UVC non "
124 "compliance - GET_DEF(PROBE) not supported. "
125 "Enabling workaround.\n");
126 ret = -EIO;
127 goto out;
128 } else if (ret != size) {
129 uvc_printk(KERN_ERR, "Failed to query (%u) UVC %s control : "
130 "%d (exp. %u).\n", query, probe ? "probe" : "commit",
131 ret, size);
132 ret = -EIO;
133 goto out;
134 }
107 135
108 ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]); 136 ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]);
109 ctrl->bFormatIndex = data[2]; 137 ctrl->bFormatIndex = data[2];
@@ -138,13 +166,14 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
138 * Try to get the value from the format and frame descriptor. 166 * Try to get the value from the format and frame descriptor.
139 */ 167 */
140 uvc_fixup_buffer_size(video, ctrl); 168 uvc_fixup_buffer_size(video, ctrl);
169 ret = 0;
141 170
142out: 171out:
143 kfree(data); 172 kfree(data);
144 return ret; 173 return ret;
145} 174}
146 175
147int uvc_set_video_ctrl(struct uvc_video_device *video, 176static int uvc_set_video_ctrl(struct uvc_video_device *video,
148 struct uvc_streaming_control *ctrl, int probe) 177 struct uvc_streaming_control *ctrl, int probe)
149{ 178{
150 __u8 *data; 179 __u8 *data;
@@ -186,6 +215,12 @@ int uvc_set_video_ctrl(struct uvc_video_device *video,
186 video->streaming->intfnum, 215 video->streaming->intfnum,
187 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, 216 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
188 UVC_CTRL_STREAMING_TIMEOUT); 217 UVC_CTRL_STREAMING_TIMEOUT);
218 if (ret != size) {
219 uvc_printk(KERN_ERR, "Failed to set UVC %s control : "
220 "%d (exp. %u).\n", probe ? "probe" : "commit",
221 ret, size);
222 ret = -EIO;
223 }
189 224
190 kfree(data); 225 kfree(data);
191 return ret; 226 return ret;
@@ -252,6 +287,12 @@ done:
252 return ret; 287 return ret;
253} 288}
254 289
290int uvc_commit_video(struct uvc_video_device *video,
291 struct uvc_streaming_control *probe)
292{
293 return uvc_set_video_ctrl(video, probe, 0);
294}
295
255/* ------------------------------------------------------------------------ 296/* ------------------------------------------------------------------------
256 * Video codecs 297 * Video codecs
257 */ 298 */
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 9a6bc1aafb16..595b90ee6528 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -617,6 +617,7 @@ enum uvc_device_state {
617struct uvc_device { 617struct uvc_device {
618 struct usb_device *udev; 618 struct usb_device *udev;
619 struct usb_interface *intf; 619 struct usb_interface *intf;
620 unsigned long warnings;
620 __u32 quirks; 621 __u32 quirks;
621 int intfnum; 622 int intfnum;
622 char name[32]; 623 char name[32];
@@ -679,6 +680,9 @@ struct uvc_driver {
679#define UVC_TRACE_SUSPEND (1 << 8) 680#define UVC_TRACE_SUSPEND (1 << 8)
680#define UVC_TRACE_STATUS (1 << 9) 681#define UVC_TRACE_STATUS (1 << 9)
681 682
683#define UVC_WARN_MINMAX 0
684#define UVC_WARN_PROBE_DEF 1
685
682extern unsigned int uvc_trace_param; 686extern unsigned int uvc_trace_param;
683 687
684#define uvc_trace(flag, msg...) \ 688#define uvc_trace(flag, msg...) \
@@ -687,6 +691,12 @@ extern unsigned int uvc_trace_param;
687 printk(KERN_DEBUG "uvcvideo: " msg); \ 691 printk(KERN_DEBUG "uvcvideo: " msg); \
688 } while (0) 692 } while (0)
689 693
694#define uvc_warn_once(dev, warn, msg...) \
695 do { \
696 if (!test_and_set_bit(warn, &dev->warnings)) \
697 printk(KERN_INFO "uvcvideo: " msg); \
698 } while (0)
699
690#define uvc_printk(level, msg...) \ 700#define uvc_printk(level, msg...) \
691 printk(level "uvcvideo: " msg) 701 printk(level "uvcvideo: " msg)
692 702
@@ -740,10 +750,10 @@ extern int uvc_video_resume(struct uvc_video_device *video);
740extern int uvc_video_enable(struct uvc_video_device *video, int enable); 750extern int uvc_video_enable(struct uvc_video_device *video, int enable);
741extern int uvc_probe_video(struct uvc_video_device *video, 751extern int uvc_probe_video(struct uvc_video_device *video,
742 struct uvc_streaming_control *probe); 752 struct uvc_streaming_control *probe);
753extern int uvc_commit_video(struct uvc_video_device *video,
754 struct uvc_streaming_control *ctrl);
743extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, 755extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
744 __u8 intfnum, __u8 cs, void *data, __u16 size); 756 __u8 intfnum, __u8 cs, void *data, __u16 size);
745extern int uvc_set_video_ctrl(struct uvc_video_device *video,
746 struct uvc_streaming_control *ctrl, int probe);
747 757
748/* Status */ 758/* Status */
749extern int uvc_status_init(struct uvc_device *dev); 759extern int uvc_status_init(struct uvc_device *dev);