Bug 61692

Summary: [PATCH] New driver for VFS5011 138a:0011
Product: libfprint Reporter: Arseniy Lartsev <arseniy>
Component: libfprintAssignee: libfprint-bugs
Status: RESOLVED FIXED QA Contact:
Severity: enhancement    
Priority: medium CC: acelan, anarsoul, arseniy, dieguitoll, dion, eldermarco, ian, jaminjay+fdbz, jb, jckeerthan, ladnymichal, nikoamia, roger.k.wells, tcallawa, whoopie79
Version: unspecified   
Hardware: Other   
OS: All   
See Also: https://bugs.freedesktop.org/show_bug.cgi?id=74635
Whiteboard:
i915 platform: i915 features:
Attachments: Patch (against latest git version) with driver implementation
Patch with driver implementation (suits both 0.5.0 and latest git snapshot)
Make all USB transfer asynchronous
0001-lib-Add-VFS5011-driver.patch
0001-lib-Add-VFS5011-driver.patch
0001-lib-Add-VFS5011-driver-v2.patch
powertop snapshot before and after running fprint_demo
Validity :0017 support
Validity :0017 support (v2)
0001-lib-Add-VFS5011-driver.patch

Description Arseniy Lartsev 2013-03-02 15:48:38 UTC
Created attachment 75783 [details] [review]
Patch (against latest git version) with driver implementation

So far no one said that my driver sucks, so maybe let's try to merge it.

I tried to create a proper patch, please have a look at it. I'll be happy to make any necessary changes to the patch and/or my code.
Comment 1 Vasily Khoruzhick 2013-03-19 13:29:00 UTC
Comment on attachment 75783 [details] [review]
Patch (against latest git version) with driver implementation

Review of attachment 75783 [details] [review]:
-----------------------------------------------------------------

