# persistent device name

#
# run following shell cmd.
#
# udevadm info -a -p $(udevadm info -q path -n /dev/ttyACM0)
#

#
# then you get sth. like following:
#

# 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/usb1/1-2/1-2.4/1-2.4:1.0/tty/ttyACM0':
#     KERNEL=="ttyACM0"
#     SUBSYSTEM=="tty"
#     DRIVER==""

#   looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2.4/1-2.4:1.0':
#     KERNELS=="1-2.4:1.0"
#     SUBSYSTEMS=="usb"
#     DRIVERS=="cdc_acm"
#     ATTRS{authorized}=="1"
#     ATTRS{bAlternateSetting}==" 0"
#     ATTRS{bInterfaceClass}=="02"
#     ATTRS{bInterfaceNumber}=="00"
#     ATTRS{bInterfaceProtocol}=="01"
#     ATTRS{bInterfaceSubClass}=="02"
#     ATTRS{bNumEndpoints}=="01"
#     ATTRS{bmCapabilities}=="6"
#     ATTRS{supports_autosuspend}=="1"

#   looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2.4':
#     KERNELS=="1-2.4"
#     SUBSYSTEMS=="usb"
#     DRIVERS=="usb"
#     ATTRS{authorized}=="1"
#     ATTRS{avoid_reset_quirk}=="0"
#     ATTRS{bConfigurationValue}=="1"
#     ATTRS{bDeviceClass}=="02"
#     ATTRS{bDeviceProtocol}=="00"
#     ATTRS{bDeviceSubClass}=="00"
#     ATTRS{bMaxPacketSize0}=="64"
#     ATTRS{bMaxPower}=="100mA"
#     ATTRS{bNumConfigurations}=="1"
#     ATTRS{bNumInterfaces}==" 2"
#     ATTRS{bcdDevice}=="0277"
#     ATTRS{bmAttributes}=="c0"
#     ATTRS{busnum}=="1"
#     ATTRS{configuration}==""
#     ATTRS{devnum}=="31"
#     ATTRS{devpath}=="2.4"
#     ATTRS{idProduct}=="0483"
#     ATTRS{idVendor}=="16c0"
#     ATTRS{ltm_capable}=="no"
#     ATTRS{manufacturer}=="Teensyduino"
#     ATTRS{maxchild}=="0"
#     ATTRS{product}=="USB Serial"
#     ATTRS{quirks}=="0x0"
#     ATTRS{removable}=="fixed"
#     ATTRS{rx_lanes}=="1"
#     ATTRS{serial}=="4871050"
#     ATTRS{speed}=="12"
#     ATTRS{tx_lanes}=="1"
#     ATTRS{urbnum}=="10"
#     ATTRS{version}==" 1.10"

#   looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-2':
#     KERNELS=="1-2"
#     SUBSYSTEMS=="usb"
#     DRIVERS=="usb"
#     ATTRS{authorized}=="1"
#     ATTRS{avoid_reset_quirk}=="0"
#     ATTRS{bConfigurationValue}=="1"
#     ATTRS{bDeviceClass}=="09"
#     ATTRS{bDeviceProtocol}=="02"
#     ATTRS{bDeviceSubClass}=="00"
#     ATTRS{bMaxPacketSize0}=="64"
#     ATTRS{bMaxPower}=="100mA"
#     ATTRS{bNumConfigurations}=="1"
#     ATTRS{bNumInterfaces}==" 1"
#     ATTRS{bcdDevice}=="9212"
#     ATTRS{bmAttributes}=="e0"
#     ATTRS{busnum}=="1"
#     ATTRS{configuration}==""
#     ATTRS{devnum}=="30"
#     ATTRS{devpath}=="2"
#     ATTRS{idProduct}=="0610"
#     ATTRS{idVendor}=="05e3"
#     ATTRS{ltm_capable}=="no"
#     ATTRS{manufacturer}=="GenesysLogic"
#     ATTRS{maxchild}=="4"
#     ATTRS{product}=="USB2.0 Hub"
#     ATTRS{quirks}=="0x0"
#     ATTRS{removable}=="removable"
#     ATTRS{rx_lanes}=="1"
#     ATTRS{speed}=="480"
#     ATTRS{tx_lanes}=="1"
#     ATTRS{urbnum}=="44"
#     ATTRS{version}==" 2.10"

