Add USB support for location based device unit numbers.
Sponsored by: Mellanox Technologies
Differential D21886
Add USB support for location based device unit numbers • hselasky on Oct 3 2019, 12:02 PM. Authored by Tags None Referenced Files
Details
Add USB support for location based device unit numbers. Sponsored by: Mellanox Technologies
Diff Detail
Event TimelineComment Actions @imp: We can have both if the TTY layers support it. Could you implement a tty_makedevalias() function ? At least with this patch the sysctls are coherent, pointing to only one device. Comment Actions There is people who expect the first serial device they plug-in to be ttyU0 (me for example) and there are people who would prefer the unit number to stay the same independent of the order the devices are detected (me as well). I would prefer aliases as well, so we can have both. I didn't check whether it actually is a match to your problem, but how about tty_makealias() in sys/tty.h? sys/tty.h-int tty_makedevf(struct tty *tp, struct ucred *cred, int flags, I do remember from way back talks about naming schemes for USB devices in the USB device tree, something like usb-1-3-2 being a device plugged into port 2 of a hub that is plugged into port 3 of a hub plugged into port 1 of the root hub. Comment Actions I'd prefer the alias stuff as well. I think we have what we need, but if not I'm happy to fix things that are broken. There's a number of different ways to have the aliases setup, and at times code in ucom will be the answer, and other times code in devfs and/or devd might be better. The whole device_t vs dev_t stuff will get in the way here, I fear... Comment Actions @avg: It is needed for embedded, where for example tree USB modems control different things and you have apps that should connect to the same modem after boot. Comment Actions I see. I do not have any objections. Comment Actions My use case for something like this is a USB-serial console server where I might have 16 different USB-serial adapters attached to various USB hubs; I intended to address it by using the serial number in each device. @hselasky can you give an example of the unit numbers that would be generated by this patch? Comment Actions Yes, I am doing something like that now. attach 1001 { match "vendor" "0x12d1"; match "product" "0x1506"; action "ln -sf /dev/cua$ttyname.0 /dev/3g"; }; notify 1001 { match "system" "USB"; match "subsystem" "DEVICE"; match "type" "DETACH"; match "vendor" "0x12d1"; match "product" "0x1506"; action "unlink /dev/3g"; }; attach 1001 { match "vendor" "0x2341"; match "product" "0x0043"; action "ln -sf /dev/cua$ttyname /dev/arduino"; }; notify 1001 { match "system" "USB"; match "subsystem" "DEVICE"; match "type" "DETACH"; match "vendor" "0x2341"; match "product" "0x0043"; action "unlink /dev/arduino"; }; Requires manual configuration though. Comment Actions
Indeed; most of the cheap USB-serial adapters (e.g. the ones available on aliexpress.com for about $1 USD) have the same (often empty) serial number. I found that the cp210x devices can be reprogrammed. https://github.com/emaste/cp210x-cfg is my trivial FreeBSD port of a configuration tool I use to give them unique serial numbers. Comment Actions I took Daniel O'Connor's script from: https://www.mail-archive.com/freebsd-usb@freebsd.org/msg14258.html and did a minor improvement to support creating a USB path via the hub ports, and have this script now: It creates symlinks for devices: Comment Actions Cool script. It would be better to add the alias with devfs. Then it would disappear w/o devd needing all the info... Comment Actions How do you propose to do it? It looks like devfs.conf is the only part of devfs that supports link, and that is done via /etc/rc.d/devfs on boot. devfs.rules and devfs do not have the option to specify links. Comment Actions I've been using this script for about a week, and it does exactly what it says on the tin. Would be fantastic if it could be merged, others can enjoy it. :) Comment Actions Yes, I'm using the script jmg@ modified - it works exactly as I would expect it to: ls -l /dev/tty.* /dev/cu.* lrwxr-xr-x 1 root wheel 5 Jun 12 12:54 /dev/cu.A0AC1F827C641630 -> cuaU2 lrwxr-xr-x 1 root wheel 5 Jun 12 12:54 /dev/tty.A0AC1F827C641630 -> ttyU2 Comment Actions Hello world :-) +1 and thank you for this unique tty/cua with USBSERIAL in node name :-) Also thank you for the hints for DEVD :-) Highly demanded in complex embedded systems and electronics testing scenarios :-) Comment Actions FYI, I wasn't aware of this but there was more to do to conner's script; I have a 4-port USB-serial dongle (1 USB, 4 cuaU*)..
Comment Actions Cool! The only thing where it falls short is for multi-port serial devices.: # ls -l /dev/cu.74301246 /dev/cuaU2.? lrwxr-xr-x 1 root wheel 5 Mar 5 21:24 /dev/cu.74301246 -> cuaU2 crw-rw---- 1 uucp dialer 0x208 Mar 5 21:30 /dev/cuaU2.0 crw-rw---- 1 uucp dialer 0x20e Mar 5 21:24 /dev/cuaU2.1 crw-rw---- 1 uucp dialer 0x218 Mar 5 21:24 /dev/cuaU2.2 crw-rw---- 1 uucp dialer 0x24a Mar 5 21:24 /dev/cuaU2.3 I'll see whether I could modify it for that, but otherwise, it's what I've been looking for. Comment Actions Suggested change: --- usbserialsn~ 2023-03-05 14:23:15.625410000 +0100 +++ usbserialsn 2023-03-06 22:27:01.397518000 +0100 @@ -99,6 +99,8 @@ ' "DEV=$1") } +ttyports=$(devinfo -v | sed -ne '/^ *'"${devname}"'/s/.*ttyports=\([0-9][0-9]*\).*/\1/p') + if [ x"$sernum" = x"auto" ]; then sernum=usb.$(getdevpath "$devname") fi @@ -113,8 +115,18 @@ echo "Bad usage" exit 1 fi - ln -sf cua${ttyname} /dev/cu.${sernum} - ln -sf tty${ttyname} /dev/tty.${sernum} + if [ $ttyports -eq 1 ]; then + ln -sf cua${ttyname} /dev/cu.${sernum} + ln -sf tty${ttyname} /dev/tty.${sernum} + else + # multi-port board, create links for sub-devices + portno=0 + while [ $portno -lt $ttyports ]; do + ln -sf cua${ttyname}.${portno} /dev/cu.${sernum}.${portno} + ln -sf tty${ttyname}.${portno} /dev/tty.${sernum}.${portno} + portno=$(( $portno + 1 )) + done + fi echo ${sernum} >/var/run/usbserialsn.${devname} ;; @@ -127,6 +139,7 @@ exit 0 fi sernum=$(cat /var/run/usbserialsn.${devname}) + rm -f /dev/cu.${sernum}.* /dev/tty.${sernum}.* # multi-port case rm -f /dev/cu.${sernum} /dev/tty.${sernum} /var/run/usbserialsn.${devname} ;; Comment Actions @joerg : There are some ideas spreading that using usbconfig or making a new libusbconfig or adding something to libusb may be better than just, making custom scripts to handle things. What do you think? Comment Actions Well, I do not really care much about the way to get there. ;-) What I need:
For devices that do not provide serial number information, I'm fine with any of the suggested ways for a "location-based" name, or with just "inventing" a pseudo-serial number (as MacOS does). Nevertheless, once we decided for a method, it is more than likely that we at least have to provide upstream patches to projects like PySerial so they can recognize the names we've chosen. Comment Actions Fixed names - yes, but there is something missing in the USB specification, that you can give your own name to USB devices. --HPS |