::: libfprint/drivers/vfs5011.c
@@ +25,5 @@
> +}
> +
> +static void debugprint(const char *line)
> +{
> +#ifdef DEBUG

There's fp_dbg/fp_err/fp_whatever already. Please don't reinvent a wheel

@@ +67,5 @@
> +static int usb_send(libusb_device_handle *handle, unsigned char *data, unsigned size)
> +{
> +	int transferred = 0;
> +	int r = libusb_bulk_transfer(handle, VFS5011_OUT_ENDPOINT, data, size,
> +	                                    &transferred, VFS5011_DEFAULT_WAIT_TIMEOUT);

No synchronous transfers are allowed in driver

@@ +85,5 @@
> +static int usb_recv(libusb_device_handle *handle, unsigned endpoint, unsigned char *buf,
> +             unsigned max_bytes, int *transferred)
> +{
> +	int r = libusb_bulk_transfer(handle, endpoint, buf, max_bytes, transferred,
> +	                             VFS5011_DEFAULT_WAIT_TIMEOUT);

Same

@@ +404,5 @@
> +
> +// Rescale image to account for variable swiping speed
> +int vfs5011_rescale_image(unsigned char *image, int input_lines,
> +                          unsigned char *output, int max_output_lines)
> +{

Could you use existing scale functions?

@@ +435,5 @@
> +//  		if (! on_good_offsets && (i >= GOOD_OFFSETS_CRITERION)) {
> +//  			if (get_deviation_int(offsets + i - GOOD_OFFSETS_CRITERION, GOOD_OFFSETS_CRITERION) <
> +//  			    GOOD_OFFSETS_THRESHOLD)
> +//  				on_good_offsets = 1;
> +//  		}

Please drop commented out blocks of code

@@ +876,5 @@
> +struct fp_img_driver vfs5011_driver =
> +{
> +	.driver =
> +	{
> +		.id = 12,

Please don't use hardcoded ID anymore, define your own in driver_ids.h and use that one

@@ +886,5 @@
> +
> +	.flags = 0,
> +	.img_width = VFS5011_IMAGE_WIDTH,
> +	.img_height = -1,
> +	.bz3_threshold = 20,

Why threshold is so low?
Comment 2 Arseniy Lartsev 2013-03-23 11:32:39 UTC
> Why threshold is so low?

I wrote an e-mail to the mailing list explaining the situation in detail back in December: http://lists.freedesktop.org/archives/fprint/2012-December/000376.html

> No synchronous transfers are allowed in driver

The fact that you didn't tell this before is a bit surprising given that the code has been available for more than a month now.

Switching to asynchronous transfers is a major change that would require some effort. And let me put it frankly: your reply does not exactly motivate me to do that.
Comment 3 Vasily Khoruzhick 2013-03-26 12:05:25 UTC
(In reply to comment #2)
> > Why threshold is so low?
> 
> I wrote an e-mail to the mailing list explaining the situation in detail
> back in December:
> http://lists.freedesktop.org/archives/fprint/2012-December/000376.html

OK

> > No synchronous transfers are allowed in driver
> 
> The fact that you didn't tell this before is a bit surprising given that the
> code has been available for more than a month now.

You didn't ask for assistance in driver development, and I didn't pay enough attention to maillist for last months. 
 
> Switching to asynchronous transfers is a major change that would require
> some effort. And let me put it frankly: your reply does not exactly motivate
> me to do that.

Well, I'll try to explain you why it's an requirement:
see libfprint/libfprint/poll.c quote:

 * libfprint does not create internal library threads and hence can only
 * execute when your application is calling a libfprint function. However,
 * libfprint often has work to be do, such as handling of completed USB
 * transfers, and processing of timeouts required in order for the library
 * to function. Therefore it is essential that your own application must
 * regularly "phone into" libfprint so that libfprint can handle any pending
 * events.
 *
 * The function you must call is fp_handle_events() or a variant of it. This
 * function will handle any pending events, and it is from this context that
 * all asynchronous event callbacks from the library will occur. You can view
 * this function as a kind of iteration function.

Usually application adds libfprint FDs to its poll/select call and calls fp_handle_events_timeout() on any event for those FDs. That basically means that libfprint runs in main loop, same loop in which UI runs. So it's not a good idea to use synchronous libusb calls, because they can take >1s to complete, so it can "freeze" UI for 1s.

Anyway, it's not complicated to convert your driver to asynchronous model. Join #fprint@irc.freenode.org IRC channel and I'll try to help you
Comment 4 Arseniy Lartsev 2013-04-01 18:35:16 UTC
Marco Hoffmeier reports that 138a:0018 also works with this driver: https://github.com/ars3niy/fprint_vfs5011/pull/1
Comment 5 Arseniy Lartsev 2013-04-07 18:48:57 UTC
Created attachment 77561 [details] [review]
Patch with driver implementation (suits both 0.5.0 and latest git snapshot)

I've updated the driver, partially switched to asynchronous transfers for device initialization together with some code cleanup.

There's still a short initialization sequence that has to be done before capturing, which is done synchronously.

If I understand correctly, an application using libfprint assumes that the device is ready for capturing the image right after fp_async_enroll/verify/identify_start returns.

So that if pre-capture initialization is done asynchronously, the user will be asked to deploy his finger right away, before the initalization is completed. And if there is a delay during initialization and the user is quick enough, hse will actually swipe the finger before the device is initialized.

I'm not sure that this is better than UI freeze, that's why I left synchronous transfers there. Some kind of intermediate "now you can swipe your finger" callback could seem a better solution, but that's a lot of work.

In any case, I'm also attaching a patch to make all initialization asynchronous.
Comment 6 Arseniy Lartsev 2013-04-07 18:49:55 UTC
Created attachment 77562 [details]
Make all USB transfer asynchronous
Comment 7 Bastien Nocera 2013-04-24 15:19:28 UTC
Vasily, can you review it?
Comment 8 Vasily Khoruzhick 2013-04-24 15:40:01 UTC
Comment on attachment 77561 [details] [review]
Patch with driver implementation (suits both 0.5.0 and latest git snapshot)

Review of attachment 77561 [details] [review]:
-----------------------------------------------------------------

::: libfprint/drivers/vfs5011.c
@@ +1,1 @@
> +#include <stdio.h>

Please add a copyright header to vfs5011.c and vfs5011.h, you can borrow one from any driver

@@ +10,5 @@
> +#include "driver_ids.h"
> +
> +#include "vfs5011_proto.h"
> +
> +static char *get_debugfiles_path(void)

Please use fp_dbg macro, don't introduce driver-specific debug stuff.

@@ +147,5 @@
> +		fpi_ssm_mark_aborted(ssm, -EINVAL);
> +		goto out;
> +	}
> +	
> +	struct usb_action *action = &data->actions[ssm->cur_state];

Please don't mix declarations with code

@@ +189,5 @@
> +		fpi_ssm_mark_aborted(ssm, -EINVAL);
> +		return;
> +	}
> +	
> +	struct usb_action *action = &data->actions[ssm->cur_state];

Same as above

@@ +300,5 @@
> +}
> +
> +//====================== utils =======================
> +
> +#if VFS5011_LINE_SIZE > INT_MAX/(256*256)

It would be better to perform this test somewhere in configure.ac, I don't think that it's a good
idea to emit compilation error after configure script succeed

@@ +365,5 @@
> +
> +static void median_filter(int *data, int size, int filtersize)
> +{
> +	int i;
> +	int *result = (int *)malloc(size*sizeof(int));

Please use g_malloc from glib, or implement error handling, I prefer first way.

@@ +508,5 @@
> +};
> +
> +enum {
> +	DEV_OPEN_START,
> +// 	DEV_OPEN_INIT_COMPLETE,

No dead code please, even a single line

@@ +585,5 @@
> +	return 0;
> +}
> +
> +void save_pgm(const char *filename, unsigned char *data, int width, int height)
> +{

Remove all debug stuff that was used during development, I don't think we need it

@@ +984,5 @@
> +		return r;
> +	}
> +	
> +	struct fpi_ssm *ssm;
> +	ssm = fpi_ssm_new(dev->dev, open_loop, DEV_OPEN_NUM_STATES);

Don't perform device initialization in dev_open, right place to do init is dev_activate.
Please note that image capture loop should not finish until explicit dev_deactivate call.

Typical loop looks like this:
(1) device init -> (2) start finger detect -> (3) finger detected -> (4) image capture -> (5) send image to lib -> (6) jump to (2)
Comment 9 Vasily Khoruzhick 2013-04-24 15:43:08 UTC
Arseniy, could you catch me in IRC, so we can discuss all driver details and avoid another submit/review round?
Comment 10 Arseniy Lartsev 2013-04-24 17:43:21 UTC
> Don't perform device initialization in dev_open, right place to do init is
> dev_activate.

Right now putting it in dev_open is the best choice. Doing it in dev_activate would cause a problem which I mentioned in comment #5 (any thought on this, by the way?) – only much worse since this initialization takes a second or two.

Also, AFAIR windows does this initialization immediately when I plug in the device into USB port. (Thin is embedded sensor in a laptop but one can still "plug it in" in VirtualBox).
Comment 11 Vasily Khoruzhick 2013-04-24 18:31:41 UTC
(In reply to comment #10)
> > Don't perform device initialization in dev_open, right place to do init is
> > dev_activate.
> 
> Right now putting it in dev_open is the best choice. Doing it in
> dev_activate would cause a problem which I mentioned in comment #5 (any
> thought on this, by the way?) – only much worse since this initialization
> takes a second or two.

Could you implement some check too see if initialization was completed earlier? Maybe some register value changes after init, etc? Library doesn't expect any device init in dev_open, so it's not a good idea.

Anyway, I don't like workarounds, clean solution is always better. Maybe we need to add another state into fp_imgdev_state, something like IMGDEV_STATE_INITIALIZING, right before AWAIT_FINGER_ON, so libfprint user will be aware when it's necessary to show "scan your finger" message. 

> Also, AFAIR windows does this initialization immediately when I plug in the
> device into USB port. (Thin is embedded sensor in a laptop but one can still
> "plug it in" in VirtualBox).

That's OK, but unfortunately libfprint driver is "stateless", i.e. it can't preserve any data between fp scan sessions, so we can't mimic _that_ windows behavior
Comment 12 Arseniy Lartsev 2013-04-24 19:21:35 UTC
> Could you implement some check too see if initialization was completed
> earlier? Maybe some register value changes after init, etc? 

Unfortunately I don't know how to query registers on this device. During initialization I'm sending some blobs and occasionally read something back, but I have no idea what it all means :-/

But it does not harm to do this initialization many times. It would not harm to do it every time dev_activate is called – the hardware seems to be fine with that.

The only problem is how to handle the delay which happens during this initialization properly, so that it won't disappoint the user.

> Library doesn't expect any device init in dev_open, so it's not a good idea.

But is there some technical reason why it should not be there right now? I mean, can this (doing device initialization in dev_open) break things, cause incorrect behavior in some situations?

By the way, I also have an unrelated question. If an application opens the device and then enrolls/verifies/identifies fingers a few times, will dev_activate be called every time when the finger needs to be scanned, or just once?

Sorry, I cannot chat now, I don't have more time today.
Comment 13 Vasily Khoruzhick 2013-04-24 19:39:24 UTC
(In reply to comment #12)
> > Could you implement some check too see if initialization was completed
> > earlier? Maybe some register value changes after init, etc? 
> 
> Unfortunately I don't know how to query registers on this device. During
> initialization I'm sending some blobs and occasionally read something back,
> but I have no idea what it all means :-/

Maybe it makes sense to reverse-engineer protocol a bit? I'll take a look at it probably this weekend

> But it does not harm to do this initialization many times. It would not harm
> to do it every time dev_activate is called – the hardware seems to be fine
> with that.
> 
> The only problem is how to handle the delay which happens during this
> initialization properly, so that it won't disappoint the user.
>
> 
> > Library doesn't expect any device init in dev_open, so it's not a good idea.
> 
> But is there some technical reason why it should not be there right now? I
> mean, can this (doing device initialization in dev_open) break things, cause
> incorrect behavior in some situations?

Yes, there's no synchronization points for dev_open, so you can't use async transfers in it, and synchronous transfers are not allowed in libfprint. 
 
> By the way, I also have an unrelated question. If an application opens the
> device and then enrolls/verifies/identifies fingers a few times, will
> dev_activate be called every time when the finger needs to be scanned, or
> just once?

Depends on libfprint internal usage. Current master calls dev_activate for each scan, but I've a pending commit that changes enroll routine to perform 5 scans, and it uses single dev_activate for 5 scans.
 
> Sorry, I cannot chat now, I don't have more time today.

OK
Comment 14 Arseniy Lartsev 2013-04-25 19:21:06 UTC
> there's no synchronization points for dev_open, so you can't use async
> transfers in it, and synchronous transfers are not allowed in libfprint.

But it works for me with async transfers in dev_open :-/ Both fprint_demo that uses asynchronous API and command-line examples using synchronous API work fine.

You gave a theoretical explanation why it's bad, but I'm not a computer programmer, I'm a physicist, and I don't understand this theory. Can you please also give a practical explanation, i.e. what exactly will break and in which situation?

As a side note, vfs301 driver, which just happened to be the one I used as an example, has synchronous transfers :p (and even separate debug system).
Comment 15 Vasily Khoruzhick 2013-04-25 19:35:05 UTC
(In reply to comment #14)
> > there's no synchronization points for dev_open, so you can't use async
> > transfers in it, and synchronous transfers are not allowed in libfprint.
> 
> But it works for me with async transfers in dev_open :-/ Both fprint_demo
> that uses asynchronous API and command-line examples using synchronous API
> work fine.
> 
> You gave a theoretical explanation why it's bad, but I'm not a computer
> programmer, I'm a physicist, and I don't understand this theory. Can you
> please also give a practical explanation, i.e. what exactly will break and
> in which situation?

Just a simple race:

app calls dev_open -> init async transfer starts -> app calls dev_activate -> another async transfer starts -> it breaks initialization (e.g. response from init is interpreted as response from activate) -> driver failure

> As a side note, vfs301 driver, which just happened to be the one I used as
> an example, has synchronous transfers :p (and even separate debug system).

I didn't review vfs301 driver, so I'm not responsible for its inclusion :)
Comment 16 Bastien Nocera 2013-04-25 20:00:37 UTC
(In reply to comment #15)
> (In reply to comment #14)
<snip>
> > As a side note, vfs301 driver, which just happened to be the one I used as
> > an example, has synchronous transfers :p (and even separate debug system).
> 
> I didn't review vfs301 driver, so I'm not responsible for its inclusion :)

I'm probably the one who reviewed it. It worked (at least the original author claimed it did), and I'm really not familiar with the libfprint drivers, seeing as I mostly worked on fprintd and the integration with the rest of the user-space.
Comment 17 Arseniy Lartsev 2013-04-30 20:03:37 UTC
> app calls dev_open -> init async transfer starts -> app calls dev_activate
> -> another async transfer starts -> it breaks initialization

Hang on. Don't you need a pointer to fp_dev to activate a device? And you only get this pointer from fp_dev_open_cb callback, which callback is invoked after all async transfers in dev_open are completed. Am I missing something?
Comment 18 AceLan Kao 2013-07-10 08:20:53 UTC
*poke*
Could you please speed up the review process?
There are many users suffered from this.
Thanks.
Comment 19 Vasily Khoruzhick 2013-07-10 08:59:56 UTC
(In reply to comment #18)
> *poke*
> Could you please speed up the review process?
> There are many users suffered from this.
> Thanks.

It's already reviewed, and there were no new version to review.
I won't accept driver with synchronous transfers.
Comment 20 AceLan Kao 2013-07-10 09:29:09 UTC
Could you advice us which driver is good for reference, so that Arseniy could follow that one to rewrite it.
Or if Arseniy is unavailable to do it now, I can give it a try.
Thanks.
Comment 21 Arseniy Lartsev 2013-07-10 09:39:19 UTC
(In reply to comment #20)
> Could you advice us which driver is good for reference, so that Arseniy
> could follow that one to rewrite it.

There's no need to rewrite my driver, just minor changes here and there.

> Or if Arseniy is unavailable to do it now, I can give it a try.

I'm generally available, but Vasily has been somewhat impolite to me. Never answered my question in comment #17, for example. That's why I'm not putting too much effort into speeding up the process, simply because it's not exactly fun.

There is, however, fully asynchronous version of the driver: https://bugs.freedesktop.org/attachment.cgi?id=77562.
Comment 22 Vasily Khoruzhick 2013-07-10 10:07:47 UTC
(In reply to comment #21)
> (In reply to comment #20)
> > Could you advice us which driver is good for reference, so that Arseniy
> > could follow that one to rewrite it.
> 
> There's no need to rewrite my driver, just minor changes here and there.
> 
> > Or if Arseniy is unavailable to do it now, I can give it a try.
> 
> I'm generally available, but Vasily has been somewhat impolite to me.

I'm very sorry if I was impolite to you, it wasn't intended. I'm just a bit tired of arguing why drivers MUST be asynchronous. I'll write a libfprint driver guideline when I get some spare time

> Never
> answered my question in comment #17, for example.

Missed that one. Anyway:

> Hang on. Don't you need a pointer to fp_dev to activate a device? And you only > get this pointer from fp_dev_open_cb callback, which callback is invoked after > all async transfers in dev_open are completed. Am I missing something?

See img_dev_open(), it doesn't wait for any async xfers from dev_open(), only if you explicitly wait for async transfers to complete in dev_open()

> That's why I'm not putting
> too much effort into speeding up the process, simply because it's not
> exactly fun.

Heh

> There is, however, fully asynchronous version of the driver:
> https://bugs.freedesktop.org/attachment.cgi?id=77562.

OK, will take a look tonight. Could you squash 2 patches into single meanwhile? Thanks!

P.S. You still can catch me in IRC for faster communication...
Comment 23 AceLan Kao 2013-07-11 03:52:33 UTC
Please allow me to do the boring job.
I refine the code by removing the tailing space, cutting off at 80 chars, moving the open brace, and removing the C99 // comments.
Hoping this will make the process more smoothly.
Comment 24 AceLan Kao 2013-07-11 03:53:48 UTC
Created attachment 82310 [details] [review]
0001-lib-Add-VFS5011-driver.patch
Comment 25 Vasily Khoruzhick 2013-07-11 10:01:28 UTC
Comment on attachment 82310 [details] [review]
0001-lib-Add-VFS5011-driver.patch

Review of attachment 82310 [details] [review]:
-----------------------------------------------------------------

::: libfprint/drivers/vfs5011.c
@@ +33,5 @@
> +	}
> +	fp_dbg(s);
> +#endif
> +}
> +

Please drop all debugging stuff from driver. Only debug logs via fp_dbg are allowed.

@@ +321,5 @@
> +static void median_filter(int *data, int size, int filtersize)
> +{
> +	int i;
> +	int *result = (int *)malloc(size*sizeof(int));
> +	int *sortbuf = (int *)malloc(filtersize*sizeof(int));

Please use g_malloc or g_malloc0 here.

@@ +329,5 @@
> +		if (i1 < 0)
> +			i1 = 0;
> +		if (i2 >= size)
> +			i2 = size-1;
> +		memmove(sortbuf, data+i1, (i2-i1+1)*sizeof(int));

g_memmove()

@@ +330,5 @@
> +			i1 = 0;
> +		if (i2 >= size)
> +			i2 = size-1;
> +		memmove(sortbuf, data+i1, (i2-i1+1)*sizeof(int));
> +		qsort(sortbuf, i2-i1+1, sizeof(int), cmpint);

I wonder if there's glib wrapper for that one...

@@ +364,5 @@
> +	};
> +	int i;
> +	float y = 0.0;
> +	int line_ind = 0;
> +	int *offsets = (int *)malloc(input_lines * sizeof(int));

g_malloc()

@@ +372,5 @@
> +
> +	if (debugpath != NULL) {
> +		sprintf(name, "%s/offsets%d.dat", debugpath, (int)time(NULL));
> +		debugfile = fopen(name, "wb");
> +	}

Drop debug stuff except logs

@@ +945,5 @@
> +			array_n_elements(vfs5011_initialization);
> +		data->init_sequence.actions = vfs5011_initialization;
> +		data->init_sequence.device = dev;
> +		data->init_sequence.receive_buf =
> +			malloc(VFS5011_RECEIVE_BUF_SIZE);

g_malloc()

@@ +989,5 @@
> +	int r = libusb_reset_device(dev->udev);
> +	if (r != 0) {
> +		fp_err("Failed to reset the device");
> +		return r;
> +	}

Is it necessary? Btw, doc says that handle may be invalid after reset, and you're reusing same handle later.

@@ +1000,5 @@
> +
> +	struct fpi_ssm *ssm;
> +	ssm = fpi_ssm_new(dev->dev, open_loop, DEV_OPEN_NUM_STATES);
> +	ssm->priv = dev;
> +	fpi_ssm_start(ssm, open_loop_complete);

And no one waits for this ssm (and async USB reqs) to complete here. It's a race condition I've described earlier. Please move device initialization into dev_activate().

@@ +1035,5 @@
> +}
> +
> +static void dev_deactivate(struct fp_img_dev *dev)
> +{
> +	fpi_imgdev_deactivate_complete(dev);

How do you ensure that _all_ transfers are completed now? fpi_imgdev_deactivate_complete should be called only after deactivation has been completed. For this driver "cancel" button in fprint_demo won't work.
Comment 26 Vasily Khoruzhick 2013-07-11 10:04:14 UTC
Btw, I feel like not all issues from previous patch were fixed
Comment 27 Bastien Nocera 2013-07-11 10:13:35 UTC
(In reply to comment #25)
> @@ +330,5 @@
> > +			i1 = 0;
> > +		if (i2 >= size)
> > +			i2 = size-1;
> > +		memmove(sortbuf, data+i1, (i2-i1+1)*sizeof(int));
> > +		qsort(sortbuf, i2-i1+1, sizeof(int), cmpint);
> 
> I wonder if there's glib wrapper for that one...

https://developer.gnome.org/glib/2.34/glib-Miscellaneous-Utility-Functions.html#g-qsort-with-data

Might not be necessary to use the GLib wrapper.
Comment 28 AceLan Kao 2013-07-19 03:55:15 UTC
Sorry for reply late, I was on vacation, I'll try to revise those part of code soon.
Comment 29 Vasily Khoruzhick 2013-07-19 05:49:35 UTC
(In reply to comment #28)
> Sorry for reply late, I was on vacation, I'll try to revise those part of
> code soon.

No pb, I was busy as well :)
Comment 30 AceLan Kao 2013-08-06 08:15:23 UTC
Created attachment 83699 [details] [review]
0001-lib-Add-VFS5011-driver.patch

Sorry to take so long to resend the patch.

@@ +1000,5 @@
>> +
>> +	struct fpi_ssm *ssm;
>> +	ssm = fpi_ssm_new(dev->dev, open_loop, DEV_OPEN_NUM_STATES);
>> +	ssm->priv = dev;
>> +	fpi_ssm_start(ssm, open_loop_complete);
>
>And no one waits for this ssm (and async USB reqs) to complete here. It's a race >condition I've described earlier. Please move device initialization into >dev_activate().
The code is required and I can imagine the race condition you mentioned, but the fingerprint device won't work if move the code to dev_activate() function.
So, I add a check in dev_activate() function to make sure open_loop_complete() have finished to continue.

And you had mentioned that do we need to do reset in dev_open()
r = libusb_reset_device(dev->udev);
        if (r != 0) {
                fp_err("Failed to reset the device");
                return r;
        }
I checked if I removed the code, the device doesn't work.

I'm learning libfprint by modifying the code, so please give me more explicit advise, so that I can know how to fix it.
Thanks.
Comment 31 Vasily Khoruzhick 2013-08-06 08:21:52 UTC
(In reply to comment #30)
> Created attachment 83699 [details] [review] [review]
> 0001-lib-Add-VFS5011-driver.patch
> 
> Sorry to take so long to resend the patch.
> 
> @@ +1000,5 @@
> >> +
> >> +	struct fpi_ssm *ssm;
> >> +	ssm = fpi_ssm_new(dev->dev, open_loop, DEV_OPEN_NUM_STATES);
> >> +	ssm->priv = dev;
> >> +	fpi_ssm_start(ssm, open_loop_complete);
> >
> >And no one waits for this ssm (and async USB reqs) to complete here. It's a race >condition I've described earlier. Please move device initialization into >dev_activate().

> The code is required and I can imagine the race condition you mentioned, but
> the fingerprint device won't work if move the code to dev_activate()
> function.

Because you need to wait for completion of these transfers, but probably you don't.

> So, I add a check in dev_activate() function to make sure
> open_loop_complete() have finished to continue.

Please, no workarounds, let's fix an issue instead.

> And you had mentioned that do we need to do reset in dev_open()
> r = libusb_reset_device(dev->udev);
>         if (r != 0) {
>                 fp_err("Failed to reset the device");
>                 return r;
>         }
> I checked if I removed the code, the device doesn't work.

I guess it doesn't work on second time, because there's no proper deinit sequence and device is still in active state.

> I'm learning libfprint by modifying the code, so please give me more
> explicit advise, so that I can know how to fix it.
> Thanks.

Take a look at other drivers, almost all for AuthenTec devices are pretty simple. Try to catch me on IRC (#fprint@irc.freenode.net) if you have further questions.
Comment 32 Johannes Becker 2013-09-08 14:17:03 UTC
Really looking forward to see this Patch included. Thanks for the hard work to all involved!
Comment 33 AceLan Kao 2013-11-05 08:47:23 UTC
Sorry to take so long to re-submit the patch,
I'm not familiar with the lib, so takes some time to study it.

For your questions.
1. Because you need to wait for completion of these transfers, but probably you don't.
Actually, we don't have to wait.
When open the device, it won't continue to next state
if fpi_imgdev_open_complete() is not be called.
And we call it at open_loop_complete(), so that makes sure the transfers are all done. There is no race condition.

2. Please, no workarounds, let's fix an issue instead.
Okay, I removed them.
And this issue is not exist as explanation above.

3. I guess it doesn't work on second time, because there's no proper deinit sequence and device is still in active state.
I don't know the deinit commands.
Arseniy, please give me some advice if you know how to get the deinit commands.
BTW, since we don't have the deinit commands, so we call libusb_reset_device() every time when we open the device.
That will probably reset the device and then it can be init again.
Comment 34 AceLan Kao 2013-11-05 08:48:12 UTC
Created attachment 88670 [details] [review]
0001-lib-Add-VFS5011-driver-v2.patch
Comment 35 Vasily Khoruzhick 2013-11-05 09:04:41 UTC
(In reply to comment #33)
> Sorry to take so long to re-submit the patch,
> I'm not familiar with the lib, so takes some time to study it.
> 
> For your questions.
> 1. Because you need to wait for completion of these transfers, but probably
> you don't.
> Actually, we don't have to wait.
> When open the device, it won't continue to next state
> if fpi_imgdev_open_complete() is not be called.
> And we call it at open_loop_complete(), so that makes sure the transfers are
> all done. There is no race condition.

OK, you're right

> 2. Please, no workarounds, let's fix an issue instead.
> Okay, I removed them.
> And this issue is not exist as explanation above.

OK

> 3. I guess it doesn't work on second time, because there's no proper deinit
> sequence and device is still in active state.
> I don't know the deinit commands.
> Arseniy, please give me some advice if you know how to get the deinit
> commands.
> BTW, since we don't have the deinit commands, so we call
> libusb_reset_device() every time when we open the device.
> That will probably reset the device and then it can be init again.

Anyway, I'm OK for libusb_reset_device() here for now, but only if someone will continue to investigate how to deinit device properly.

Out of curiosity, is this device available as a standalone USB device?
Comment 36 AceLan Kao 2013-11-05 09:14:11 UTC
I'll write "Validity Sensors" an email to see if they can provide us the commands.
And I don't know if there is a standalone USB drive with this chip. There is no information from their website.
http://www.validityinc.com/index.php
Comment 37 AceLan Kao 2013-11-11 08:40:41 UTC
I don't get any reply from Validity Sensors for a whole week.
So, I think this is probably the best we can do for now.
Comment 38 Vasily Khoruzhick 2013-11-11 08:53:43 UTC
(In reply to comment #37)
> I don't get any reply from Validity Sensors for a whole week.
> So, I think this is probably the best we can do for now.

Could you also estimate power consumption (via powertop) before first use of the fingerprint scanner (i.e. after fresh boot) and after first use? I'm a bit worrying that since scanner is not stopped properly it'll consume more power.
Comment 39 AceLan Kao 2013-11-12 02:47:34 UTC
Created attachment 89064 [details]
powertop snapshot before and after running fprint_demo

I took 4 snapshots of powertop.
1. Before running fprint_demo
2. After running fprint_demo and do scan and verify fingerprint
3. Reboot my laptop and remove all USB devices and then do powertop
4. After running fprint_demo and do verify fingerprint
Looks good to me, no visible power loss.
Comment 40 Keerthan Jaic 2014-01-05 11:16:06 UTC
Based on the windows driver readme here: http://download.lenovo.com/ibmdl/pub/pc/pccbbs/mobiles/lz4xr3a2.txt , I am inclined to beleive this patch will work for PIDs 0015 and 0017 too.

I should receive my T440p which has a 138a:0017 Validity Sensors fingerprint reader in a couple of weeks, I will confirm then.
Comment 41 Nikolay Amiantov 2014-01-13 00:05:45 UTC
Created attachment 91917 [details] [review]
Validity :0017 support

This patch is indeed working for :0017 Validity sensor, I've attached a small patch which enables its support.
Comment 42 mail2ghost 2014-01-21 14:29:18 UTC
(In reply to comment #41)
> Created attachment 91917 [details] [review] [review]
> Validity :0017 support
> 
> This patch is indeed working for :0017 Validity sensor, I've attached a
> small patch which enables its support.

Confirming that the patch for :0017 is working on my T440 with no issues so far.
Comment 43 aureli 2014-03-13 15:01:23 UTC
What is chance to include this path in next release?
Comment 44 Vasily Khoruzhick 2014-03-13 15:49:26 UTC
(In reply to comment #43)
> What is chance to include this path in next release?

It'll be included. I still need to finish several features and a single driver for a next release.
Comment 45 aureli 2014-03-13 16:16:27 UTC
(In reply to comment #44)
> (In reply to comment #43)
> > What is chance to include this path in next release?
> 
> It'll be included. I still need to finish several features and a single
> driver for a next release.

Thank you for reply. :) You save my day.
Comment 46 Whoopie 2014-04-15 07:35:16 UTC
*** Bug 74635 has been marked as a duplicate of this bug. ***
Comment 47 Nikolay Amiantov 2014-05-11 17:37:55 UTC
I use this driver and I have run into bug when sudo with pam_fprintd cannot be killed with ^C or anything besides SIGKILL when fingerprint is awaited. I can't check this for any driver besides this one, but I suspect that this is driver's issue.
Comment 48 Nikolay Amiantov 2014-05-11 17:45:27 UTC
Also, when I get "Swipe your finger again", the reader is shutted down. It doesn't react to my finger until "Verification timed out" is printed. After that, until fprintd dies (which stays running for some time), PAM module does not work.
Comment 49 Nikolay Amiantov 2014-05-12 00:43:04 UTC
Created attachment 98874 [details] [review]
Validity :0017 support (v2)

Removed unnecessary .rules file patching.
Comment 50 Whoopie 2014-07-05 08:43:12 UTC
I can't use the driver with Ubuntu 14.04.

One of the 3 following things happens:
1. fprintd-enroll segfaults.
2. The message "Enroll result: enroll-completed" is shown, but there're no prints under ~/.fprint/prints.
3. I get the error message:
   Enroll result: enroll-unknown-error
   VerifyStop failed: Message did not receive a reply (timeout by message bus)
Comment 51 AceLan Kao 2014-07-07 03:41:20 UTC
Whoopie,
The libfprint doesn't release new version yet.
If you would like to try it on Ubuntu 14.04, you can try the package I built.
http://people.ubuntu.com/~acelan/libfprint/
Comment 52 Whoopie 2014-07-07 05:58:05 UTC
AceLan,

I patched libfprint git with the attached patch from this bugreport. Even with your compiled version, I have the same results as described above.
Comment 53 Whoopie 2014-10-01 11:48:21 UTC
The syslog shows:

Oct  1 13:47:29 v131 kernel: [212177.755988] usb 2-1.3: reset full-speed USB device number 3 using ehci-pci
Oct  1 13:47:31 v131 kernel: [212179.490094] traps: fprintd[20034] trap int3 ip:7f3c9bb5dc13 sp:7fff06996f70 error:0
Comment 54 Michael Scherer 2014-10-26 12:43:37 UTC
I tried the git version ( 35e356f62 ) and the 2 patchs on a RHEL 7 with a t440s, and it work fine. that work fine, no segfault on my side with fprintd-enroll and verify.
Comment 55 Michael Scherer 2014-10-26 12:53:42 UTC
Ok, spoke too fast, it always say "no match"
Comment 56 Michael Scherer 2014-10-26 14:44:48 UTC
So, testing with others people fingers, the problem is the speed of sliding the finger. So it work fine for me, provided I do slide more slowly.
Comment 57 Vasily Khoruzhick 2014-12-18 18:14:39 UTC
Created attachment 110999 [details] [review]
0001-lib-Add-VFS5011-driver.patch

Please test if this version works for you.
Comment 58 Whoopie 2014-12-18 20:09:24 UTC
With the lastest version, I get the error message:
   Enroll result: enroll-unknown-error
   VerifyStop failed: Message did not receive a reply (timeout by message bus)

The syslog shows:
Dec 18 21:07:52 v131 kernel: [26042.424432] usb 2-1.3: reset full-speed USB device number 3 using ehci-pci
Dec 18 21:07:54 v131 kernel: [26044.143346] traps: fprintd[20976] trap int3 ip:7f1ca1119c13 sp:7fffbcfcecd0 error:0
Comment 59 Vasily Khoruzhick 2014-12-18 20:17:03 UTC
(In reply to Whoopie from comment #58)
> With the lastest version, I get the error message:
>    Enroll result: enroll-unknown-error
>    VerifyStop failed: Message did not receive a reply (timeout by message
> bus)
> 
> The syslog shows:
> Dec 18 21:07:52 v131 kernel: [26042.424432] usb 2-1.3: reset full-speed USB
> device number 3 using ehci-pci
> Dec 18 21:07:54 v131 kernel: [26044.143346] traps: fprintd[20976] trap int3
> ip:7f1ca1119c13 sp:7fffbcfcecd0 error:0

Well, I've only replaced free() calls with g_free() and time() with g_get_real_time(). AceLan, could you check what's wrong?
Comment 60 AceLan Kao 2014-12-22 08:28:17 UTC
Hi, I'm on vacation until EOY.
I'll see what I can do when I'm available.
Comment 61 Whoopie 2015-01-01 11:11:34 UTC
Got it working with the change mentioned in http://article.gmane.org/gmane.linux.fprint/2490 (removing the line 770
in file libfprint/drivers/vfs5011.c --"RECV(VFS5011_IN_ENDPOINT_CTRL2,
8)").
Comment 62 Diego López León 2015-01-26 12:21:14 UTC
I can confirm this patch works fine applied on top of libfprint_0.5.1-1 from the Debian Archives. I just _debianized_ it for ease applying at https://gist.github.com/diega/2e1d2dbbbb7700480de0 (I though it was better to upload there instead of taint this bug report with another file)
Comment 63 Vasily Khoruzhick 2015-01-26 12:34:02 UTC
(In reply to Diego López León from comment #62)
> I can confirm this patch works fine applied on top of libfprint_0.5.1-1 from
> the Debian Archives. I just _debianized_ it for ease applying at
> https://gist.github.com/diega/2e1d2dbbbb7700480de0 (I though it was better
> to upload there instead of taint this bug report with another file)

Diego, please test it against git master. There were some changes since 0.5.1, such as several scans during enrollment for all imaging scanners.
Comment 64 Diego López León 2015-01-26 18:45:15 UTC
Vasily,
Thanks for your recommendation, I just tested it against current master and it seems to work fine.

I can even notice a better matching rate comparing with 5.1. I don't know if the differences between 5.1 and master justifies this behavior or it is just my impression, but it worth to mention.

Again, the patch for applying it on top of a debian build for master@35e356f is in https://gist.github.com/diega/3b8a8cc5f5588076fd39
Comment 65 Vasily Khoruzhick 2015-01-26 18:46:28 UTC
(In reply to Diego López León from comment #64)
> Vasily,
> Thanks for your recommendation, I just tested it against current master and
> it seems to work fine.
> 
> I can even notice a better matching rate comparing with 5.1. I don't know if
> the differences between 5.1 and master justifies this behavior or it is just
> my impression, but it worth to mention.
> 
> Again, the patch for applying it on top of a debian build for master@35e356f
> is in https://gist.github.com/diega/3b8a8cc5f5588076fd39

Thanks for testing!
Comment 66 Bastien Nocera 2015-01-26 19:06:01 UTC
Vasily, let me know when you've merged/reviewed, and I'll do a release.
I'm a bit lost on the status :)
Comment 67 Vasily Khoruzhick 2015-01-26 19:22:40 UTC
(In reply to Bastien Nocera from comment #66)
> Vasily, let me know when you've merged/reviewed, and I'll do a release.
> I'm a bit lost on the status :)

Sure.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.