Re: [Bugme-new] [Bug 12301] New: Fingerprint reader doesn't respod after the first use

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 30 Dec 2008, Erik Ekman wrote:

> > Okay, this is starting to narrow things down.  Here's a kernel patch to
> > add some extra debugging information to the log.  Run the same test as
> > before (you don't need to set usbfs_snoop this time) and post the
> > resulting dmesg log.
> >
> > Alan Stern
> >
> 
> Here is the resulting dmesg of tf-tool --acquire:

The initial stuff is all normal.

...
> findintfep: 0
> checkintf: 0
> ep addr: 129: ptr: f6526f40

Through here.

> findintfep: 0
> checkintf: 0
> ep addr: 129: ptr: 00000000
> findintfep: 0
> checkintf: 0
> ep addr: 129: ptr: 00000000
> findintfep: 0
> checkintf: 0
> ep addr: 129: ptr: 00000000
> findintfep: 0
> checkintf: 0
> ep addr: 2: ptr: 00000000

This part indicates where the trouble starts.  And I believe I see the
cause of the problem; the interface gets disabled but never re-enabled.  
You can remove the earlier patch and try the patch below; it should fix
this problem.

Timo, pay attention to this: There may still be another problem lurking
in the library source code.  _libthinkfinger_usb_hello() behaves very
badly: It sends a direct Set-Config request without using
usb_set_configuration().  You should remove the entire first call to
usb_control_msg() from that function.  I know the comment says "should 
not be relevant", but the comment is wrong.

If it turns out that the Set-Config really is needed (it might indeed
be necessary for Windows systems), it shouldn't be done this way.  
Instead, usb_set_configuration() should be called from within
_libthinkfinger_usb_init(), just before usb_claim_interface().

Alan Stern



Index: 2.6.28/drivers/usb/core/usb.h
===================================================================
--- 2.6.28.orig/drivers/usb/core/usb.h
+++ 2.6.28/drivers/usb/core/usb.h
@@ -10,7 +10,9 @@ extern int usb_create_ep_files(struct de
 extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint);
 
 extern void usb_enable_endpoint(struct usb_device *dev,
-		struct usb_host_endpoint *ep);
+		struct usb_host_endpoint *ep, bool reset_toggle);
+extern void usb_enable_interface(struct usb_device *dev,
+		struct usb_interface *intf, bool reset_toggles);
 extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr);
 extern void usb_disable_interface(struct usb_device *dev,
 		struct usb_interface *intf);
Index: 2.6.28/drivers/usb/core/driver.c
===================================================================
--- 2.6.28.orig/drivers/usb/core/driver.c
+++ 2.6.28/drivers/usb/core/driver.c
@@ -279,9 +279,12 @@ static int usb_unbind_interface(struct d
 	 * altsetting means creating new endpoint device entries).
 	 * When either of these happens, defer the Set-Interface.
 	 */
-	if (intf->cur_altsetting->desc.bAlternateSetting == 0)
-		;	/* Already in altsetting 0 so skip Set-Interface */
-	else if (!error && intf->dev.power.status == DPM_ON)
+	if (intf->cur_altsetting->desc.bAlternateSetting == 0) {
+		/* Already in altsetting 0 so skip Set-Interface.
+		 * Just re-enable it without affecting the endpoint toggles.
+		 */
+		usb_enable_interface(udev, intf, false);
+	} else if (!error && intf->dev.power.status == DPM_ON)
 		usb_set_interface(udev, intf->altsetting[0].
 				desc.bInterfaceNumber, 0);
 	else
