libftdi Archives

Subject: Re: libftdi and ftdi_sio

From: Krishnendu Chatterjee <krishnendu.chatterjee@xxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Mon, 24 Aug 2015 04:44:01 +0530

Opening one ftdi device with libftdi (say bound to /dev/ttyUSB0) will not detach any other ftdi device bound to other ports (say /dev/ttyUSB1).

On Aug 23, 2015 6:46 AM, "Shashank Chintalagiri" <shashank@xxxxxxxxxx> wrote:
I'm 'using' libftdi. Assume for he purpose of  this discussion that I only care about posix systems, and if necessary than can be restricted to modern desktop linuxes. While the actual code I'm running is python code using pylibftdi [1], an approach from the C and libftdi perspective is fine.


I notice the following (expected) behaviour :

 * Using libftdi causes ftdi_sio to be unloaded (detached). Any ftdi_sio provided /dev/ttyUSBx disappear.
 * All /dev/ttyUSBx disappear, regardless of how many FTDI devices are connected and how many of those have libftdi drivers attached.
 * 'Creating' a pylibftdi Device (which effectively translates to an ftdi_usb_open_* call) makes libftdi active.
 * 'Closing' a pylibftdi Device does not seem to reload ftdi_sio.


What I'm having some trouble with is the following :

 * Is it possible to use libftdi on some (or one) FTDI devices, but continue using ftdi_sio on others? If so, how.

 * After I'm done using libftdi, I'd like to have the /dev/ttyUSBx back. I know I can do this by manually running insmod, but I'm hoping that it can be achieved without manual intervention. Since libftdi is able to (effectively) run rmmod, I would expect it to be able to reverse it's actions either at an algorithmically determined point or at the user's explicit request.

 * The creation of the pylibftdi Device instance includes a call to libusb's libusb_set_auto_detach_kernel_driver(), which should, according to the documentation, reload the kernel when the device is released. This does not work. Is there something I'm missing here? Is there a libftdi specific way / function which can reload ftdi_sio - either on device close or by an explicit function call by my code, assuming that I take responsibility for any unintended side effects of doing so.

 * If you have, say, 3 FTDI devices, of which 2 use libftdi. If only one of those two are closed, then reloading ftdi_sio at that point is likely not a good idea. If there is an attach_kernel_driver() or similar function within libftdi, what rationale does it use? Similarly, if libusb's libusb_set_auto_detach_kernel_driver() was to work or a call to libusb_attach_kernel_driver() was made, how would libusb handle this and how would libftdi react to this?


I found a small patch [2] on the mailing list which seemingly addressed this issue. The OP there didn't seem to want to see it through, and that line of code didn't make it into libftdi. Would that piece of code have worked? Is / was there something inherently wrong with that approach? More immediately, would it be possible to use that approach from outside libftdi? Specifically, the proposed patch involved calling libusb_attach_kernel_driver() after libusb_release_interface() and before ftdi_usb_close_internal() in ftdi_usb_close(). However, if I'd like to be able to do this with vanilla libftdi, the libusb_attach_kernel_driver() call would have to come either before or after ftdi_usb_close(). Is there any chance for this to work?



For reference, here is the relevant portion of the code that I'd like to be able to use :

driver = pylibftdi.Driver()
devices = driver.list_devices()
serials = [x[2] for x in devices]

# If I exit at this point, /dev/ttyUSBx is still available.

with pylibftdi.Device(device_id="some serial number") as device:

    # This 'with' ... is a contextmanager in python. At the end of this code
    # block, device.close() is called automatically. Within pylibftdi, this
    # is implemented as a call to libftdi's ftdi_usb_close and then
    # ftdi_usb_deinit

    chipid = c_uint()
    device.ftdi_fn.ftdi_read_chipid(byref(chipid))

# /dev/ttyUSBx is gone, but at this point I want it back.


And here is the route I think may work (though I haven't had a chance to try it yet for lack of a device on hand) :

def close(self):
    """
    close our connection, free resources
    """
    if self._opened:
        ctx_p = cast(byref(self.ctx), POINTER(ftdi_context_partial)).contents
        self.fdll.ftdi_usb_close(byref(self.ctx))
        if self.auto_detach:
            dev = ctx_p.libusb_device_handle
            if dev:
                self.driver._libusb.libusb_attach_kernel_driver(dev, 1)
        self.fdll.ftdi_deinit(byref(self.ctx))
        del self.ctx
    self._opened = False


libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx




libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx


Current Thread