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

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

Closed
michaelrsweet opened this Issue Oct 19, 2011 · 5 comments

Comments

Projects
None yet
1 participant
Collaborator

michaelrsweet commented Oct 19, 2011

Version: 1.5.0
CUPS.org User: till.kamppeter

See

https://bugs.launchpad.net/ubuntu/+source/cups/+bug/872483

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.

Collaborator

michaelrsweet commented Oct 20, 2011

CUPS.org 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.

Collaborator

michaelrsweet commented Oct 21, 2011

CUPS.org User: henry128

Hi,

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.

Collaborator

michaelrsweet commented Nov 11, 2011

CUPS.org User: till.kamppeter

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

https://bugs.launchpad.net/ubuntu/+source/cups/+bug/872483

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.

Collaborator

michaelrsweet commented Jan 27, 2012

CUPS.org User: mike

Closing per Till's last comments.

Collaborator

michaelrsweet commented Jan 27, 2012 edited

"usb-backend-reset-printer-before-printing.patch":

--- 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 @@
     sleep(5);
   }

+ /*
+  * 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

@michaelrsweet michaelrsweet added this to the Stable milestone Mar 17, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment