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