Index: 2.6.28/drivers/usb/core/message.c
===================================================================
--- 2.6.28.orig/drivers/usb/core/message.c
+++ 2.6.28/drivers/usb/core/message.c
@@ -1113,22 +1113,26 @@ void usb_disable_device(struct usb_devic
  * usb_enable_endpoint - Enable an endpoint for USB communications
  * @dev: the device whose interface is being enabled
  * @ep: the endpoint
+ * @reset_toggle: flag to set the endpoint's toggle back to 0
  *
- * Resets the endpoint toggle, and sets dev->ep_{in,out} pointers.
+ * Resets the endpoint toggle if asked, and sets dev->ep_{in,out} pointers.
  * For control endpoints, both the input and output sides are handled.
  */
-void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep)
+void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep,
+		bool reset_toggle)
 {
 	int epnum = usb_endpoint_num(&ep->desc);
 	int is_out = usb_endpoint_dir_out(&ep->desc);
 	int is_control = usb_endpoint_xfer_control(&ep->desc);
 
 	if (is_out || is_control) {
-		usb_settoggle(dev, epnum, 1, 0);
+		if (reset_toggle)
+			usb_settoggle(dev, epnum, 1, 0);
 		dev->ep_out[epnum] = ep;
 	}
 	if (!is_out || is_control) {
-		usb_settoggle(dev, epnum, 0, 0);
+		if (reset_toggle)
+			usb_settoggle(dev, epnum, 0, 0);
 		dev->ep_in[epnum] = ep;
 	}
 	ep->enabled = 1;
@@ -1138,17 +1142,18 @@ void usb_enable_endpoint(struct usb_devi
  * usb_enable_interface - Enable all the endpoints for an interface
  * @dev: the device whose interface is being enabled
  * @intf: pointer to the interface descriptor
+ * @reset_toggles: flag to set the endpoints' toggles back to 0
  *
  * Enables all the endpoints for the interface's current altsetting.
  */
-static void usb_enable_interface(struct usb_device *dev,
-				 struct usb_interface *intf)
+void usb_enable_interface(struct usb_device *dev,
+		struct usb_interface *intf, bool reset_toggles)
 {
 	struct usb_host_interface *alt = intf->cur_altsetting;
 	int i;
 
 	for (i = 0; i < alt->desc.bNumEndpoints; ++i)
-		usb_enable_endpoint(dev, &alt->endpoint[i]);
+		usb_enable_endpoint(dev, &alt->endpoint[i], reset_toggles);
 }
 
 /**
@@ -1271,7 +1276,7 @@ int usb_set_interface(struct usb_device 
 	 * during the SETUP stage - hence EP0 toggles are "don't care" here.
 	 * (Likewise, EP0 never "halts" on well designed devices.)
 	 */
-	usb_enable_interface(dev, iface);
+	usb_enable_interface(dev, iface, true);
 	if (device_is_registered(&iface->dev))
 		usb_create_sysfs_intf_files(iface);
 
@@ -1346,7 +1351,7 @@ int usb_reset_configuration(struct usb_d
 			alt = &intf->altsetting[0];
 
 		intf->cur_altsetting = alt;
-		usb_enable_interface(dev, intf);
+		usb_enable_interface(dev, intf, true);
 		if (device_is_registered(&intf->dev))
 			usb_create_sysfs_intf_files(intf);
 	}
@@ -1604,7 +1609,7 @@ free_interfaces:
 			alt = &intf->altsetting[0];
 
 		intf->cur_altsetting = alt;
-		usb_enable_interface(dev, intf);
+		usb_enable_interface(dev, intf, true);
 		intf->dev.parent = &dev->dev;
 		intf->dev.driver = NULL;
 		intf->dev.bus = &usb_bus_type;
Index: 2.6.28/drivers/usb/core/usb.c
===================================================================
--- 2.6.28.orig/drivers/usb/core/usb.c
+++ 2.6.28/drivers/usb/core/usb.c
@@ -362,7 +362,7 @@ struct usb_device *usb_alloc_dev(struct 
 	dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
 	dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;
 	/* ep0 maxpacket comes later, from device descriptor */
-	usb_enable_endpoint(dev, &dev->ep0);
+	usb_enable_endpoint(dev, &dev->ep0, true);
 	dev->can_submit = 1;
 
 	/* Save readable and stable topology id, distinguishing devices
Index: 2.6.28/drivers/usb/core/hub.c
===================================================================
--- 2.6.28.orig/drivers/usb/core/hub.c
+++ 2.6.28/drivers/usb/core/hub.c
@@ -2385,7 +2385,7 @@ void usb_ep0_reinit(struct usb_device *u
 {
 	usb_disable_endpoint(udev, 0 + USB_DIR_IN);
 	usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
-	usb_enable_endpoint(udev, &udev->ep0);
+	usb_enable_endpoint(udev, &udev->ep0, true);
 }
 EXPORT_SYMBOL_GPL(usb_ep0_reinit);
 

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux