On Fri, Jan 25, 2013 at 04:00:51PM +0100, Martin Pieuchot wrote:
> What about modifying ulpt(4) to upload the correct firmware like
> uvideo(4) does?

I've done this, and the printer now works out of the box with lpd(8),
as long as the foo2zjs port is used as a filter:

$ cat /etc/printcap                                  
#       $OpenBSD: printcap,v 1.4 2003/03/28 21:32:30 jmc Exp $

#lp|local line printer:\
#       :lp=/dev/lp:sd=/var/spool/output:lf=/var/log/lpd-errs:
#rp|remote line printer:\
#       :lp=:rm=printhost:rp=lp:sd=/var/spool/output:lf=/var/log/lpd-errs:
# Entry edited Sun Jan 27 19:58:45 2013 by foomatic-configure.
# Additional configuration atop /etc/foomatic/lpd/lp.ppd
lp|local line printer|HP LaserJet 1020:\
    :af=/etc/foomatic/lpd/lp.ppd:\
    :lf=/var/log/lpd-errs:\
    :sd=/var/spool/output/lp:\
    :ppdfile=/etc/foomatic/lpd/lp.ppd:\
    :lp=/dev/ulpt0:\
    :if=/usr/local/bin/foomatic-rip:\
    :sh:\
    :mx#0:

For the record, here's the foomatic-configure line I used (IIRC):
  # foomatic-configure -n lp -s lpd -p HP-LaserJet_1020 -o PageSize=A4

Diff for ulpt below. The firmware port is attached, and since tech@
will probably eat the attachment also at http://stsp.name/openbsd/ulpt.tar.gz

The firmware has some ridiculous licensing conditions:

  3. Copies and Adaptations.   You may only make copies or adaptations of
  the Software for archival purposes or when copying or adaptation is an
  essential step in the authorized Use of the Software. You must reproduce
  all copyright notices in the original Software on all copies or
  adaptations. You may not copy the Software onto any public network.

I'm not sure what "copy onto any public network" is supposed to mean here.
Does this last clause affect our ability to put a firmware package on
the firmware mirrors?

Index: sys/dev/usb/ulpt.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ulpt.c,v
retrieving revision 1.40
diff -u -p -r1.40 ulpt.c
--- sys/dev/usb/ulpt.c  17 Sep 2011 08:36:06 -0000      1.40
+++ sys/dev/usb/ulpt.c  27 Jan 2013 22:56:32 -0000
@@ -46,6 +46,8 @@
 #include <sys/conf.h>
 #include <sys/vnode.h>
 #include <sys/syslog.h>
+#include <sys/types.h>
+#include <sys/malloc.h>
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
@@ -103,6 +105,8 @@ struct ulpt_softc {
 
        int sc_refcnt;
        u_char sc_dying;
+
+       struct ulpt_fwdev *sc_fwdev;
 };
 
 void ulpt_disco(void *);
@@ -112,6 +116,38 @@ int ulpt_status(struct ulpt_softc *);
 void ulpt_reset(struct ulpt_softc *);
 int ulpt_statusmsg(u_char, struct ulpt_softc *);
 
+/*
+ * Printers which need firmware uploads.
+ */
+void ulpt_load_firmware(void *);
+usbd_status ulpt_ucode_loader_hp(struct ulpt_softc *);
+struct ulpt_fwdev {
+       struct usb_devno         uv_dev;
+       char                    *ucode_name;
+       usbd_status              (*ucode_loader)(struct ulpt_softc *);
+} ulpt_fwdevs[] = {
+       {
+           { USB_VENDOR_HP, USB_PRODUCT_HP_1000 },
+           "ulpt-hp1000",
+           ulpt_ucode_loader_hp
+       },
+       {
+           { USB_VENDOR_HP, USB_PRODUCT_HP_1005 },
+           "ulpt-hp1005",
+           ulpt_ucode_loader_hp
+       },
+       {
+           { USB_VENDOR_HP, USB_PRODUCT_HP_1018 },
+           "ulpt-hp1018",
+           ulpt_ucode_loader_hp
+       },
+       {
+           { USB_VENDOR_HP, USB_PRODUCT_HP_1020 },
+           "ulpt-hp1020",
+           ulpt_ucode_loader_hp
+       },
+};
+
 #if 0
 void ieee1284_print_id(char *);
 #endif