#   looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1':
#     KERNELS=="usb1"
#     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}=="0504"
#     ATTRS{bmAttributes}=="e0"
#     ATTRS{busnum}=="1"
#     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 5.4.0-48-generic xhci-hcd"
#     ATTRS{maxchild}=="11"
#     ATTRS{product}=="xHCI Host Controller"
#     ATTRS{quirks}=="0x0"
#     ATTRS{removable}=="unknown"
#     ATTRS{rx_lanes}=="1"
#     ATTRS{serial}=="0000:00:14.0"
#     ATTRS{speed}=="480"
#     ATTRS{tx_lanes}=="1"
#     ATTRS{urbnum}=="1026"
#     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{ari_enabled}=="0"
#     ATTRS{broken_parity_status}=="0"
#     ATTRS{class}=="0x0c0330"
#     ATTRS{consistent_dma_mask_bits}=="64"
#     ATTRS{d3cold_allowed}=="1"
#     ATTRS{dbc}=="disabled"
#     ATTRS{device}=="0x9cb1"
#     ATTRS{dma_mask_bits}=="64"
#     ATTRS{driver_override}=="(null)"
#     ATTRS{enable}=="1"
#     ATTRS{irq}=="53"
#     ATTRS{local_cpulist}=="0-3"
#     ATTRS{local_cpus}=="f"
#     ATTRS{msi_bus}=="1"
#     ATTRS{numa_node}=="-1"
#     ATTRS{revision}=="0x03"
#     ATTRS{subsystem_device}=="0x7270"
#     ATTRS{subsystem_vendor}=="0x8086"
#     ATTRS{vendor}=="0x8086"

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



# now look at (line 28 of this file). which is:

#     KERNELS=="1-2.4:1.0"


#
# KERNELS value indicates what port is being used.
#



#
# now, look at the usb plugs of the usb hub (black one w/ usb 3 support)
# by pluging in and out (trial and error)
# one can easily get a mapping of KERNELS values like:
#



#
# but, be careful !
# all usb ports are usb 3.0 capable ports.
# plug-in usb 3.0 device, then they will be registered under usb3 bus.
# plug-in usb 2.0 device, then they will be registered under usb2 bus.
# usb2 bus & usb3 bus numbering map is totally different !
#



# usb 2.0 mapping (for example, you will get one of these with 'arduino')

#     +-------+-------+-------+-------+
#     | 1-2.1 | 1-2.2 | 1-2.3 | 1-2.4 |--------[USB A plug]|||
#     +-------+-------+-------+-------+



# usb 3.0 mapping (for example, you will get one of these with 'usb3.0 external ssd')

#     +-------+-------+-------+-------+
#     | 2-2.1 | 2-2.2 | 2-2.3 | 2-2.4 |--------[USB A plug]|||
#     +-------+-------+-------+-------+



# so, as a summary

# usb 2/3 port mappings

#     +-------+-------+-------+-------+
#     |   A   |   B   |   C   |   D   |--------[USB A plug]|||
#     +-------+-------+-------+-------+
#     +-------+-------+-------+-------+
#     | 1-2.1 | 1-2.2 | 1-2.3 | 1-2.4 |--------[USB A plug]|||
#     +-------+-------+-------+-------+
#     +-------+-------+-------+-------+
#     | 2-2.1 | 2-2.2 | 2-2.3 | 2-2.4 |--------[USB A plug]|||
#     +-------+-------+-------+-------+


# configurations to get fixed symlinks only for ttyACM* & ttyUSB*

# usb 2.0
KERNEL=="ttyACM*", KERNELS=="1-2.1", MODE="0666", SYMLINK+="portA"
KERNEL=="ttyUSB*", KERNELS=="1-2.1", MODE="0666", SYMLINK+="portA"
# usb 3.0
KERNEL=="ttyACM*", KERNELS=="2-2.1", MODE="0666", SYMLINK+="portA"
KERNEL=="ttyUSB*", KERNELS=="2-2.1", MODE="0666", SYMLINK+="portA"

# usb 2.0
KERNEL=="ttyACM*", KERNELS=="1-2.2", MODE="0666", SYMLINK+="portB"
KERNEL=="ttyUSB*", KERNELS=="1-2.2", MODE="0666", SYMLINK+="portB"
# usb 3.0
KERNEL=="ttyACM*", KERNELS=="2-2.2", MODE="0666", SYMLINK+="portB"
KERNEL=="ttyUSB*", KERNELS=="2-2.2", MODE="0666", SYMLINK+="portB"

# usb 2.0
KERNEL=="ttyACM*", KERNELS=="1-2.3", MODE="0666", SYMLINK+="portC"
KERNEL=="ttyUSB*", KERNELS=="1-2.3", MODE="0666", SYMLINK+="portC"
# usb 3.0
KERNEL=="ttyACM*", KERNELS=="2-2.3", MODE="0666", SYMLINK+="portC"
KERNEL=="ttyUSB*", KERNELS=="2-2.3", MODE="0666", SYMLINK+="portC"

# usb 2.0
KERNEL=="ttyACM*", KERNELS=="1-2.4", MODE="0666", SYMLINK+="portD"
KERNEL=="ttyUSB*", KERNELS=="1-2.4", MODE="0666", SYMLINK+="portD"
# usb 3.0
KERNEL=="ttyACM*", KERNELS=="2-2.4", MODE="0666", SYMLINK+="portD"
KERNEL=="ttyUSB*", KERNELS=="2-2.4", MODE="0666", SYMLINK+="portD"
