#!/bin/sh - # # $NetBSD: 99-ucom-symlinks,v 1.1 2024/03/30 06:29:01 thorpej Exp $ # # Attempt to create stable names (using symbolic links) to USB serial # devices, regardless of device enumeration order, suitable for use in # configuration files. The format of the stable names is: # # /dev/{cdt}ty-$driver-$serialnumber-$portnumber # - or - # /dev/{cdt}ty-$driver-$serialnumber # # depending on whether or not the device is a multi-port adapter. # # e.g. # # /dev/tty-uftdi-FT64S4YP-1 -> /dev/ttyU0 # # /dev/tty-uslsa-01E7ABCC -> /dev/ttyU4 # # If $driver or $serialnumber cannot be determined, then no symbolic link # will be created. # # Written by Jason R. Thorpe, December 2022. Public domain. # export LC_ALL=C event="$1" shift devices=$@ symlink_name() { local parent local portnum local serialnum local driver parent=$(drvctl -p $1 device-parent) if [ x"$parent" != x ]; then driver=$(drvctl -p $parent device-driver) serialnum=$(drvctl -p $parent serialnumber) fi # If the device is a single-port device, it may have the default # port number locator of '-1'. In that case, elide the port # number. portnum=$(drvctl -p $1 port) if [ x"$portnum" = x"-1" -o x"$portnum" = x ]; then portnum="" else portnum="-${portnum}" fi if [ x"$driver" != x -a x"$serialnum" != x ]; then echo "${driver}-${serialnum}${portnum}" else echo "" fi } remove_ucom_symlink() { local name local unit name=$(readlink "/dev/${1}") if [ x"$name" != x ]; then rm -f "/dev/tty-${name}" rm -f "/dev/dty-${name}" rm -f "/dev/cty-${name}" rm -f "/dev/${1}" fi } add_ucom_symlink() { local name local tty_path local dty_path local cty_path name=$(symlink_name $1) unit=$(drvctl -p $1 device-unit) if [ x"$name" != x -a x"$unit" != x ]; then # # We need to make two sets of symlinks: # # /dev/tty-uslsa-01E7ABCC -> /dev/ttyU4 # # /dev/ucom4 -> uslsa-01E7ABCC # # This is needed because when we get the detach event # for e.g. ucom4, the parent device (e.g. uslsa0) may # already be gone, meaning we cannot query it. So # what we're doing is stashing the information in the # second symlink so we can readlink(1) it later to # recover the stable name. # tty_path="/dev/ttyU${unit}" dty_path="/dev/dtyU${unit}" cty_path="/dev/ctyU${unit}" ln -sf "${name}" "/dev/${1}" if [ -c ${tty_path} ]; then ln -sf ${tty_path} "/dev/tty-${name}" fi if [ -c ${dty_path} ]; then ln -sf ${dty_path} "/dev/dty-${name}" fi if [ -c ${cty_path} ]; then ln -sf ${cty_path} "/dev/cty-${name}" fi fi } for device in $devices; do case $device in ucom*) case $event in device-attach) remove_ucom_symlink $device add_ucom_symlink $device ;; device-detach) remove_ucom_symlink $device ;; esac esac done