@@ -158,6 +194,21 @@ ulpt_match(struct device *parent, void *
 }
 
 void
+ulpt_load_firmware(void *arg)
+{
+       struct ulpt_softc *sc = (struct ulpt_softc *)arg;
+       usbd_status err;
+
+       err = (sc->sc_fwdev->ucode_loader)(sc);
+       if (err != USBD_NORMAL_COMPLETION)
+               printf("%s: could not load firmware '%s'\n",
+                   sc->sc_dev.dv_xname, sc->sc_fwdev->ucode_name);
+}
+
+#define ulpt_lookup(v, p) \
+       ((struct ulpt_fwdev *)usb_lookup(ulpt_fwdevs, v, p))
+
+void
 ulpt_attach(struct device *parent, struct device *self, void *aux)
 {
        struct ulpt_softc *sc = (struct ulpt_softc *)self;
@@ -262,6 +313,15 @@ ulpt_attach(struct device *parent, struc
        sc->sc_ifaceno = id->bInterfaceNumber;
        sc->sc_udev = dev;
 
+       /* maybe the device needs firmware */
+       sc->sc_fwdev = ulpt_lookup(uaa->vendor, uaa->product);
+       if (sc->sc_fwdev) {
+               if (rootvp == NULL)
+                       mountroothook_establish(ulpt_load_firmware, sc);
+               else
+                       ulpt_load_firmware(sc);
+       }
+
 #if 0
 /*
  * This code is disabled because for some mysterious reason it causes
@@ -605,6 +665,67 @@ ulptwrite(dev_t dev, struct uio *uio, in
        error = ulpt_do_write(sc, uio, flags);
        if (--sc->sc_refcnt < 0)
                usb_detach_wakeup(&sc->sc_dev);
+       return (error);
+}
+
+usbd_status
+ulpt_ucode_loader_hp(struct ulpt_softc *sc)
+{
+       usbd_status error;
+       int load_error;
+       uint8_t *ucode;
+       uint32_t len;
+       size_t ucode_size;
+       const char *ucode_name = sc->sc_fwdev->ucode_name;
+       int offset = 0, remain;
+       usbd_xfer_handle xfer;
+       void *bufp;
+
+       /* open microcode file */
+       load_error = loadfirmware(ucode_name, &ucode, &ucode_size);
+       if (load_error != 0) {
+               printf("%s: failed loadfirmware of file %s (error %d)\n",
+                   sc->sc_dev.dv_xname, ucode_name, load_error);
+               return (USBD_INVAL);
+       }
+
+       /* upload microcode */
+       error = usbd_open_pipe(sc->sc_iface, sc->sc_out, 0, &sc->sc_out_pipe);
+       if (error)
+               goto free_ucode;
+       xfer = usbd_alloc_xfer(sc->sc_udev);
+       if (xfer == NULL)
+               goto close_pipe;
+       bufp = usbd_alloc_buffer(xfer, ULPT_BSIZE);
+       if (bufp == NULL) {
+               error = USBD_NOMEM;
+               goto free_xfer;
+       }
+       remain = ucode_size;
+       while (remain > 0) {
+               len = min(remain, ULPT_BSIZE);
+               memcpy(bufp, &ucode[offset], len);
+               error = usbd_bulk_transfer(xfer, sc->sc_out_pipe, USBD_NO_COPY,
+                         USBD_NO_TIMEOUT, bufp, &len, "ulptwr");
+               if (error != USBD_NORMAL_COMPLETION) {
+                       printf("%s: ucode upload error=%s!\n",
+                           sc->sc_dev.dv_xname, usbd_errstr(error));
+                       break;
+               }
+               DPRINTF(("%s: uploaded %d bytes ucode\n",
+                   sc->sc_dev.dv_xname, len));
+
+               offset += len;
+               remain -= len;
+       }
+free_xfer:
+       usbd_free_xfer(xfer);
+close_pipe:
+       usbd_close_pipe(sc->sc_out_pipe);
+       sc->sc_out_pipe = NULL;
+free_ucode:
+       free(ucode, M_DEVBUF);
+
        return (error);
 }
 
Index: sys/dev/usb/usbdevs
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs,v
retrieving revision 1.595
diff -u -p -r1.595 usbdevs
--- sys/dev/usb/usbdevs 4 Jan 2013 02:47:46 -0000       1.595
+++ sys/dev/usb/usbdevs 25 Jan 2013 14:29:06 -0000
@@ -2032,6 +2032,7 @@ product HP 5200C          0x0401  Scanjet 5200C
 product HP 830C                        0x0404  DeskJet 830C
 product HP 3400CSE             0x0405  ScanJet 3400cse
 product HP 885C                        0x0504  DeskJet 885C
+product HP 1000                        0x0517  LaserJet 1000
 product HP 6300C               0x0601  Scanjet 6300C
 product HP 840C                        0x0604  DeskJet 840c
 product HP 2200C               0x0605  ScanJet 2200C
@@ -2043,6 +2044,7 @@ product HP 2215                   0x1016  iPAQ 22xx/Jorn
 product HP 959C                        0x1104  Deskjet 959C
 product HP 568J                        0x1116  Jornada 568
 product HP 930C                        0x1204  DeskJet 930c
+product HP 1005                        0x1317  LaserJet 1005
 product HP P2000U              0x1801  Inkjet P-2000U
 product HP HS2300              0x1e1d  HS2300
 product HP T750                        0x1f06  T750 UPS
@@ -2052,7 +2054,9 @@ product HP RT2200         0x1f0a  R/T2200 UPS
 product HP R1500G2             0x1fe0  R1500 G2 UPS
 product HP T750G2              0x1fe1  T750 G2 UPS
 product HP 640C                        0x2004  DeskJet 640c
+product HP 1020                        0x2b17  LaserJet 1020
 product HP P1100               0x3102  Photosmart P1100
+product HP 1018                        0x4117  LaserJet 1018
 product HP HN210E              0x811c  HN210E Ethernet
 
 /* HP products */
Index: sys/dev/usb/usbdevs.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs.h,v
retrieving revision 1.605
diff -u -p -r1.605 usbdevs.h
--- sys/dev/usb/usbdevs.h       4 Jan 2013 02:48:27 -0000       1.605
+++ sys/dev/usb/usbdevs.h       25 Jan 2013 14:29:59 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: usbdevs.h,v 1.605 2013/01/04 02:48:27 jsg Exp $       */
+/*     $OpenBSD$       */
 
 /*
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -2039,6 +2039,7 @@
 #define        USB_PRODUCT_HP_830C     0x0404          /* DeskJet 830C */
 #define        USB_PRODUCT_HP_3400CSE  0x0405          /* ScanJet 3400cse */
 #define        USB_PRODUCT_HP_885C     0x0504          /* DeskJet 885C */
+#define        USB_PRODUCT_HP_1000     0x0517          /* LaserJet 1000 */
 #define        USB_PRODUCT_HP_6300C    0x0601          /* Scanjet 6300C */
 #define        USB_PRODUCT_HP_840C     0x0604          /* DeskJet 840c */
 #define        USB_PRODUCT_HP_2200C    0x0605          /* ScanJet 2200C */
@@ -2050,6 +2051,7 @@
 #define        USB_PRODUCT_HP_959C     0x1104          /* Deskjet 959C */
 #define        USB_PRODUCT_HP_568J     0x1116          /* Jornada 568 */
 #define        USB_PRODUCT_HP_930C     0x1204          /* DeskJet 930c */
+#define        USB_PRODUCT_HP_1005     0x1317          /* LaserJet 1005 */
 #define        USB_PRODUCT_HP_P2000U   0x1801          /* Inkjet P-2000U */
 #define        USB_PRODUCT_HP_HS2300   0x1e1d          /* HS2300 */
 #define        USB_PRODUCT_HP_T750     0x1f06          /* T750 UPS */
@@ -2059,7 +2061,9 @@
 #define        USB_PRODUCT_HP_R1500G2  0x1fe0          /* R1500 G2 UPS */
 #define        USB_PRODUCT_HP_T750G2   0x1fe1          /* T750 G2 UPS */
 #define        USB_PRODUCT_HP_640C     0x2004          /* DeskJet 640c */
+#define        USB_PRODUCT_HP_1020     0x2b17          /* LaserJet 1020 */
 #define        USB_PRODUCT_HP_P1100    0x3102          /* Photosmart P1100 */
+#define        USB_PRODUCT_HP_1018     0x4117          /* LaserJet 1018 */
 #define        USB_PRODUCT_HP_HN210E   0x811c          /* HN210E Ethernet */
 
 /* HP products */
Index: sys/dev/usb/usbdevs_data.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs_data.h,v
retrieving revision 1.599
diff -u -p -r1.599 usbdevs_data.h
--- sys/dev/usb/usbdevs_data.h  4 Jan 2013 02:48:27 -0000       1.599
+++ sys/dev/usb/usbdevs_data.h  25 Jan 2013 14:29:59 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: usbdevs_data.h,v 1.599 2013/01/04 02:48:27 jsg Exp $  */
+/*     $OpenBSD$       */
 
 /*
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -4150,6 +4150,10 @@ const struct usb_known_product usb_known
            "DeskJet 885C",
        },
        {
+           USB_VENDOR_HP, USB_PRODUCT_HP_1000,
+           "LaserJet 1000",
+       },
+       {
            USB_VENDOR_HP, USB_PRODUCT_HP_6300C,
            "Scanjet 6300C",
        },
@@ -4194,6 +4198,10 @@ const struct usb_known_product usb_known
            "DeskJet 930c",
        },
        {
+           USB_VENDOR_HP, USB_PRODUCT_HP_1005,
+           "LaserJet 1005",
+       },
+       {
            USB_VENDOR_HP, USB_PRODUCT_HP_P2000U,
            "Inkjet P-2000U",
        },
@@ -4230,8 +4238,16 @@ const struct usb_known_product usb_known
            "DeskJet 640c",
        },
        {
+           USB_VENDOR_HP, USB_PRODUCT_HP_1020,
+           "LaserJet 1020",
+       },
+       {
            USB_VENDOR_HP, USB_PRODUCT_HP_P1100,
            "Photosmart P1100",
+       },
+       {
+           USB_VENDOR_HP, USB_PRODUCT_HP_1018,
+           "LaserJet 1018",
        },
        {
            USB_VENDOR_HP, USB_PRODUCT_HP_HN210E,
Index: share/man/man4/ulpt.4
===================================================================
RCS file: /cvs/src/share/man/man4/ulpt.4,v
retrieving revision 1.10
diff -u -p -r1.10 ulpt.4
--- share/man/man4/ulpt.4       3 Sep 2011 22:59:08 -0000       1.10
+++ share/man/man4/ulpt.4       27 Jan 2013 23:15:17 -0000
@@ -50,6 +50,26 @@ The bits in the minor number select vari
 .Bl -tag -width Pa
 .It Pa /dev/ulpt?
 .El
+.Pp
+For some HP LaserJet printer models (1000, 1005, 1018, 1020), the driver needs
+at least version 1.0 of the following firmware files, which are loaded when an
+interface is attached:
+.Pp
+.Bl -tag -width Ds -offset indent -compact
+.It /etc/firmware/ulpt-hp1000
+.It /etc/firmware/ulpt-hp1005
+.It /etc/firmware/ulpt-hp1018
+.It /etc/firmware/ulpt-hp1020
+.El
+.Pp
+These firmware files are not free because HP refuses to grant
+distribution rights. As a result, even though
+.Ox
+includes the driver, the firmware files cannot be included and
+users have to download these files on their own.
+.Pp
+A prepackaged version of the firmware can be installed using
+.Xr fw_update 1 .
 .Sh SEE ALSO
 .Xr intro 4 ,
 .Xr lpt 4 ,

Attachment: ulpt.tar.gz
Description: application/tar-gz

Reply via email to