Commit d732c44c authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

V4L/DVB (11944): uvcvideo: Add generic control blacklist.

Another device (5986:0241) has been reported to advertise a UVC control it
does not support. Rework the control blacklist to match devices by their
VID:PID instead of trying to be clever about which controls might not be
supported properly.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 926b3b41
...@@ -1372,21 +1372,19 @@ int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping) ...@@ -1372,21 +1372,19 @@ int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping)
} }
/* /*
* Prune an entity of its bogus controls. This currently includes processing * Prune an entity of its bogus controls using a blacklist. Bogus controls
* unit auto controls for which no corresponding manual control is available. * are currently the ones that crash the camera or unconditionally return an
* Such auto controls make little sense if any, and are known to crash at * error when queried.
* least the SiGma Micro webcam.
*/ */
static void static void
uvc_ctrl_prune_entity(struct uvc_entity *entity) uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity)
{ {
static const struct { static const struct {
u8 idx_manual; struct usb_device_id id;
u8 idx_auto; u8 index;
} blacklist[] = { } blacklist[] = {
{ 2, 11 }, /* Hue */ { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */
{ 6, 12 }, /* White Balance Temperature */ { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */
{ 7, 13 }, /* White Balance Component */
}; };
u8 *controls; u8 *controls;
...@@ -1400,19 +1398,17 @@ uvc_ctrl_prune_entity(struct uvc_entity *entity) ...@@ -1400,19 +1398,17 @@ uvc_ctrl_prune_entity(struct uvc_entity *entity)
size = entity->processing.bControlSize; size = entity->processing.bControlSize;
for (i = 0; i < ARRAY_SIZE(blacklist); ++i) { for (i = 0; i < ARRAY_SIZE(blacklist); ++i) {
if (blacklist[i].idx_auto >= 8 * size || if (!usb_match_id(dev->intf, &blacklist[i].id))
blacklist[i].idx_manual >= 8 * size)
continue; continue;
if (!uvc_test_bit(controls, blacklist[i].idx_auto) || if (blacklist[i].index >= 8 * size ||
uvc_test_bit(controls, blacklist[i].idx_manual)) !uvc_test_bit(controls, blacklist[i].index))
continue; continue;
uvc_trace(UVC_TRACE_CONTROL, "Auto control %u/%u has no " uvc_trace(UVC_TRACE_CONTROL, "%u/%u control is black listed, "
"matching manual control, removing it.\n", entity->id, "removing it.\n", entity->id, blacklist[i].index);
blacklist[i].idx_auto);
uvc_clear_bit(controls, blacklist[i].idx_auto); uvc_clear_bit(controls, blacklist[i].index);
} }
} }
...@@ -1442,8 +1438,7 @@ int uvc_ctrl_init_device(struct uvc_device *dev) ...@@ -1442,8 +1438,7 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
bControlSize = entity->camera.bControlSize; bControlSize = entity->camera.bControlSize;
} }
if (dev->quirks & UVC_QUIRK_PRUNE_CONTROLS) uvc_ctrl_prune_entity(dev, entity);
uvc_ctrl_prune_entity(entity);
for (i = 0; i < bControlSize; ++i) for (i = 0; i < bControlSize; ++i)
ncontrols += hweight8(bmControls[i]); ncontrols += hweight8(bmControls[i]);
......
...@@ -1946,8 +1946,7 @@ static struct usb_device_id uvc_ids[] = { ...@@ -1946,8 +1946,7 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1, .bInterfaceSubClass = 1,
.bInterfaceProtocol = 0, .bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_PROBE_MINMAX .driver_info = UVC_QUIRK_PROBE_MINMAX
| UVC_QUIRK_IGNORE_SELECTOR_UNIT | UVC_QUIRK_IGNORE_SELECTOR_UNIT },
| UVC_QUIRK_PRUNE_CONTROLS },
/* Generic USB Video Class */ /* Generic USB Video Class */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
{} {}
......
...@@ -313,7 +313,6 @@ struct uvc_xu_control { ...@@ -313,7 +313,6 @@ struct uvc_xu_control {
#define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008 #define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008
#define UVC_QUIRK_STREAM_NO_FID 0x00000010 #define UVC_QUIRK_STREAM_NO_FID 0x00000010
#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020
#define UVC_QUIRK_PRUNE_CONTROLS 0x00000040
#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 #define UVC_QUIRK_FIX_BANDWIDTH 0x00000080
/* Format flags */ /* Format flags */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment