Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On some printers the libusb-based "usb" CUPS backend needs to send a reset signal to the printer #3964

michaelrsweet opened this issue Oct 19, 2011 · 5 comments


Copy link

@michaelrsweet michaelrsweet commented Oct 19, 2011

Version: 1.5.0 User: till.kamppeter


The problem happens on Ubuntu Oneiric which uses CUPS 1.5.0. This is the first Ubuntu release which deprecates (blacklists) the usblp kernel module and uses a purely libusb-based "usb" CUPS backend.

The bug happens only for some printer models, including the Samsung ML-2250, ML-2570, and the OKI B410d. The Dymo label writer 450 is not affected. If the problem occurs it occurs with all drivers, PostScript, PCL, HPLIP, Ghostscript, ..., so it is not driver-specific.

The problem is that after the printer has printed a job its USB interface is not in the same state as before printing the job. Sending a second job, even if it is absolutely identical with the first job, leads to garbage being printed. Users report to work around this they have to turn off and turn on the printer or unplug and replug the USB cable before each print job so that the jobs get printed correctly.

A workaround was found by sending a USB reset (USBDEVFS_RESET IOCTL) to the /dev/bus/usb/XXX/YYY file representing the printer using a little C program (attached, compile with "gcc -o usbreset usbreset.c", then run "./usbreset /dev/bus/usb/XXX/YYY" as root or with "sudo") between jobs.

So a possible fix would be to let the "usb" CUPS backend send this IOCTL before (or after?) each job. The C code does not need any special library (not even libusb), so the code can be added without introducing new dependencies.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Oct 20, 2011 User: till.kamppeter

Attached is a patch for backend/usb-libusb.c. It makes a printer reset, equivalent to the small C program which I attached in the beginning (I checked the source code of libusb) before each job. After the reset I close the device and reinitialize the connection (simple reopen does not work), as otherwise some printers (I tested with 5 different HP printers) crash and reboot and/or drop the job.

Now all printers print reliably and one does not perceive any additional delay between jobs.

I am applying the patch to the Ubuntu package of CUPS and let the original bug reporter test whether it solves his problem.

Note that the patch is set up to get a quick testing and can perhaps be done in a more elegant way by someone who is more knowledgeable about USB than me.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Oct 21, 2011 User: henry128


I just posted STR #3965 for a very similar problem, except that I got ignored print jobs (not gibberish), and usb_reset() caused me even more problems.

I think it may solve your problem as well. I compared the USB trace between the usblp and libusb backends, and then made the libusb backend behave almost identically to usblp.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Nov 11, 2011 User: till.kamppeter

This patch is actually not needed and perhaps too invasive. The reporter of the Ubuntu bug

has tested the patch of STR #3965 and it is absolutely sufficient. There are also no known regressions reported by other Ubuntu users.

So the patch of this STR can be dropped in favor of the patch of STR #3965.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Jan 27, 2012 User: mike

Closing per Till's last comments.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Jan 27, 2012


--- backend/usb-libusb.c~   2011-06-15 01:03:29.000000000 +0200
+++ backend/usb-libusb.c    2011-10-20 11:56:15.101500474 +0200
@@ -32,6 +32,7 @@
 #include <usb.h>
 #include <poll.h>
 #include <cups/cups-private.h>
+#include <linux/usbdevice_fs.h>

@@ -119,6 +120,27 @@

+ /*
+  * Reset printer device ...
+  */
+  if (usb_reset(printer->handle) < 0)
+  {
+    _cupsLangPrintFilter(stderr, "ERROR",
+            _("Unable to reset printer."));
+  }
+  /* we have to close and reopen the device after the reset, but
+     for reopening it we cannot do a simple "open_device(printer, 1)"
+     as with this some printers, like the HP LaserJet 3390, crash and
+     reboot and the job gets dropped. Therefore we need to reinitialize
+     the connection by calling "find_device(print_cb, uri)" again. */
+  close_device(printer);
+  while ((printer = find_device(print_cb, uri)) == NULL)
+  {
+    _cupsLangPrintFilter(stderr, "INFO",
+            _("Waiting for printer to become available."));
+    sleep(5);
+  }

   * If we are printing data from a print driver on stdin, ignore SIGTERM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant
You can’t perform that action at this time.