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, Dec 30, 2008 at 8:09 PM, Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote:
> 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);
>
>
>


Works for me, both with tf-tool --acquire and pam_fprint_enroll, both
which scan 3 swipes.

/Erik
--
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