hybrid usb backend doesn't work with usblp if printer needs to load firmware (HP LJ 1000/1005/1018/1020/P100x/...)

Reported by Kevin Goodsell on 2010-03-21
This bug affects 1 person
Affects Status Importance Assigned to Milestone
foo2zjs (Ubuntu)

Bug Description

Binary package hint: cups

This is in Ubuntu 9.10, with CUPS version 1.4.1-5ubuntu2.4.

The first symptom of the problem is that the printer is not discovered. Invoking the usb backend directly shows the same:

0$ sudo /usr/lib/cups/backend/usb
DEBUG: list_devices_libusb
DEBUG: usb_find_busses=2
DEBUG: usb_find_devices=5

Running this in strace reveals a few things. The device is on bus 1, id 100:

0$ sudo lsusb
Bus 002 Device 002: ID 046d:c51a Logitech, Inc. MX Revolution/G7 Cordless Mouse
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 100: ID 03f0:2b17 Hewlett-Packard LaserJet 1020
Bus 001 Device 099: ID 04cc:1520 Philips Semiconductors
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
0$ ls -l /dev/bus/usb/001/
total 0
crw-rw-r-- 1 root root 189, 0 2010-03-20 14:15 001
crw-rw-r-- 1 root root 189, 98 2010-03-20 20:28 099
crw-rw---- 1 root lp 189, 99 2010-03-20 21:02 100

From the trace, when an attempt is made to configure this device in the libusb part of the hybrid backend, an EBUSY error is encountered:

open("/dev/bus/usb/001/100", O_RDWR) = 3
ioctl(3, USBDEVFS_SETCONFIGURATION, 0xbfe38e24) = -1 EBUSY (Device or resource busy)
ioctl(3, USBDEVFS_CLAIMINTERFACE, 0xbfe38e24) = -1 EBUSY (Device or resource busy)
close(3) = 0

This seems to be because the device has been claimed by usblp. Next, the usblp part of the backend tries to discover the device:

open("/dev/usblp0", O_RDWR|O_EXCL|O_LARGEFILE) = 3
ioctl(3, SNDCTL_DSP_SYNC, 0xbfe397ad) = -1 EIO (Input/output error)
close(3) = 0

For some reason, the ioctl here is failing (ignore the ioctl name, it's not accurate). My best guess is that the earlier fidgeting with the USB device left it in a bad state. The failure of this ioctl seems to be the core cause of the discovery failure. After this occurs in the trace, the usblp backend runs through several more possible lp device names, all producing ENOENT, before giving up.

So, moving from the strace to the failing ioctl, it seems clear that this is the LPIOC_GET_DEVICE_ID call in backendGetDeviceID from ieee1284.c (which is invoked from list_devices_unix in the hybrid backend). I dove into the kernel code to see if I could figure out why it would return EIO.

The implementation of this ioctl is found in drivers/usb/class/usblp.c:


It looks to me like it can only return EIO if the call to usblp_cache_device_id_string returns EIO, which it will do if usblp_get_id fails for any reason. usblp_get_id's return value boils down to the return value from usb_control_msg, so this is probably what is failing.

That's all I've got so far.

Related branches

Kevin Goodsell (kevin-goodsell) wrote :
Kevin Goodsell (kevin-goodsell) wrote :

I've found some additional details about this problem. First, if I stop the CUPS service before I turn on the printer the probe works fine, and locates the printer as a usblp device. I can then start CUPS and print without issue (I assume... I'm not actually wasting paper testing this, since the failure to discover the printer is the primary issue).

This, and some additional testing, suggest that the problem is related to the timing of the probe. The printers in this line lack the internal memory to store their firmware, and instead load the firmware when they are first turned on or connected. It's obvious to the user when this is happening because the printer noisily "runs" while the firmware loads (the paper rollers turn, I guess). This takes a good 5 or 6 seconds.

I'm hypothesizing that probing the printer while the firmware is loading causes the problem. Maybe it even corrupts the firmware.

Further investigation pending.

Till Kamppeter (till-kamppeter) wrote :

I have done a short test:

1. If the printer is up and running with loaded firmware, discovery works perfectly, like with a printer with built-in firmware.

