LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 09-18-2007, 01:51 PM   #1
tm007
LQ Newbie
 
Registered: Sep 2007
Posts: 9

Rep: Reputation: 0
udev not called to remove open USB serial device


I have written a simple program that is called whenever a USB serial device (ttyUSB0) is connected/disconnected. When I connect the device my program is called without any problems. The problem is when I disconnect the device. If ttyUSB0 is opened by another program and the device is disconnected while still open udev never calls my program. I need to be notified when the device disconnects so I can terminate the program that has opened ttyUSB0 in the first place. I am not sure if this is a problem with something I've done, udev or the USB serial module. I have tried this on both Ubuntu 2.6.20.15 (x86) and an embedded (ARM) version of 2.6.19.2. I have not tried newer kernels since the 2.6.19.2 is my real target.

Does anyone have any ideas why udev is not running my program when the device is disconnected?

Are there different or better ways of detecting the USB device has disconnected? Any help or ideas are very welcome.

Below is the simple udev rule to call my program:
Code:
KERNEL=="ttyUSB*", RUN+="/tmp/my_program %k"
 
Old 09-20-2007, 03:57 PM   #2
tm007
LQ Newbie
 
Registered: Sep 2007
Posts: 9

Original Poster
Rep: Reputation: 0
Possible Kernel Bug

Just an update on my findings. It appears that this was either a design decision or a bug within the kernel. If anyone can answer that I'd love to know the answer.

It looks to me to be a problem with the ref counting in the USB serial driver. When the kref is created it starts with a value one. Once a device connects it increments. The destroy_serial triggers the sending of the uevent which would notify my program that the device has disconnected. But within serial_disconnect there is a only single kref_put, therefore the destory_serial is not called until the open device is closed. So, once the port is closed the kref_put is called and results in the proper cleanup and the uevent is sent.

To fix this problem for the USB serial you can use the following change within serial_disconnect:

Code:
if (serial) {
    for (i = 0; i < serial->num_ports; ++i) {
        port = serial->port[i];
        if (port && port->tty)
        {
            tty_hangup(port->tty);

            /* prevents a close from an open device crashing the driver */
            port->tty->driver_data = NULL;

            /* we are also done with the reference used by tty */
            usb_serial_put(serial);
        }
    }
    /* let the last holder of this object 
     * cause it to be cleaned up */
    usb_serial_put(serial);
}

I have also seen the same behavior when using cdc-acm, therefore it is unclear if this is a bug or a design decision.

It seems to me that it should be a bug because how else is an application to know that the device has disconnected?
 
Old 09-21-2007, 06:31 AM   #3
gnashley
Amigo developer
 
Registered: Dec 2003
Location: Germany
Distribution: Slackware
Posts: 4,771

Rep: Reputation: 477Reputation: 477Reputation: 477Reputation: 477Reputation: 477
The USB and SCSI kernel code are still undergoing major changes which frequently break the drivers in one way or another. You don't mention which kernel version you are using, but I suspect that using another version would give different results. Don't think that using the latest will solve the problem as there are still design changes occurring.
 
Old 09-24-2007, 08:46 AM   #4
tm007
LQ Newbie
 
Registered: Sep 2007
Posts: 9

Original Poster
Rep: Reputation: 0
gnashley, thanks for the comment. The kernel version used are 2.6.20.15 (Kubuntu) and 2.6.19.2 (Freescale BSP). I have also compared usb-serial.c from these versions to the latest kernel code and found no changes that would fix this problem.

I also got basically the same response as gnashley from the Linux kernel people. The Linux bugzilla response was:
Quote:
You should get a hangup on the port. That notifies the open process.

No comment on the other bits although the whole open/close stuff has a couple of other races and is on the hit list for a rewrite so a semi-ugly patch here for now isn't too worrying.
If you need to use udev for the notification then you'll need to use something like the "semi-ugly patch" that I have proposed
 
  


Reply

Tags
kernel, serial, ttyusb, udev, usb


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Connect from FC6 box to other device via serial/usb Hewson Linux - Hardware 5 03-13-2007 04:43 PM
USB device as serial device BlackHatRob Linux - Hardware 1 06-08-2006 08:09 PM
USB-Serial Custom Device with C d13VB Programming 0 05-11-2005 10:45 AM
Failed to open device /dev/usb/ttyUSB0: No such device efm Linux - Newbie 2 04-04-2005 09:46 PM
USB->Serial Device hugoveiga Linux - Hardware 0 01-06-2005 08:04 AM


All times are GMT -5. The time now is 12:59 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration