[argyllcms] Re: argyll v0.60.2 usb assignments

  • From: Graeme Gill <graeme@xxxxxxxxxxxxx>
  • To: argyllcms@xxxxxxxxxxxxx
  • Date: Sat, 18 Nov 2006 16:25:30 +1100

Caspar Maessen wrote:
And this works:

caspar@casco:~> ls -l /dev/bus/usb/004/004
crw-rw-rw- 1 root root 189, 387 2006-11-17 21:26 /dev/bus/usb/004/004

caspar@casco:~> dispcal -
<...>
-c listno 1 = 'usb:/bus0/dev4 (Xrite DTP94)'
    2 =
<...>

Excellent !

But now I'm curious about how this works. I'll try and give my explanation. Please correct where I'm wrong, or complete:

SYSFS{idVendor}=="0765", SYSFS{idProduct}=="d094",
  This is the recognition part. By these two codes the udev-system
  recognizes the fact that the Xrite DTP94 was plugged in.

Yes. The original script in 
<http://www.mail-archive.com/avr-chat@xxxxxxxxxx/msg00902.html>
is setup with SUBSYSTEM=="usb_device", so that it creates these names for
all USB devices. We're being a bit more selective here. Perhaps some 
installations
of libusb install this general line in the udev rules ?

PROGRAM="/bin/sh -c 'K=%k; K=$${K#usbdev}; \
printf bus/usb/%%03i/%%03i $${K%%%%.*} $${K#*.}'",
  This is the external program that will be executed.
  In this case a series of commands executed in the shell, starting
  with assigning the variable K the value of the kernelname of the
  device. Then from the front of the string "usbdev" is being removed.
And the remaining is handeled with the formatted print-command. The output is assigned to the udev-substitution $result or %c.

Right, the kernel name must encode the bus and device numbers, so they
get extracted from the "usbdev4.4" string with the "${K%.*}" and "${K#*.}"
expressions.

NAME="%c", MODE="666"
  The result of the previous program is the name of the node to be
  created (or has been created in an earlier stage?) and will be given
  the attributes "666" or "rw-rw-rw-".

Yes, %c is the output of the shell script, so the udev node is created with
the "/dev/bus/usb/004/004" name and "666" permissions.

libusb looks for /dev/bus/usb/00N/00M first, or /proc/bus/usb/00N/00M
second, so now it works. A way of fixing this so that the
shell script isn't needed, would be to make libusb look for
"/dev/usbdevN.M" ahead of both of those, so that a simple
NAME="%k" would work.

What I can't figure out is the format in the printf command. It is given two arguments created form the K-variable by means of substring removal. But what is /%%03i/%%03i doing in the format. I referenced the man- and info-page, but couldn't find an explanation.

It's using the printf utility, which operates like the standard C printf(),
so the format expression %03i is for integer, 3 digits with leading '0's,
creating the '004' and '004'.

Another approach I've come across doesn't use printf:

PROGRAM="/bin/sh -c 'X=%k; X=$${X#usbdev}; B=$${X%%%%.*}; D=$${X#*.}; echo 
bus/usb/$$B/$$D'"

So it seems like this problem solved (for the moment!).

udev on my system seems to be an early version, it doesn't accept
the "==" syntax, and also complains if the rule isn't on one line.
It also doesn't work.
Hopefully such systems aren't a problem, as hotplug works on them.

Graeme Gill.


Other related posts: