Menu

#622 DNP DS620 (1452:8b01) intermittently fails with LIBUSB_ERROR_ACCESS (-3) during concurrent print jobs

open
DS620 (1)
5
3 hours ago
6 days ago
No

Bug Description
Environment
Printer: DNP DS620 (USB VID:PID 1452:8b01)

System: OpenWrt (Linux), CUPS 2.4.x, Gutenprint 5.3.6-pre Commit [093342] master (selphy_print backend)

CUPS backend: Runs as root (no user permission issues)

Kernel module: usblp is manually configured to ignore this device (to avoid driver conflict)

Problem
When multiple print jobs are submitted within a short time (e.g., a batch of photos), the backend occasionally fails to open the printer and logs:

text
ERROR: Could not open device 1452:8b01 - -3 (need to be root?)
The error code -3 corresponds to LIBUSB_ERROR_ACCESS. After this failure, the job is aborted and the printer stops responding until the backend is restarted (or the printer is power‑cycled).

The issue is intermittent – it does not occur with every job, but becomes more frequent under concurrent load (e.g., when CUPS spawns multiple backend processes simultaneously).

Root Cause Analysis
The problem is likely a race condition when multiple selphy_print backend processes try to libusb_open() the same USB device at the same time.

The backend’s probe_device() and main() both call libusb_open() without any retry mechanism for LIBUSB_ERROR_ACCESS or LIBUSB_ERROR_BUSY.

Under normal conditions, libusb_open() may fail if another process already has the device open, or if the kernel’s usbfs layer temporarily returns -EACCES during device re‑enumeration or driver detachment.

The kernel driver usblp is already blocked for this VID/PID, but the device may still be temporarily grabbed by other kernel modules (e.g., usb-storage for the printer’s card reader) or by another backend instance performing a scan.

Suggested Fix
The CUPS native usb backend (usb-libusb.c) handles such transient errors by retrying the whole device enumeration with a sleep(5) loop when find_device() returns NULL. A similar approach could be applied to the backend_common.c of selphy_print:

Implement a retry wrapper around libusb_open()
When the open fails with LIBUSB_ERROR_ACCESS or LIBUSB_ERROR_BUSY, wait a short time (e.g., 2 seconds) and retry up to a certain number of attempts.

Aggressively detach all kernel drivers
Immediately after a successful libusb_open(), detach the kernel driver from every interface of the device (not just the printer interface) to prevent non‑printer drivers from holding the device.

Add a small random delay during device scanning
In find_and_enumerate(), introduce a random sleep (0–500 ms) before probing each device. This reduces the probability that two parallel scanning processes collide on the same device.

A prototype of these changes (tested on OpenWrt) resolved the intermittent failures for me. I would be happy to submit a patch if the approach is acceptable.

Steps to Reproduce
Connect a DNP DS620 (1452:8b01) to an OpenWrt box running Gutenprint 5.3.x.

Ensure CUPS is configured with User root and that usblp does not claim the printer.

Submit several print jobs simultaneously (e.g., lp -d printer file1.jpg file2.jpg file3.jpg).

Observe the CUPS error log (/var/log/cups/error_log). After a few attempts, a job will fail with “Could not open device … -3”.

Additional Information
The problem persists even when MaxActiveJobs 1 is set in cupsd.conf, indicating that the race is not solely caused by concurrent jobs – a single scanning pass can also hit the error if the device is still settling after a previous close.

The printer works flawlessly when using the generic CUPS usb backend (with usblp enabled), but that backend cannot perform the rewinding and media‑saving features required for DNP’s dye‑sub printers.

Please let me know if you need logs or further details. I’m willing to help test any proposed fix or provide a clean patch.

1 Attachments

Related

Commit: [093342]

Discussion

  • Solomon Peachy

    Solomon Peachy - 2 days ago

    An 'EACCES' error is an OS permission problem, and to me seems like the USB port/cable is flaky, leading to the printer being repeatedly re-enumerated on the bus with udev not being able to fix up permissions before it is accessed by CUPS. That said, CUPS will access it as root anyway, so it's not clear why EACCES would ever be an issue.

    As for BUSY, that could indeed happen if multiple things try to probe the printer simultaneously, but that shouldn't be happening either as CUPS serializes all access to a given printer. When a job is submitted to the printer, the backend returns as soon as the printer accepts it. If another job is submitted when the first is still being printed, the backend will attach, then send it to the printer if there are sufficient buffers, otherwise it will block (ie not return BUSY) until buffers are available. If another process tries to access this printer at the same time, that other process will return BUSY.

    But there shouldn't be anything else trying to access this printer, certainly not multiple backend instances in parallel. Are perhaps you using multiple queues for the same physical printer? If so, why?

     
  • XiaoMing Wang

    XiaoMing Wang - 3 hours ago

    I have confirmed that the issue was related to my backend permission settings, and it has been resolved. Thank you very much. You can close it now

     

Log in to post a comment.

MongoDB Logo MongoDB