Saturday, September 22, 2018

Better CCID suport in FreeBSD

My CCID driver had some problems when used on a FreeBSD system. I used FreeBSD 10.4 (stable) but the problem should also be present in more recent or older versions of FreeBSD.

The problem

The problem was that the removal a USB reader was not reported to the PC/SC application. The removal was detected by the PC/SC daemon (pcscd) but something failed in the removal process.

The same problem also prevented the PC/SC daemon to exit correctly when stopped using the keyboard combination Control+C.

After some debugging the cause of the problem was identified. When the CCID driver is stopped (because a reader is removed or pcscd is exited) the driver tries to cancel all the unfinished USB transfers. When the reader provides an interrupt end point to notify card events the CCID driver initiates a USB transfer reading from this end point with a long timeout (10 minutes).

libUSB issues

I reported the problem using the FreeBSD bug report tool:

I worked with Hans Petter Selasky (libUSB co-maintainer) to fix the problems. I would like to thank Hans Petter for his availability. That is great to have problems fixed in just a few days.

libusb_cancel_transfer() does NOT cancel a transfer after the USB device is removed

Bug reported at: libusb_cancel_transfer() does NOT cancel a transfer after the USB device is removed

Patch applied in FreeBSD: Revision 338616

Debug is not working correctly

Use of DPRINTF() to print debug message was not working in some functions.

Bug reported at: libusb DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "sync I/O done"); does not work in libusb10_do_transfer_cb()

Patch applied in FreeBSD: Revision 338679

Bogus management after a device removal

Bug reported at: libusb_bulk_transfer() does not fail (with LIBUSB_ERROR_NO_DEVICE) if the device is not more present

This bug is solved by the patch also solving the libusb_cancel_transfer() problem.

Fixed in FreeBSD stable versions

The problems have also been fixed in FreeBSD stable versions 9, 10, 11.


My CCID driver should now work better on FreeBSD.