FreeBSD: Permanent nodes for usb devices

devicesfreebsdusb

In FreeBSD, USB devices appear in /dev as (for example) /dev/ugen2.5, /dev/ugen2.6, etc…

However, I noticed after a reboot sometimes these are pointing to different devices. Is there a way to lock them down, or to get a node like /dev/my-usb-device that doesn't change after reboot?

Best Answer

I don't think you can lock, but there's a fairly easy way to do this. You need to add some stuff to etc/devd.conf which handles the specific device when it appears. You'll need to use something unique about the device (e.g. its serial number). Here is an example for the USB serial port that handles my doorbell:

# Set up symlink to doorbell serial port
attach 200 {
        device-name     "uftdi[0-9]";
        match           "vendor"        "0x0403";
        match           "product"       "0x6001";
        match           "sernum"        "A10167K1";
        action          "/root/bin/cuaconfig $device-name doorbell $sernum";
};  

Notice that the action is to run a script. This works out the true serial port number by devious means, and then adds a symbolic link in /dev. Your programs use this to access the device. Here is my script, which is probably more than you will need. This one translates the USB device name to a serial port name, bacause I'm using an FTDI USB port serial chip. You will probably have something a lot simpler, and probably not need that translation.

#!/bin/sh

# configure cuaU? ports - called from devd.conf
# arg 1 - device name, of the form uftdi?
# arg 2 - symlink to create/delete in /dev (any existing one deleted)
# arg 3 - serial number

dev=$1
link=$2
sernum=$3

# get FTDI unit number
ftunit=${dev#uftdi}

# generate full tty name
ttyname="/dev/cua$(sysctl -n dev.uftdi.$ftunit.ttyname)"

# generate full symlink name
symlink="/dev/${link}"

# delete any existing symlink to the port, then create the new one
echo "creating symlink ${symlink} to ${ttyname} on serial ${sernum}" > /dev/console
rm -f ${symlink}
ln -s ${ttyname} ${symlink}`

Getting the serial number of a device

It may be enough to use the manufacturer IDs in the devd.conf stuff. However, you might have two the same (I have, they are FT232 USB serial ports). In that case, you can differentiate them by serial number (beware, some FT232 clones all have the same serial number!)

There are various ways to get the serial number. One is to install the port sysutils/usbutils. This contains the lsusb command, which will list out all the devices. You can use:

lsusb -v -s 0403:6001 | grep serial  

to get the serial number.

Related Question