# Configuring USB device with devd



## Linnet (Nov 19, 2020)

Hello,

I'm trying to get my Lauterbach USB debugger to work on FreeBSD 12.1. I have gotten the Trace32 software to work under linux emulation. The Trace32 software looks for /dev/lauterbach/trace32/1-1 which on linux is solved by a udev rule.

So, looking at the device shows this:

```
usbconfig -u 1 -a 7 dump_device_desc
ugen1.7: <Lauterbach Development Tools Lauterbach PODBUS USB Controller> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (0mA)

  bLength = 0x0012 
  bDescriptorType = 0x0001 
  bcdUSB = 0x0200 
  bDeviceClass = 0x0000  <Probed by interface class>
  bDeviceSubClass = 0x0000 
  bDeviceProtocol = 0x0000 
  bMaxPacketSize0 = 0x0040 
  idVendor = 0x0897 
  idProduct = 0x0002 
  bcdDevice = 0x0000 
  iManufacturer = 0x0001  <Lauterbach Development Tools>
  iProduct = 0x0002  <Lauterbach PODBUS USB Controller>
  iSerialNumber = 0x0000  <no string>
  bNumConfigurations = 0x0001
```
My thoughts here is to just add it in a similar way but with devd, if that's possible. The problem only seems to be how to re-write devfs with a link from ugen1.7 to lauterbach/trace32/1-1.

Would that work, and if, any suggestion on how to do it? I have no luck creating the subdirectory from devd (notify 0) though. 

Thanks,
/s


----------



## tingo (Nov 19, 2020)

It is very possible to use devd for that purpose. My examples only change permissions, but you get the idea.

```
root@kg-core2# more /usr/local/etc/devd/ulx3s.conf
# allow group (operator) to access the usb connection of ulx3s

notify 100 {
        match "system"          "USB";
        match "subsystem"       "INTERFACE";
        match "type"            "ATTACH";
        match "vendor" "0x0403";
        match "product" "0x6015";
        action "usb_devaddr=`echo $cdev | sed 's#^ugen##'` && chmod g+rw /dev/usb/${usb_devaddr}.*";
};
```
and

```
root@kg-core2# more /usr/local/etc/devd/dirtyjtag.conf
# allow group (operator) to access the usb connection of ulx3s

notify 100 {
        match "system"          "USB";
        match "subsystem"       "INTERFACE";
        match "type"            "ATTACH";
        match "vendor" "0x1209";
        match "product" "0xc0ca";
        action "usb_devaddr=`echo $cdev | sed 's#^ugen##'` && chmod g+rw /dev/usb/${usb_devaddr}.*";
};
```
hope this helps.


----------



## Linnet (Nov 20, 2020)

tingo said:


> It is very possible to use devd for that purpose. My examples only change permissions, but you get the idea.
> 
> ```
> root@kg-core2# more /usr/local/etc/devd/ulx3s.conf
> ...


It definetely got clearer to me, thanks for that tingo. 

Still though not clear to me how to make an accessible node in /dev for Trace32. Seems like I need to configure that with devfs, do you agree?


----------



## tingo (Nov 20, 2020)

why not create a link? something like this: 
	
	



```
action "ln -s $cdev /dev/lauterbach/trace32/1-1";
```
of course, you should check that it works as intended before deploying it - I haven't tested this. If you need to fix ownership and / or permissions of the link that can be done too.


----------



## Linnet (Nov 23, 2020)

The link is the problem. It works if there is in the same directory but not in a subdirectory like this is. I also tried make the dir manually but since /dev is not a "filesystem" per se my hopes where low. After digging some more it seems that devfs should be used for this.


----------



## George (Nov 23, 2020)

Yes, there is a devfs(5) file system mounted on /dev. `mkdir` or `touch` will not work here. 
There is mknod(8) to create files under /dev. The man file says that it is deprecated though.


----------



## Linnet (Nov 23, 2020)

Elazar said:


> Yes, there is a devfs(5) file system mounted on /dev. `mkdir` or `touch` will not work here.
> There is mknod(8) to create files under /dev. The man file says that it is deprecated though.


I read the same thing. Will try with mknod. But I guess that it could be solved with devfs somehow. Investigation ongoing. Thanks!

/s


----------



## tingo (Nov 23, 2020)

Linnet so `# mkdir -p /dev/lauterbach/trace32` doesn't work?


