After submitting a print job and then turning on my USB printer I got: ulpt0 at uhub0 port 1 configuration 1 interface 0 "Hewlett-Packard HP LaserJet 1020" rev 2.00/1.00 addr 2 ulpt0: using bi-directional mode ulpt0: ucode upload error=IOERROR! ulpt0: could not load firmware 'ulpt-hp1020' uvm_fault(0xf388ac04, 0x0, 0, 1) -> e kernel: page fault trap, code=0 Stopped at usbd_transfer+0x13: movl 0x4(%edi),%eax ddb> trace usbd_transfer(d56362a0,0,0,f39ef000,d) at usbd_transfer+0x13 ulpt_do_write(d150e600,f39e7e9c,1,d03ff869,f39e7d2c) at ulpt_do_write+0xd6 ulptwrite(4000,f39e7e9c,1,d04f2dbb,f37d7b7c) at ulptwrite+0x5d spec_write(f39e7dc8,f38b71bc,f39e7ddc,d03ff869,f39e7dcc) at spec_write+0xad VOP_WRITE(f37d6838,f39e7e9c,1,f3909664,f388ac08) at VOP_WRITE+0x42 vn_write(d561b834,d561b850,f39e7e9c,f3909664,4faf4658) at vn_write+0x92 dofilewritev(d5488b98,5,d561b834,f39e7f04,1) at dofilewritev+0x194 sys_write(d5488b98,f39e7f60,f39e7f80,d056d895,d5488b98) at sys_write+0xa5 syscall() at syscall+0x24d --- syscall (number -809625138) --- 0x2: ddb>
With the following diff firmware load errors (which I triggered on purpose both by pulling the USB cable at the right time, and also by renaming the firmware file) are handled more gracefully: $ lpq waiting for lp to become ready (offline ?) Rank Owner Job Files Total Size 1st stsp 143 (standard input) 3 bytes $ tail /var/log/messages Oct 19 16:02:13 dougal /bsd: ulpt0: failed loadfirmware of file ulpt-hp1020 (error 2) Oct 19 16:02:13 dougal /bsd: ulpt0: could not load firmware 'ulpt-hp1020' Oct 19 16:02:29 dougal /bsd: ulpt0: failed loadfirmware of file ulpt-hp1020 (error 2) Oct 19 16:02:29 dougal /bsd: ulpt0: could not load firmware 'ulpt-hp1020' Oct 19 16:03:01 dougal /bsd: ulpt0: failed loadfirmware of file ulpt-hp1020 (error 2) Oct 19 16:03:01 dougal /bsd: ulpt0: could not load firmware 'ulpt-hp1020' Oct 19 16:03:33 dougal /bsd: ulpt0: failed loadfirmware of file ulpt-hp1020 (error 2) Oct 19 16:03:33 dougal /bsd: ulpt0: could not load firmware 'ulpt-hp1020' Oct 19 16:04:06 dougal /bsd: ulpt0: failed loadfirmware of file ulpt-hp1020 (error 2) Oct 19 16:04:06 dougal /bsd: ulpt0: could not load firmware 'ulpt-hp1020' In my testing the printer recovers automatically once the firmware file is put in place. There is no need to re-plug it. ok? Index: ulpt.c =================================================================== RCS file: /cvs/src/sys/dev/usb/ulpt.c,v retrieving revision 1.47 diff -u -p -r1.47 ulpt.c --- ulpt.c 12 Jul 2014 20:26:33 -0000 1.47 +++ ulpt.c 19 Oct 2014 13:41:00 -0000 @@ -100,6 +100,7 @@ struct ulpt_softc { #define ULPT_INIT 0x04 /* waiting to initialize for open */ u_char sc_flags; #define ULPT_NOPRIME 0x40 /* don't prime on open */ +#define ULPT_EFIRMWARE 0x80 /* error loading firmware */ u_char sc_laststatus; int sc_refcnt; @@ -193,9 +194,12 @@ ulpt_load_firmware(void *arg) usbd_status err; err = (sc->sc_fwdev->ucode_loader)(sc); - if (err != USBD_NORMAL_COMPLETION) + if (err != USBD_NORMAL_COMPLETION) { + sc->sc_flags |= ULPT_EFIRMWARE; printf("%s: could not load firmware '%s'\n", sc->sc_dev.dv_xname, sc->sc_fwdev->ucode_name); + } else + sc->sc_flags &= ~ULPT_EFIRMWARE; } #define ulpt_lookup(v, p) \ @@ -469,6 +473,13 @@ ulptopen(dev_t dev, int flag, int mode, if (sc->sc_state) return (EBUSY); + /* If a previous attempt to load firmware failed, retry. */ + if (sc->sc_flags & ULPT_EFIRMWARE) { + ulpt_load_firmware(sc); + if (sc->sc_flags & ULPT_EFIRMWARE) + return (EIO); + } + sc->sc_state = ULPT_INIT; sc->sc_flags = flags; DPRINTF(("ulptopen: flags=0x%x\n", (unsigned)flags)); @@ -640,7 +651,7 @@ ulptwrite(dev_t dev, struct uio *uio, in sc = ulpt_cd.cd_devs[ULPTUNIT(dev)]; - if (usbd_is_dying(sc->sc_udev)) + if (usbd_is_dying(sc->sc_udev) || (sc->sc_flags & ULPT_EFIRMWARE)) return (EIO); sc->sc_refcnt++;