Hi Jérôme,

On Thursday 28 May 2009 15:21:52 Jérôme Pouiller wrote:
> Hi Laurent,
>
> On Wednesday 27 May 2009 17:11:03 Laurent Pinchart wrote:
> [...]
>
> > On Tuesday 26 May 2009 17:49:14 Jérôme Pouiller wrote:
>
> [...]
>
> > > 2. It looks like a hardware bug, but how to prove it?
> >
> > The camera stalls a GET_DEF request  on the hue control. First of all,
> > does the problem occur every time  the hue control is queried, or only
> > from times to times ?
>
> 100% reproducible.
>
> > If the problem is 100% reproducible, I'd like to try other requests to
> > see if the camera stalls GET_DEF(hue)  only or all GET requests on the
> > hue control.
>
> Only happens with HUE (see test-BisonCam.c and test-output).
>
> > Could you try to read the value (VIDIOC_G_CTRL) of the hue control ?
>
> It   return  EIO   and   uvcvideo  driver   print   same  message   (see
> test-BisonCam.c and test-output).

I expected the uvcvideo driver to print a slightly different message (129 
instead of 135). I'm pretty sure it did, you might have missed that.

> > If  it doesn't  work, could  you  modify the  PU_HUE_CONTROL entry  in
> > uvc_ctrls (uvc_ctrl.c) and retest VIDIOC_QUERYCTRL ?
> >
> > Set the flags field to
> >
> > UVC_CONTROL_GET_DEF |
> > UVC_CONTROL_GET_MIN |
> > UVC_CONTROL_GET_MAX |
> > UVC_CONTROL_GET_RES |
> > UVC_CONTROL_GET_CUR |
> > UVC_CONTROL_SET_CUR |
> > UVC_CONTROL_RESTORE |
> > UVC_CONTROL_AUTO_UPDATE
> >
> > at first  and remove the  GET_DEF, GET_MIN, GET_MAX and  GET_RES flags
> > one by one, trying VIDIOC_QUERYCTRL at each step. The driver will only
> > perform the listed requests in  the GET_DEF, GET_MIN, GET_MAX, GET_RES
> > order. I'd like to know which of those work or fail.
>
> VIDIOC_QUERYCTRL  success only  if  I remove  GET_DEF, GET_MIN,  GET_MAX
> and  GET_RES flags.  In  all  other cases,  my  test  program give  same
> output as  in test-output. (Except:  if I remove UVC_CONTROL_GET* flags,
> VIDIOC_G_CTRL return EINVAL).

It seems that the camera doesn't support the hue control at all, even though 
it reports it does.

The proper way to fix this is to blacklist the hue control for your model. 
Setting the UVC_QUIRK_PRUNE_CONTROLS and modifying uvc_ctrl_prune_controls() 
should do the job. Could you please try the attached patch ?

Best regards,

Laurent Pinchart

diff -r b7cdedd8e305 linux/drivers/media/video/uvc/uvc_ctrl.c
--- a/linux/drivers/media/video/uvc/uvc_ctrl.c	Mon May 25 10:30:47 2009 -0300
+++ b/linux/drivers/media/video/uvc/uvc_ctrl.c	Thu May 28 15:59:30 2009 +0200
@@ -1374,21 +1374,19 @@
 }
 
 /*
- * Prune an entity of its bogus controls. This currently includes processing
- * unit auto controls for which no corresponding manual control is available.
- * Such auto controls make little sense if any, and are known to crash at
- * least the SiGma Micro webcam.
+ * Prune an entity of its bogus controls using a blacklist. Bogus controls
+ * are currently the ones that crash the camera or unconditionally return an
+ * error when queried.
  */
 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 {
-		u8 idx_manual;
-		u8 idx_auto;
+		struct usb_device_id id;
+		u8 index;
 	} blacklist[] = {
-		{ 2, 11 }, /* Hue */
-		{ 6, 12 }, /* White Balance Temperature */
-		{ 7, 13 }, /* White Balance Component */
+		{ { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */
+		{ { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */
 	};
 
 	u8 *controls;
@@ -1402,19 +1400,17 @@
 	size = entity->processing.bControlSize;
 
 	for (i = 0; i < ARRAY_SIZE(blacklist); ++i) {
-		if (blacklist[i].idx_auto >= 8 * size ||
-		    blacklist[i].idx_manual >= 8 * size)
+		if (!usb_match_id(dev->intf, &blacklist[i].id))
 			continue;
 
-		if (!uvc_test_bit(controls, blacklist[i].idx_auto) ||
-		     uvc_test_bit(controls, blacklist[i].idx_manual))
+		if (blacklist[i].index >= 8 * size ||
+		    !uvc_test_bit(controls, blacklist[i].index))
 			continue;
 
-		uvc_trace(UVC_TRACE_CONTROL, "Auto control %u/%u has no "
-			"matching manual control, removing it.\n", entity->id,
-			blacklist[i].idx_auto);
+		uvc_trace(UVC_TRACE_CONTROL, "%u/%u control is black listed, "
+			"removing it.\n", entity->id, blacklist[i].index);
 
-		uvc_clear_bit(controls, blacklist[i].idx_auto);
+		uvc_clear_bit(controls, blacklist[i].index);
 	}
 }
 
@@ -1445,7 +1441,7 @@
 		}
 
 		if (dev->quirks & UVC_QUIRK_PRUNE_CONTROLS)
-			uvc_ctrl_prune_entity(entity);
+			uvc_ctrl_prune_entity(dev, entity);
 
 		for (i = 0; i < bControlSize; ++i)
 			ncontrols += hweight8(bmControls[i]);
_______________________________________________
Linux-uvc-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel

Reply via email to