xref: /netbsd-src/share/examples/devpubd/hooks/99-ucom-symlinks (revision 70f7362772ba52b749c976fb5e86e39a8b2c9afc)
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