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