# devd usb device with unique /dev/ name



## vrabac (Apr 22, 2012)

I am trying to set up devd to always create on boot/attach a unique /dev/ name which should be accessible from a normal user (0666 rights). I have on Linux an udev rule which is working just fine:

```
SUBSYSTEMS=="usb", ATTRS{idProduct}=="6001", ATTRS{idVendor}=="0403", ATTRS{product}=="Reader*", SYMLINK+="$attr{product}", KERNEL=="ttyUSB*", MODE="0666"
```
It creates a device names Reader1-4 in /dev/ based on the above matches.

I would like to do the same on FreeBSD 9.0, and so far *I* could only do a match rule and put something to logger. Actually the creating part which I found on [1] isn't working as device/file not found which is OK as it looks wrong.

Here is config and *devd -Dd* output for this specific device.

```
%cat /usr/local/etc/devd/readers.conf
attach 100 {
        match "vendor" "0x0403";
        match "product" "0x6001";
        match "sernum" "A8003YTe";
#        action "logger $device-name $sernum";
        action "usb_devaddr=`echo $device-name | sed 's#^ugen##'` && \
                chown root:wheel /dev/usb/${usb_devaddr}.* && \
                chmod 0660 /dev/usb/${usb_devaddr}.* && \
                ln -s /dev/usb/${usb_devaddr} /dev/Reader4";
};
```
The first action was only for test purpose to see if matching is actually working. And it is: 
	
	



```
Executing 'logger uftdi1 A8003YTe'
```

*devd -Dd* output when device is inserted:

```
Popping table
Processing event '+uftdi1 at bus=2 hubaddr=2 port=1 devaddr=4 interface=0 vendor=0x0403 product=0x6001 devclass=0x00
 devsubclass=0x00 sernum="A8003YTe" release=0x0600 mode=host intclass=0xff intsubclass=0xff intprotocol=0xff  ttyname=U1
 ttyports=1 on uhub2'
Pushing table
setting device-name=uftdi1
setting bus=2
setting hubaddr=2
setting port=1
setting devaddr=4
setting interface=0
setting vendor=0x0403
setting product=0x6001
setting devclass=0x00
setting devsubclass=0x00
setting sernum=A8003YTe
setting release=0x0600
setting mode=host
setting intclass=0xff
setting intsubclass=0xff
setting intprotocol=0xff
setting ttyname=U1
setting ttyports=1
setting bus=uhub2
Processing attach event
Testing device-name=uftdi1 against ^ed50
Testing device-name=uftdi1 against ^ubt[0-9]+
Testing device-name=uftdi1 against ^ukbd0
Testing device-name=uftdi1 against ^ums[0-9]+
Testing vendor=0x0403 against ^0x0854
Testing vendor=0x0403 against ^0x1645
Testing vendor=0x0403 against ^0x0403
Testing product=0x6001 against ^0x6001
Testing sernum=A8003YTe against ^A8003YTe
Executing 'usb_devaddr=`echo uftdi1 | sed 's#^ugen##'` && chown root:wheel /dev/usb/${usb_devaddr}.* && chmod 0660
 /dev/usb/${usb_devaddr}.* && ln -s /dev/usb/${usb_devaddr} /dev/Reader4'
chown: /dev/usb/uftdi1.*: No such file or directory
Popping table
```
As the error points it looks in /dev/usb/ for $device-name which doesn't exist. What I found with usbconfig is that the $device-name is:

```
%usbconfig -u 1 -a 4 dump_device_desc
ugen1.4: <Reader4 FTDI> at usbus1, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON
```

So the ugen1.4 is device name which is a symlink to ugen1.4 -> usb/1.4.0. Should here as default /dev/usb/$device-name be created or something else is wrong.

Any help is welcome, as *I* don't have idea anymore.

Summary:
ftdi USB reader -> USB hub -> USB port on ALIX.3D3 running on FreeBSD 9.0.
Goal:
Create from $sernum unique /dev/ name which will be done on boot and on attach. Is this with boot possible to do with devd at all?
Give user permission to this unique device name (0666) or create group with this rights and assign user to that group.
Enjoying in FreeBSD 

[1] http://forums.freebsd.org/showpost.php?p=102179&postcount=5


----------



## Sunsun (Jun 10, 2012)

Hello!
Do you have any progress in this problem? I have the same problem.


----------



## Moosfet (Dec 11, 2012)

I've been using a similar rule in Linux for quite some time:

ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", NAME="FTDI/$attr{serial}", MODE="666"

The nicest thing about this is that it puts all the devices in a folder, "/dev/FTDI/", and it will respect any "/" characters in the serial number.  So I made the serial numbers on my devices in the form of "device/serial" where each device of the same type has the same device code, but each device has a unique serial code.  This way scripts that work with different devices can just automatically find "/dev/FTDI/whatever/*" and only bother me about specifying the specific device if they find more than one device of the same type is present.

Unfortunately, in FreeBSD, you can't create directories in /dev/, and the "/" is stripped from my serial numbers for some reason.  Bummer.  Time to come up with a new scheme I guess.

Anyway, assuming you just want to create a symlink in /dev/ that points to the correct device, this seems to work:


```
attach 1000 {
  match "vendor" "0x0403";
  match "product" "0x6001";
  action "stty raw -echo < /dev/cua$ttyname.init";
  action "stty raw -echo < /dev/tty$ttyname.init";
  action "stty raw -echo < /dev/cua$ttyname.lock";
  action "stty raw -echo < /dev/tty$ttyname.lock";
  action "ln -sf /dev/cua$ttyname /dev/$sernum";
};

notify 1000 {
  match "subsystem" "DEVICE";
  match "type" "DETACH";
  match "vendor" "0x0403";
  match "product" "0x6001";
  action "rm /dev/$sernum";
};
```

Note that I use the "stty" command to configure the devices to act as simple character devices rather than interfaces for terminals attached via a serial port.  This is certainly what everyone else will want to do as well, since no one has ever used one of these devices as a terminal, and having the kernel echo data back to the device will certainly only cause problems.  I don't think the commands will interfere with setting the baud rate and modem control signals on FTDI chips with those features, but if you find that stuff doesn't work, then you might want to try adjusting or removing the "stty" commands.


----------



## wblock@ (Dec 11, 2012)

vrabac said:
			
		

> *devd -Dd* output when device is inserted:
> 
> ```
> ...
> ...



Look at the device name there.  It is pointless to use sed(1) to remove ugen when it is not in the device name anyway.

So let's do only what needs to be done (untested):

```
action "chown root:wheel /dev/$device-name && \
        chmod 0660 /dev/$device-name && \
        ln -s /dev/$device-name /dev/Reader4";
```

While that will do what you are asking, I think it won't do what you want.  uftdi(4) is used with ucom(4), and probably you want to link to the /dev/cuaU0 device.



> [1] http://forums.freebsd.org/showpost.php?p=102179&postcount=5



That's from 2010.  I've posted recently on the same subject, but don't have a link handy, so do some searching here.


----------



## fonz (Dec 11, 2012)

wblock@ said:
			
		

> I've posted recently on the same subject, but don't have a link handy,


You mean this thread I presume?

Fonz


----------



## wblock@ (Dec 12, 2012)

Yes, that's the one--thanks!


----------



## Moosfet (Dec 12, 2012)

It's worth noting that for the FTDI devices, no "detach" event is generated when they are disconnected.  That is why I used a "notify" to remove the symbolic link.


----------

