0

I am a scuba diver and proud owner of 2 diving computers. These two can be connected to a USB port and with Linus' SubSurface divinglog program I can import dive-logs from them. One is an Atomic Aquatics Cobalt and the other is a Suunto D4i. Now I want to create dev-files with udev for each of them so I can connect them to any USB-port and still use the same dev-file in the logging software. (E.g. /dev/my_cobalt and /dev/my_d4i)

The same (kind of) configuration is used for both.
For the D4i the usage of the dev-file gets blocked by an automatically created /dev/ttyUSB0.
For both divingcomputers the dev-file gets created and for the Cobalt all works as wanted but not for the D4i.
I can use /dev/ttyUSB0 but not /dev/my_d4i.

Somehow it seems (I'm not sure) to be caused by a difference in the way they present themselves to the USB-bus. See the output of lsusb below.

If anyone can tell me what causes this difference and/or how to solve this I'd really appreciate it. (Why is when connecting the d4i also a ttyUSB dev-file created?)

Below is some information about findings/settings.

/etc/udev/rules.d/dive-computers.rules

# My Cobalt2 DiveComputer
SUBSYSTEM=="usb", ATTR{idVendor}=="0471", ATTR{idProduct}=="0888", SYMLINK+="my_cobalt", GROUP="dialout", MODE="0660"
# My Suunto D4i DiveComputer
SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}=="6001", SYMLINK+="my_d4i", GROUP="dialout", MODE="0660"

dev-files after connecting Cobalt

lrwxrwxrwx   1 root root            15 mei 16 23:13 my_cobalt -> bus/usb/003/007
# no ttyUSB0 created

dev-files after connecting d4i

lrwxrwxrwx   1 root root            15 mei 16 23:15 my_d4i -> bus/usb/003/009
crw-rw----   1 root dialout   188,   0 mei 16 23:15 ttyUSB0

lsusb -v -D /dev/bus/usb/003/007 (Cobalt)

Device: ID 0471:0888 Philips (or NXP) Hantek DDS-3005 Arbitrary Waveform Generator
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          220 Diagnostic
  bDeviceSubClass         1 Reprogrammable Diagnostics
  bDeviceProtocol         1 USB2 Compliance
  bMaxPacketSize0        16
  idVendor           0x0471 Philips (or NXP)
  idProduct          0x0888 Hantek DDS-3005 Arbitrary Waveform Generator
  bcdDevice            0.02
  iManufacturer           1 ATOMIC AQUATICS
  iProduct                2 COBALT
  iSerial                 3 123456789ABCDEF
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           39
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          4 Console
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           3
      bInterfaceClass       220 Diagnostic
      bInterfaceSubClass    160 
      bInterfaceProtocol    176 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
Device Status:     0x0101
  Self Powered

lsusb -v -D /dev/bus/usb/003/009 (D4i)

Device: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0x0403 Future Technology Devices International, Ltd
  idProduct          0x6001 FT232 USB-Serial (UART) IC
  bcdDevice            6.00
  iManufacturer           1 Smartinterface
  iProduct                2 USB  Serial Cable
  iSerial                 3 DiYISDGK
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    255 Vendor Specific Subclass
      bInterfaceProtocol    255 Vendor Specific Protocol
      iInterface              2 USB  Serial Cable
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
Device Status:     0x0000
  (Bus Powered)

logging of the software (for what its worth)

Starting download from  /dev/my_d4i
Starting the thread 0
[0.000126] ERROR: Inappropriate ioctl for device (25) [in ../../src/serial_posix.c:308 (dc_serial_open)]
[0.000156] ERROR: Failed to open the serial port. [in ../../src/suunto_d9.c:155 (suunto_d9_device_open)]
INFO: dc_deveice_open error value of -6
Finishing the thread Unable to open %s %s (%s) dives downloaded 0
Starting download from  /dev/ttyUSB0
Starting the thread 0
INFO: dc_deveice_open error value of 0
Finishing the thread  dives downloaded 0

1
  • You are symlinking the raw USB device instead of the tty device. I answered a practically similar question before, either here or on unix.stackexchange, but can't find it right now. Basically you need to change the udev rule for the correct subsystem, and use ATTRS instead of ATTR to match in the whole device path. Details in the answer when I can find it.
    – dirkt
    May 17 '18 at 8:36
0

So dirkt gave a comment that made me think and I checked some facts again. With udevadm monitor and then connecting the devices I got the following:

Cobalt:

KERNEL[25393.161856] add      /devices/pci0000:00/0000:00:14.0/usb3/3-8 (usb)
KERNEL[25393.165873] add      /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0 (usb)
KERNEL[25393.165941] bind     /devices/pci0000:00/0000:00:14.0/usb3/3-8 (usb)
UDEV  [25393.183044] add      /devices/pci0000:00/0000:00:14.0/usb3/3-8 (usb)
UDEV  [25393.185175] add      /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0 (usb)
UDEV  [25393.186958] bind     /devices/pci0000:00/0000:00:14.0/usb3/3-8 (usb)

D4i

