After a recent update to FreeBSD 8, my USB attached HP LaserJet 1320 stopped printing via CUPS. No hint at all why, and /var/log/cups/error_log was of no help either. Print jobs simply accumulated in the print queue, but there was no LED blinking on the printer. Sending PostScript directly to /dev/ulpt0 worked, but sending it via CUPS didn’t do any good.

After a lot of head scratching, I went so far as to delete the old printer in CUPS (which worked), and was in for a nasty surprise: CUPS didn’t recognize the locally attached printer when I tried to add it again.


After installing the print/cups-base port, a message advises to set the right permissions for the printer device nodes by adding some lines to /etc/devfs.rules:

add path 'unlpt*' mode 0660 group cups
add path 'ulpt*' mode 0660 group cups
add path 'lpt*' mode 0660 group cups

Well, they were there already from a previous installation of CUPS, and the perms were as they should’ve been (double checked it with ls -l /dev). What I didn’t paid attention to was this little paragraph at the end of the pkg-descr:

If you are using libusb, it is important that no device driver, e.g.
ulpt(4) is attached to the device you wish to use. In this case please
ensure the cups user and group has read/write access to /dev/ugen*

Now that’s pretty nasty. The GENERIC kernel does indeed attach ulpt(4) to the printer as soon as the latter is turned on, and building a custom kernel just to be able to print was not really practical. But setting the permissions on the exact ugen devices was a good idea anyway. But which one of the ugen devices would that be? dmesg to the rescue:

ugen1.2: <Hewlett-Packard> at usbus1
ulpt0: <Hewlett-Packard hp LaserJet 1320 series, class 0/0, rev 1.10/1.00, addr 2> on usbus1
ulpt0: using bi-directional mode

So it was /dev/ugen1.2 on my machine. Adding the line

add path 'ugen1.2' mode 0660 group cups

to /etc/devfs.rules and restarting devfs with /etc/rc.d/devfs restart changed the permissions alright:

# ls -l /dev/ugen*
lrwxr-xr-x  1 root  wheel  9 Feb  2 14:50 /dev/ugen0.1 -> usb/0.1.0
lrwxr-xr-x  1 root  wheel  9 Feb  2 14:50 /dev/ugen1.1 -> usb/1.1.0
lrw-rw----  1 root  cups   9 Feb  2 16:50 /dev/ugen1.2 -> usb/1.2.0
lrwxr-xr-x  1 root  wheel  9 Feb  2 14:50 /dev/ugen2.1 -> usb/2.1.0
lrwxr-xr-x  1 root  wheel  9 Feb  2 14:50 /dev/ugen3.1 -> usb/3.1.0
lrwxr-xr-x  1 root  wheel  9 Feb  2 14:50 /dev/ugen4.1 -> usb/4.1.0
lrwxr-xr-x  1 root  wheel  9 Feb  2 14:50 /dev/ugen5.1 -> usb/5.1.0
lrwxr-xr-x  1 root  wheel  9 Feb  2 14:50 /dev/ugen6.1 -> usb/6.1.0

However, CUPS was still not able to see the new printer, even after restarting the CUPS daemon with /usr/local/etc/rc.d/cupsd restart. Obviously, something was still missing.

The solution (and the only reason for this post), is that it is not enough to set the permissions on the symlink: one also needs to set the permissions on the linked-to file (in this case /dev/usb/1.2.0), or cupsd won’t be able to see the local printer. So adding yet another line to /etc/devfs.rules:

add path 'usb/1.2.0' mode 0660 group cups

and restarting both devfs and cupsd did the trick. CUPS is now able to see the new printer, and printing via /usr/local/bin/lpr works as previously.


  1. Bill Tillman

    I have the same problem with my setup. I recently got rid of an old server which had a parallel port and it served my entier LAN for years as print server using apsfilter and lpd method. This worked fine but my new server did not have a parallel port so I hooked up my Brother-HL-2040 printer’s USB port to the new server. I tried to install apsfilter but the hpijs port is broken. So I said might as well finally learn how to set this up with cupsd.

    My problem is that at one time I saw the ugen* device in my dmesg but it’s not there now. The only thing I see is the ulpt0 device and it clearly shows that if finds the Brother-HL-2040 printer on the other end of the USB cable. I set the permissions like you referenced in the first step but had no need for the ugen since it’s not there…or is it.

    Cups web interface runs well but it won’t find the printer. So I set it up manually and loaded a ppd file for the HL-2040 laser printer. But I can send jobs to it all night and nothing will print. No errors messages appear in the logfiles either.

  2. Just a couple of checks:
    1.) Is that on 8.0-STABLE or 7-STABLE?
    2.) Have you really double-checked that no ugen device appears?
    3.) … esp. if you turn the printer off and on again? What does dmesg say exactly?

    I’m asking this because 8-STABLE has a new USB stack, and those nested paths are 8-STABLE only.

  3. Bill Tillman

    Yes, it’s FreeBSD-8.0-STABLE. On the one server no ugen device exists.

    FreeBSD1# dmesg | grep ugen

    This is strange because I’m pretty sure I saw ugen appear on this machine yesterday.

    I have another machine right next to it running 8.0-STABLE which was make buildworld yesterday morning. On this machine I see:

    BigDell# dmesg | grep ugen
    ugen0.1: at usbus0
    ugen1.1: at usbus1
    ugen0.2: at usbus0
    ugen0.3: at usbus0

    I tried to set this up with lpd and /etc/printcap first. The print jobs still go off into hyperspace and nothing shows up in the log. Just to be sure the printer and the USB cable are working I hooked them both up to my Windows Vista computer. In less than 30 seconds the computer saw the printer, installed the correct driver and I printed two nice pages from a PDF file. So the equipment works. It’s some issue within FreeBSD I can’t put my hands around that’s causing this to fail.

    I retried the method defined above and it failed again to find the printer. The part I get so disgruntled with is how easy it is for Windows and Linux to do these simple printing tasks and with FreeBSD it takes an act of congress to get it through.