LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Hardware (http://www.linuxquestions.org/questions/linux-hardware-18/)
-   -   udev: Making rules for device with multiple virtual USB-Serial Ports (http://www.linuxquestions.org/questions/linux-hardware-18/udev-making-rules-for-device-with-multiple-virtual-usb-serial-ports-738810/)

damien_d 07-09-2009 01:42 AM

udev: Making rules for device with multiple virtual USB-Serial Ports
 
Dear all,

I am attempting to set some udev rules for a GPS Reciever (NovAtel). It has three USB-Serial ports, /dev/ttyUSB0 /dev/ttyUSB1 and /dev/ttyUSB2.

Of course, if there are other USB-Serial converters in the system (which we have), these are not guaranteed to be 0,1,2

Therefore, we'd like to assign the USB-Serial port as /dev/ttyOEMV_1 /dev/ttyOEMV_2 /dev/ttyOEMV_3 (OEMV is the line receiver)

We have tried a number of different rules, but so far, we have not been able to achieve what we want.

udevinfo reveals the following:
Code:

/home/damien # udevinfo -a -n ttyUSB4                                   
                                                                               
Udevinfo starts with the device specified by the devpath and then             
walks up the chain of parent devices. It prints for every device               
found, all possible attributes in the udev rules key format.                   
A rule to match, can be composed by the attributes of the device               
and the attributes from one single parent device.                             
                                                                               
  looking at device '/class/tty/ttyUSB4':                                     
    KERNEL=="ttyUSB4"                                                         
    SUBSYSTEM=="tty"                                                           
    DRIVER==""                                                                 
    ATTR{dev}=="188:4"                                                         
                                                                               
  looking at parent device '/devices/platform/fsl-ehci.0/usb1/1-1/1-1.3/1-1.3:1:
    KERNELS=="ttyUSB4"                                                         
    SUBSYSTEMS=="usb-serial"                                                   
    DRIVERS=="generic"                                                         
    ATTRS{port_number}=="1"                                                   
                                                                               
  looking at parent device '/devices/platform/fsl-ehci.0/usb1/1-1/1-1.3/1-1.3:1:
    KERNELS=="1-1.3:1.0"                                                       
    SUBSYSTEMS=="usb"                                                         
    DRIVERS=="usbserial_generic"                                               
    ATTRS{bInterfaceNumber}=="00"                                             
    ATTRS{bAlternateSetting}==" 0"                                             
    ATTRS{bNumEndpoints}=="06"                                                 
    ATTRS{bInterfaceClass}=="ff"                                               
    ATTRS{bInterfaceSubClass}=="00"                                           
    ATTRS{bInterfaceProtocol}=="ff"                                           
    ATTRS{modalias}=="usb:v09D7p0100d0101dcFFdsc00dpFFicFFisc00ipFF"           
    ATTRS{interface}=="Interface 0"                                           
                                                                               
  looking at parent device '/devices/platform/fsl-ehci.0/usb1/1-1/1-1.3':     
    KERNELS=="1-1.3"                                                           
    SUBSYSTEMS=="usb"                                                         
    DRIVERS=="usb"                                                             
    ATTRS{dev}=="189:4"                                                       
    ATTRS{configuration}=="Config 1"                                           
    ATTRS{bNumInterfaces}==" 1"                                               
    ATTRS{bConfigurationValue}=="1"                                           
    ATTRS{bmAttributes}=="c0"                                                 
    ATTRS{bMaxPower}=="  0mA"                                                 
    ATTRS{urbnum}=="12"                                                       
    ATTRS{idVendor}=="09d7"                                                   
    ATTRS{idProduct}=="0100"                                                   
    ATTRS{bcdDevice}=="0101"                                                   
    ATTRS{bDeviceClass}=="ff"                                                 
    ATTRS{bDeviceSubClass}=="00"                                               
    ATTRS{bDeviceProtocol}=="ff"                                               
    ATTRS{bNumConfigurations}=="1"                                             
    ATTRS{bMaxPacketSize0}=="16"                                               
    ATTRS{speed}=="12"                                                         
    ATTRS{busnum}=="1"                                                         
    ATTRS{devnum}=="5"                                                         
    ATTRS{version}==" 1.10"                                                   
    ATTRS{maxchild}=="0"                                                       
    ATTRS{quirks}=="0x0"                                                       
    ATTRS{authorized}=="1"                                                     
    ATTRS{manufacturer}=="NovAtel Inc."                                       
    ATTRS{product}=="NovAtel GPS Receiver"                                     
    ATTRS{serial}=="SYY06330353" 

<snip other parents>

We have tried to create the following rules:
Code:

# /dev/ttyOEMV_1 points to /dev/ttyUSB6 because all of the following match:
KERNEL="ttyUSB*", KERNELS=="1-1.3:1.0", SYMLINK+="ttyOEMV_1"

# Does not work because it looks for attributes in multiple parents
KERNEL="ttyUSB*", ATTRS{port_number}=="0", KERNELS=="1-1.3:1.0", SYMLINK+="ttyOEMV_1"

# Unsuitable, because it creates (for example) /dev/ttyOEMV_4 for /dev/ttyUSB4
KERNEL="ttyUSB*", KERNELS=="1-1.3:1.0", SYMLINK+="ttyOEMV_%n"

We have observed that the following attribute reliably changes to indicate the virtual port we want, even when we have two of the same receivers plugged in:
Code:

ATTRS{port_number}=="1"
We **can** more or less guarantee that the receiver will be plugged into the same USB port, which is why we try to use the USB ID (KERNELS=="1-1.3:1.0") for identifying the particular receiver (although we could do the same with the product and vendor ID, although we do want to be able to have two or more receivers in the system).

Our other options is to write a script with the RUN+=/my/script.sh with the rule to get the other ports I need to link, but that seems a little over the top.

If I can provide further information, please let me know. I would imagine that someone may have come across a similar problem working with (for example) GSM/3G modems which often have multiple USB-Serial devices over the same physical port.

Damien.

tredegar 07-12-2009 11:28 AM

I expect you have seen this page: http://www.reactivated.net/writing_udev_rules.html
Further down that page, Daniel Drake gives some useful examples, eg how to have a USB printer always appear at /dev/epson_680

You could adapt his scripts so your GPS always shows up as /dev/ttyGPS0 /dev/ttyGPS1 /dev/ttyGPS2 or whatever.

Using "USB ID (KERNELS=="1-1.3:1.0") for identifying the particular receiver" is probably not sensible, use something else to determine what is what. See the bit relating to udevinfo on the above page, and remember that "while it is legal to combine the attributes from the device in question and a single parent device, you cannot mix-and-match attributes from multiple parent devices - your rule will not work"

Let us know how you get on.


All times are GMT -5. The time now is 01:23 AM.