KERNEL[24333.615580] add      /devices/pci0000:00/0000:00:14.0/usb3/3-8 (usb)
KERNEL[24333.618406] add      /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0 (usb)
KERNEL[24333.618444] add      /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0/ttyUSB0 (usb-serial)
KERNEL[24333.618615] add      /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0/ttyUSB0/tty/ttyUSB0 (tty)
KERNEL[24333.618644] bind     /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0/ttyUSB0 (usb-serial)
KERNEL[24333.618685] bind     /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0 (usb)
KERNEL[24333.618729] bind     /devices/pci0000:00/0000:00:14.0/usb3/3-8 (usb)
UDEV  [24333.637591] add      /devices/pci0000:00/0000:00:14.0/usb3/3-8 (usb)
UDEV  [24333.639773] add      /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0 (usb)
UDEV  [24333.641366] add      /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0/ttyUSB0 (usb-serial)
UDEV  [24333.648159] add      /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0/ttyUSB0/tty/ttyUSB0 (tty)
UDEV  [24333.648969] bind     /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0/ttyUSB0 (usb-serial)
UDEV  [24333.649799] bind     /devices/pci0000:00/0000:00:14.0/usb3/3-8/3-8:1.0 (usb)
UDEV  [24333.650906] bind     /devices/pci0000:00/0000:00:14.0/usb3/3-8 (usb)

With this I guessed that the correct udev-subsystems should be:

  • d4i --> tty
  • cobalt --> usb

And as dirkt mentioned use ATTRS instead of ATTR to match in the whole devicepath. So I changed the udev-rules to:

# My Cobalt2 DiveComputer
SUBSYSTEM=="usb", ATTR{idVendor}=="0471", ATTR{idProduct}=="0888", SYMLINK+="my_cobalt", GROUP="dialout", MODE="0660"
# My Suunto D4i DiveComputer
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="DiYISDGK", SYMLINK+="my_d4i", GROUP="dialout", MODE="0660"

After restarting udev and reconnecting the device i got:

ls -l /dev/tty_d4i

lrwxrwxrwx   1 root root             7 mei 22 00:43 tty_d4i -> ttyUSB0

And this made it working as I wanted. I'm still not 100% sure why but that is my limited knowledge of udev I guess. I will keep investigating udev but for now this seems to be solved. So thanks to dirkt for the hint.

For reference the output of:

sudo udevadm info -a -n /dev/ttyUSB0

Udevadm info 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 '/devices/pci0000:00/0000:00:14.0/usb3/3-7/3-7:1.0/ttyUSB0/tty/ttyUSB0':
    KERNEL=="ttyUSB0"
    SUBSYSTEM=="tty"
    DRIVER==""

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb3/3-7/3-7:1.0/ttyUSB0':
    KERNELS=="ttyUSB0"
    SUBSYSTEMS=="usb-serial"
    DRIVERS=="ftdi_sio"
    ATTRS{latency_timer}=="16"
    ATTRS{port_number}=="0"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb3/3-7/3-7:1.0':
    KERNELS=="3-7:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="ftdi_sio"
    ATTRS{authorized}=="1"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bInterfaceClass}=="ff"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{bInterfaceProtocol}=="ff"
    ATTRS{bInterfaceSubClass}=="ff"
    ATTRS{bNumEndpoints}=="02"
    ATTRS{interface}=="USB  Serial Cable"
    ATTRS{supports_autosuspend}=="1"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb3/3-7':
    KERNELS=="3-7"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="8"
    ATTRS{bMaxPower}=="500mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bcdDevice}=="0600"
    ATTRS{bmAttributes}=="a0"
    ATTRS{busnum}=="3"
    ATTRS{configuration}==""
    ATTRS{devnum}=="14"
    ATTRS{devpath}=="7"
    ATTRS{idProduct}=="6001"
    ATTRS{idVendor}=="0403"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="Smartinterface"
    ATTRS{maxchild}=="0"
    ATTRS{product}=="USB  Serial Cable"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="removable"
    ATTRS{serial}=="DiYISDGK"
    ATTRS{speed}=="12"
    ATTRS{urbnum}=="15"
    ATTRS{version}==" 2.00"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb3':
    KERNELS=="usb3"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{authorized_default}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{bMaxPower}=="0mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bcdDevice}=="0415"
    ATTRS{bmAttributes}=="e0"
    ATTRS{busnum}=="3"
    ATTRS{configuration}==""
    ATTRS{devnum}=="1"
    ATTRS{devpath}=="0"
    ATTRS{idProduct}=="0002"
    ATTRS{idVendor}=="1d6b"
    ATTRS{interface_authorized_default}=="1"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="Linux 4.15.0-20-generic xhci-hcd"
    ATTRS{maxchild}=="15"
    ATTRS{product}=="xHCI Host Controller"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="unknown"
    ATTRS{serial}=="0000:00:14.0"
    ATTRS{speed}=="480"
    ATTRS{urbnum}=="264"
    ATTRS{version}==" 2.00"

  looking at parent device '/devices/pci0000:00/0000:00:14.0':
    KERNELS=="0000:00:14.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="xhci_hcd"
    ATTRS{broken_parity_status}=="0"
    ATTRS{class}=="0x0c0330"
    ATTRS{consistent_dma_mask_bits}=="64"
    ATTRS{d3cold_allowed}=="1"
    ATTRS{dbc}=="disabled"
    ATTRS{device}=="0x8d31"
    ATTRS{dma_mask_bits}=="64"
    ATTRS{driver_override}=="(null)"
    ATTRS{enable}=="1"
    ATTRS{irq}=="19"
    ATTRS{local_cpulist}=="0-11"
    ATTRS{local_cpus}=="fff"
    ATTRS{msi_bus}=="1"
    ATTRS{numa_node}=="0"
    ATTRS{revision}=="0x05"
    ATTRS{subsystem_device}=="0x7a54"
    ATTRS{subsystem_vendor}=="0x1462"
    ATTRS{vendor}=="0x8086"

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.