----------



## Linnet (Nov 23, 2020)

tingo said:


> Linnet so `# mkdir -p /dev/lauterbach/trace32` doesn't work?


Unfortunately no


----------



## Linnet (Nov 24, 2020)

Elazar said:


> Yes, there is a devfs(5) file system mounted on /dev. `mkdir` or `touch` will not work here.
> There is mknod(8) to create files under /dev. The man file says that it is deprecated though


That did not work via devd. I'm still puzzled if I need to write a device driver to create a node to be able to access the device.


----------



## George (Nov 24, 2020)

I have seen examples in Linux where they use udev to create a symlink under /dev/somefolder/, then use `mount`. devd() only has the option "action", which can execute a shell command.

Maybe you need a dummy driver that uses make_dev_s(9).
But generally, /dev is for driver <-> userland communication anyways.


----------



## Linnet (Nov 24, 2020)

Yeah.

If I understand it correctly:
1) Kernel informs devfs (boot or runtime) of loaded drivers (KLD) and how to populate devfs nodes
2) Apply devfs rules for specific drivers (create/re-create devfs mount) even for USB drivers
3) Devd for actions to perform on specific devices after devfs is done

If this is correct then one way is to write a specific "pass through" driver. Anyone can point to an example?


```
[stefan@spock ~]$ usbconfig -u 1 -a 5 dump_all_config_desc 
ugen1.5: <Lauterbach Development Tools Lauterbach PODBUS USB Controller> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (0mA)


 Configuration index 0

    bLength = 0x0009 
    bDescriptorType = 0x0002 
    wTotalLength = 0x0020 
    bNumInterfaces = 0x0001 
    bConfigurationValue = 0x0001 
    iConfiguration = 0x0000  <no string>
    bmAttributes = 0x00c0 
    bMaxPower = 0x0000 

    Interface 0
      bLength = 0x0009 
      bDescriptorType = 0x0004 
      bInterfaceNumber = 0x0000 
      bAlternateSetting = 0x0000 
      bNumEndpoints = 0x0002 
      bInterfaceClass = 0x0000  <Probed by interface class>
      bInterfaceSubClass = 0x0000 
      bInterfaceProtocol = 0x0000 
      iInterface = 0x0000  <no string>

     Endpoint 0
        bLength = 0x0007 
        bDescriptorType = 0x0005 
        bEndpointAddress = 0x0085  <IN>
        bmAttributes = 0x0002  <BULK>
        wMaxPacketSize = 0x0200 
        bInterval = 0x0000 
        bRefresh = 0x0000 
        bSynchAddress = 0x0000 

     Endpoint 1
        bLength = 0x0007 
        bDescriptorType = 0x0005 
        bEndpointAddress = 0x0006  <OUT>
        bmAttributes = 0x0002  <BULK>
        wMaxPacketSize = 0x0200 
        bInterval = 0x0000 
        bRefresh = 0x0000 
        bSynchAddress = 0x0000
```

Or hit me in the head if I'm totally off 

/s


----------



## Linnet (Nov 24, 2020)

Excellent explanation.



			Rethinking /dev and devices in the UNIX kernel


----------



## Linnet (Dec 9, 2020)

Update:

Sorry that this thread has become a "my space" kind of thingy. 

So, in the new versions of Trace32 software from Lauterbach a new feature was added that made it possible to define the device node name to look for.

However, on linux access goes through the infamous USBDEVFS or USBFS and /proc/usb which on FreeBSD is not supported. I have found some information about how to do this in userspace and there might even be possible to do this in a kernel driver. Regardless of kernel or user space a full compliance of USBDEVFS protocol should make this possible.

Anyone know of a driver that implements USBDEVFS support in either user or kernel?

/s


----------

