NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/60321: opening ulptN (ulpnN) for certain printers fails with EBUSY
>Number: 60321
>Category: kern
>Synopsis: opening ulptN (ulpnN) for certain printers fails with EBUSY
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Jun 10 19:35:00 +0000 2026
>Originator: Ivan Shmakov
>Release: NetBSD 10.1
>Organization:
Dbus-free station.
>Environment:
Architecture: x86_64
Machine: amd64
>Description:
Certain printers do not seem to be usable with ulpt(4) as of
NetBSD 10.1. In an irc://irc.libera.chat/%23netbsd discussion
(2026-06-09 19:50 .. 21:27 UTC) it has been suggested that the
problem has long been solved in other USB printer interface
implementations, in particular OpenBSD ulpt.c (see below.)
For an example, attaching HP LaserJet 1020 gives:
$ /sbin/dmesg | tail -n3
[ 136251,756150] ulpt0 at uhub0 port 2 configuration 1 interface 0
[ 136251,756150] ulpt0: Hewlett-Packard (0x03f0) HP LaserJet 1020 (0x2b17),
rev 2.00/1.00, addr 2, iclass 7/1
[ 136251,756150] ulpt0: using bi-directional mode
$ /sbin/drvctl -tl -- ehci0
usb1
uhub0
ulpt0
$
Actually attempting to interact with the device, however,
inevitably fails after what appears to be a driver timeout of a few
minutes. Among the commands tried were (for ulpn0, ulpt0 both):
$ time -- cp -- sihp1020.image /dev/ulpn0
cp: /dev/ulpn0: Device busy
real 340,87
user 0,01
sys 0,00
$ time -- dd if=sihp1020.image of=/dev/ulpn0
dd: /dev/ulpn0: Device busy
real 681,66
user 0,00
sys 0,01
$ time -- sh -exuc ": > /dev/ulpn0 "
sh: cannot create /dev/ulpn0: error 16
real 340,93
user 0,01
sys 0,00
$
(The printer requires an executable image to be sent to it
before it can actually be used; sihp1020.image is a copy of
such an image produced with arm2hpdl(1) from foo2zjs.)
The corresponding $ ps -o pid,stat,wchan,etime,args -x output
(individual lines observed at different times - no two commands
were running at the same time):
499 D usbxfer 4:36 cp -- sihp1020.image
5943 D usbxfer 9:52 dd if=sihp1020.image of=/dev/ulpn0
4663 D usbxfer 0:03 sh -exuc : > /dev/ulpn0
It was suggested that crash(8) is used to examine KVM state
for one of the processes above, which confirmed that it is
indeed at open(2) that the driver "hangs":
# crash
crash> bt/t 0t5943
trace: pid 5943 lid 5943 at 0xffff958075800a00
sleepq_block() at sleepq_block+0x13a
cv_wait() at cv_wait+0xb7
usbd_transfer() at usbd_transfer+0x2fa
usbd_do_request_len() at usbd_do_request_len+0xaa
usbd_do_request() at usbd_do_request+0x21
ulpt_status.isra.0() at ulpt_status.isra.0+0x33
ulptopen() at ulptopen+0xf5
cdev_open() at cdev_open+0x12b
spec_open() at spec_open+0x1e0
VOP_OPEN() at VOP_OPEN+0x3e
vn_open() at vn_open+0x2ec
do_open() at do_open+0xc3
do_sys_openat() at do_sys_openat+0x74
sys_open() at sys_open+0x24
syscall() at syscall+0x1fc
--- syscall (number 5) ---
syscall+0x1fc:
crash>
Following that, this OpenBSD Git commit was found:
commit a6eefab672c88d16a09bd086c54a1cd8998d802e
Author: deraadt <deraadt%openbsd.org@localhost>
Date: Thu Oct 9 01:07:02 2008 +0000
stop waiting for the printer to become ready, see PR 5427 for more
information. Also explains PR 4124 and 5318
[PR 5427] http://marc.info/?l=openbsd-bugs&m=117512145315766&w=2 [LJ 1022]
[PR 5318] http://marc.info/?l=openbsd-bugs&m=116503185421666&w=2 [FS-1030D]
[PR 4124] http://marc.info/?l=openbsd-bugs&m=110939774409572&w=2 [HL1440]
>How-To-Repeat:
Attach an affected USB printer, such as HP LaserJet 1020,
then try to open the corresponding ulptN or ulpnN device:
the open(2) call will wait for a while in usbxfer, then fail
with EBUSY.
>Fix:
The patch suggested in OpenBSD [PR 5427] can be applied to
NetBSD ulpt.c (as of 11 RC4) with little modification.
I haven't tested it, though.
--- usr/src/sys/dev/usb/ulpt.c.~1~ 2025-04-14 16:43:00 +0000
+++ usr/src/sys/dev/usb/ulpt.c 2026-06-10 18:58:22 +0000
@@ -436,7 +436,7 @@ ulptopen(dev_t dev, int flag, int mode,
u_char flags = ULPTFLAGS(dev);
struct ulpt_softc *sc;
usbd_status err;
- int spin, error;
+ int error;
sc = device_lookup_private(&ulpt_cd, ULPTUNIT(dev));
if (sc == NULL)
@@ -455,24 +455,8 @@ ulptopen(dev_t dev, int flag, int mode,
error = 0;
sc->sc_refcnt++;
- if ((flags & ULPT_NOPRIME) == 0)
+ if ((flags & ULPT_NOPRIME) == 0) {
ulpt_reset(sc);
-
- for (spin = 0; (ulpt_status(sc) & LPS_SELECT) == 0; spin += STEP) {
- DPRINTFN(2, ("ulpt_open: waiting a while\n"));
- if (spin >= TIMEOUT) {
- error = EBUSY;
- sc->sc_state = 0;
- goto done;
- }
-
- /* wait 1/4 second, give up if we get a signal */
- error = kpause("ulptop", true, STEP, NULL);
- if (error != EWOULDBLOCK) {
- sc->sc_state = 0;
- goto done;
- }
-
if (sc->sc_dying) {
error = ENXIO;
sc->sc_state = 0;
Home |
Main Index |
Thread Index |
Old Index