2. If you load the firmware, for example by turning it on, and probe the printer during firmware transfer, it once does not get detected and second, the firmware gets corrupted and so the printer does not get detected after the firmware transfer, too. You have to turn it off and on again and then to wait for the firmware transfer to complete, so that 1. applies.

3. You should not install the firmware for both foo2zjs and HPLIP, either you run "sudo hp-plugin" (will be started automatically under Lucid) or "sudo getweb 1020", never both. If you do both, two copies of the firmware are loaded into the printer simultaneously, which also corrupts the firmware. To solve this, remove one copy, for example via "sudo rm /usr/share/foo2zjs/firmware/*". Then turn off and turn on the printer again, wait for the firmware transfer to complete, and 1. will apply. It is no problem if the firmware got installed via HPLIP and the driver if foo2zjs or vice versa.

One would need a way to make the printer probe wait if the printer receives firmware. To protect the firmware transfer against the automatic probe which happens directly after turning on the printer HPLIP's udev script for loading the firmware has a three-second delay.

summary: - hybrid usb backend doesn't work with usblp
+ hybrid usb backend doesn't work with usblp if printer needs to load
+ firmware (HP LJ 1000/1005/1018/1020/P100x/...
summary: hybrid usb backend doesn't work with usblp if printer needs to load
- firmware (HP LJ 1000/1005/1018/1020/P100x/...
+ firmware (HP LJ 1000/1005/1018/1020/P100x/...)
Kevin Goodsell (kevin-goodsell) wrote :

Till, I think your findings agree with mine (though I know nothing about using hplip to load the firmware, and I don't know how to confirm the firmware-corruption hypothesis), except possibly on one point in #2: It seems that if you turn the printer off and back on, the firmware will just be corrupted again, assuming the CUPS daemon is running. Were you implying otherwise?

I've done additional tests simulating the behavior of the hybrid backend with a Python script, and I've found that it's actually the usblp probe that introduces the problem. Without that, it's fine. This is strange because usblp is how it was done in the past, so what has actually changed? It could be changes in the hybrid backend, or changes in the usblp backend from previous versions of CUPS. Or my analysis could be wrong, of course.

Kevin Goodsell (kevin-goodsell) wrote :

I rebuilt CUPS with the usblp backend and I can still produce this problem. I don't think it has anything to do with the hybrid backend, it's just the usblp part. Why it's a problem now and wasn't with previous CUPS versions, I don't know.

Till Kamppeter (till-kamppeter) wrote :

Kevin, how did you install the firmware on your computer? Did you run foo2zjs'

sudo getweb 1020

or did you run HPLIP's

sudo hp-plugin (or sudo hp-setup)

Both methods download and install the firmware, but to different places and different UDEV scripts will be used to load the firmware into the printer. The HPLIP solution loads the firmware with 3 seconds of delay, so that any probing by CUPS happens before loading the firmware. foo2zjs' method loads the firmware immediately and so it comes to problems.

Run the following commands in a terminal window:

rm /usr/share/foo2zjs/firmware/*
sudo hp-plugin

Let HP's plugin get installed. Then turn off and turn on the printer, is it accessible? If not, remove your print queue and let it get auto-created again by turning off and turning on the printer again.

Till Kamppeter (till-kamppeter) wrote :

I have added such a 3-second delay also to the foo2zjs package in Lucid now (20100210-0ubuntu4), please try.

Changed in cups (Ubuntu):
status: New → Incomplete
Kevin Goodsell (kevin-goodsell) wrote :

I don't have HPLIP installed. I installed the firmware with getweb. I also added a 3-second delay in foo2zjs's udev script which seems to have fixed the problem (though I don't do much printing, so if it fails intermittently I won't necessarily know right away).

Till Kamppeter (till-kamppeter) wrote :

Loading the firmware with a 3-second delay seems to solve the device access conflict. As I have added this delay to foo2zjs and HPLIP already has the delay we can consider this bug as fixed.

affects: cups (Ubuntu) → foo2zjs (Ubuntu)
Changed in foo2zjs (Ubuntu):
status: Incomplete → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers

Bug attachments