1*70f73627Sthorpej#!/bin/sh - 2*70f73627Sthorpej# 3*70f73627Sthorpej# $NetBSD: 99-ucom-symlinks,v 1.1 2024/03/30 06:29:01 thorpej Exp $ 4*70f73627Sthorpej# 5*70f73627Sthorpej# Attempt to create stable names (using symbolic links) to USB serial 6*70f73627Sthorpej# devices, regardless of device enumeration order, suitable for use in 7*70f73627Sthorpej# configuration files. The format of the stable names is: 8*70f73627Sthorpej# 9*70f73627Sthorpej# /dev/{cdt}ty-$driver-$serialnumber-$portnumber 10*70f73627Sthorpej# - or - 11*70f73627Sthorpej# /dev/{cdt}ty-$driver-$serialnumber 12*70f73627Sthorpej# 13*70f73627Sthorpej# depending on whether or not the device is a multi-port adapter. 14*70f73627Sthorpej# 15*70f73627Sthorpej# e.g. 16*70f73627Sthorpej# 17*70f73627Sthorpej# /dev/tty-uftdi-FT64S4YP-1 -> /dev/ttyU0 18*70f73627Sthorpej# 19*70f73627Sthorpej# /dev/tty-uslsa-01E7ABCC -> /dev/ttyU4 20*70f73627Sthorpej# 21*70f73627Sthorpej# If $driver or $serialnumber cannot be determined, then no symbolic link 22*70f73627Sthorpej# will be created. 23*70f73627Sthorpej# 24*70f73627Sthorpej# Written by Jason R. Thorpe, December 2022. Public domain. 25*70f73627Sthorpej# 26*70f73627Sthorpej 27*70f73627Sthorpejexport LC_ALL=C 28*70f73627Sthorpej 29*70f73627Sthorpejevent="$1" 30*70f73627Sthorpejshift 31*70f73627Sthorpejdevices=$@ 32*70f73627Sthorpej 33*70f73627Sthorpejsymlink_name() 34*70f73627Sthorpej{ 35*70f73627Sthorpej local parent 36*70f73627Sthorpej local portnum 37*70f73627Sthorpej local serialnum 38*70f73627Sthorpej local driver 39*70f73627Sthorpej 40*70f73627Sthorpej parent=$(drvctl -p $1 device-parent) 41*70f73627Sthorpej if [ x"$parent" != x ]; then 42*70f73627Sthorpej driver=$(drvctl -p $parent device-driver) 43*70f73627Sthorpej serialnum=$(drvctl -p $parent serialnumber) 44*70f73627Sthorpej fi 45*70f73627Sthorpej 46*70f73627Sthorpej # If the device is a single-port device, it may have the default 47*70f73627Sthorpej # port number locator of '-1'. In that case, elide the port 48*70f73627Sthorpej # number. 49*70f73627Sthorpej portnum=$(drvctl -p $1 port) 50*70f73627Sthorpej if [ x"$portnum" = x"-1" -o x"$portnum" = x ]; then 51*70f73627Sthorpej portnum="" 52*70f73627Sthorpej else 53*70f73627Sthorpej portnum="-${portnum}" 54*70f73627Sthorpej fi 55*70f73627Sthorpej 56*70f73627Sthorpej if [ x"$driver" != x -a x"$serialnum" != x ]; then 57*70f73627Sthorpej echo "${driver}-${serialnum}${portnum}" 58*70f73627Sthorpej else 59*70f73627Sthorpej echo "" 60*70f73627Sthorpej fi 61*70f73627Sthorpej} 62*70f73627Sthorpej 63*70f73627Sthorpejremove_ucom_symlink() 64*70f73627Sthorpej{ 65*70f73627Sthorpej local name 66*70f73627Sthorpej local unit 67*70f73627Sthorpej 68*70f73627Sthorpej name=$(readlink "/dev/${1}") 69*70f73627Sthorpej 70*70f73627Sthorpej if [ x"$name" != x ]; then 71*70f73627Sthorpej rm -f "/dev/tty-${name}" 72*70f73627Sthorpej rm -f "/dev/dty-${name}" 73*70f73627Sthorpej rm -f "/dev/cty-${name}" 74*70f73627Sthorpej rm -f "/dev/${1}" 75*70f73627Sthorpej fi 76*70f73627Sthorpej} 77*70f73627Sthorpej 78*70f73627Sthorpejadd_ucom_symlink() 79*70f73627Sthorpej{ 80*70f73627Sthorpej local name 81*70f73627Sthorpej local tty_path 82*70f73627Sthorpej local dty_path 83*70f73627Sthorpej local cty_path 84*70f73627Sthorpej 85*70f73627Sthorpej name=$(symlink_name $1) 86*70f73627Sthorpej unit=$(drvctl -p $1 device-unit) 87*70f73627Sthorpej 88*70f73627Sthorpej if [ x"$name" != x -a x"$unit" != x ]; then 89*70f73627Sthorpej # 90*70f73627Sthorpej # We need to make two sets of symlinks: 91*70f73627Sthorpej # 92*70f73627Sthorpej # /dev/tty-uslsa-01E7ABCC -> /dev/ttyU4 93*70f73627Sthorpej # 94*70f73627Sthorpej # /dev/ucom4 -> uslsa-01E7ABCC 95*70f73627Sthorpej # 96*70f73627Sthorpej # This is needed because when we get the detach event 97*70f73627Sthorpej # for e.g. ucom4, the parent device (e.g. uslsa0) may 98*70f73627Sthorpej # already be gone, meaning we cannot query it. So 99*70f73627Sthorpej # what we're doing is stashing the information in the 100*70f73627Sthorpej # second symlink so we can readlink(1) it later to 101*70f73627Sthorpej # recover the stable name. 102*70f73627Sthorpej # 103*70f73627Sthorpej 104*70f73627Sthorpej tty_path="/dev/ttyU${unit}" 105*70f73627Sthorpej dty_path="/dev/dtyU${unit}" 106*70f73627Sthorpej cty_path="/dev/ctyU${unit}" 107*70f73627Sthorpej 108*70f73627Sthorpej ln -sf "${name}" "/dev/${1}" 109*70f73627Sthorpej if [ -c ${tty_path} ]; then 110*70f73627Sthorpej ln -sf ${tty_path} "/dev/tty-${name}" 111*70f73627Sthorpej fi 112*70f73627Sthorpej if [ -c ${dty_path} ]; then 113*70f73627Sthorpej ln -sf ${dty_path} "/dev/dty-${name}" 114*70f73627Sthorpej fi 115*70f73627Sthorpej if [ -c ${cty_path} ]; then 116*70f73627Sthorpej ln -sf ${cty_path} "/dev/cty-${name}" 117*70f73627Sthorpej fi 118*70f73627Sthorpej fi 119*70f73627Sthorpej} 120*70f73627Sthorpej 121*70f73627Sthorpejfor device in $devices; do 122*70f73627Sthorpej case $device in 123*70f73627Sthorpej ucom*) 124*70f73627Sthorpej case $event in 125*70f73627Sthorpej device-attach) 126*70f73627Sthorpej remove_ucom_symlink $device 127*70f73627Sthorpej add_ucom_symlink $device 128*70f73627Sthorpej ;; 129*70f73627Sthorpej device-detach) 130*70f73627Sthorpej remove_ucom_symlink $device 131*70f73627Sthorpej ;; 132*70f73627Sthorpej esac 133*70f73627Sthorpej esac 134*70f73627Sthorpejdone 135