summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2007-02-28 18:48:36 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2007-02-28 18:48:36 +0000
commita0ce354e234749f869a267fe01249d949cd6804a (patch)
tree912cdd382018af23c17c6a6d757021e6a566bc4e /sys/dev
parentdd1fcdbcbb034dcabbf48f0f3fd5a2a0dc5cece3 (diff)
SBus parallel port driver, from NetBSD but untested (no printer or cables);
this should hopefully stop people from asking me about it (-:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/lsi64854.c6
-rw-r--r--sys/dev/ic/lsi64854var.h4
-rw-r--r--sys/dev/sbus/bpp.c413
-rw-r--r--sys/dev/sbus/bppreg.h100
-rw-r--r--sys/dev/sbus/files.sbus7
5 files changed, 525 insertions, 5 deletions
diff --git a/sys/dev/ic/lsi64854.c b/sys/dev/ic/lsi64854.c
index c70d95ac495..b1c29800c19 100644
--- a/sys/dev/ic/lsi64854.c
+++ b/sys/dev/ic/lsi64854.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lsi64854.c,v 1.7 2007/02/28 18:46:16 miod Exp $ */
+/* $OpenBSD: lsi64854.c,v 1.8 2007/02/28 18:48:35 miod Exp $ */
/* $NetBSD: lsi64854.c,v 1.18 2001/06/04 20:56:51 mrg Exp $ */
/*-
@@ -64,6 +64,8 @@ int lsi64854_setup(struct lsi64854_softc *, caddr_t *, size_t *,
int, size_t *);
int lsi64854_setup_pp(struct lsi64854_softc *, caddr_t *, size_t *,
int, size_t *);
+int lsi64854_scsi_intr(void *);
+int lsi64854_pp_intr(void *);
#ifdef DEBUG
#define LDB_SCSI 1
@@ -103,8 +105,10 @@ lsi64854_attach(sc)
break;
case L64854_CHANNEL_ENET:
sc->intr = lsi64854_enet_intr;
+ sc->setup = lsi64854_setup;
break;
case L64854_CHANNEL_PP:
+ sc->intr = lsi64854_pp_intr;
sc->setup = lsi64854_setup_pp;
break;
default:
diff --git a/sys/dev/ic/lsi64854var.h b/sys/dev/ic/lsi64854var.h
index 28a9d9438d6..9f42b481418 100644
--- a/sys/dev/ic/lsi64854var.h
+++ b/sys/dev/ic/lsi64854var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: lsi64854var.h,v 1.5 2005/03/03 01:41:44 miod Exp $ */
+/* $OpenBSD: lsi64854var.h,v 1.6 2007/02/28 18:48:35 miod Exp $ */
/* $NetBSD: lsi64854var.h,v 1.4 2001/03/29 02:58:39 petrov Exp $ */
/*-
@@ -103,6 +103,4 @@ struct lsi64854_softc {
int lsi64854_attach(struct lsi64854_softc *);
-int lsi64854_scsi_intr(void *);
int lsi64854_enet_intr(void *);
-int lsi64854_pp_intr(void *);
diff --git a/sys/dev/sbus/bpp.c b/sys/dev/sbus/bpp.c
new file mode 100644
index 00000000000..05a5c0a294d
--- /dev/null
+++ b/sys/dev/sbus/bpp.c
@@ -0,0 +1,413 @@
+/* $OpenBSD: bpp.c,v 1.1 2007/02/28 18:48:35 miod Exp $ */
+/* $NetBSD: bpp.c,v 1.25 2005/12/11 12:23:44 christos Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/errno.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#include <sys/vnode.h>
+#include <sys/conf.h>
+
+#include <machine/autoconf.h>
+#include <machine/bus.h>
+#include <machine/conf.h>
+#include <machine/intr.h>
+
+#include <dev/ic/lsi64854reg.h>
+#include <dev/ic/lsi64854var.h>
+
+#include <dev/sbus/sbusvar.h>
+#include <dev/sbus/bppreg.h>
+
+#define splbpp() spltty() /* XXX */
+
+#ifdef DEBUG
+#define DPRINTF(x) do { if (bppdebug) printf x ; } while (0)
+int bppdebug = 1;
+#else
+#define DPRINTF(x)
+#endif
+
+#if 0
+struct bpp_param {
+ int bpp_dss; /* data setup to strobe */
+ int bpp_dsw; /* data strobe width */
+ int bpp_outputpins; /* Select/Autofeed/Init pins */
+ int bpp_inputpins; /* Error/Select/Paperout pins */
+};
+#endif
+
+struct hwstate {
+ u_int16_t hw_hcr; /* Hardware config register */
+ u_int16_t hw_ocr; /* Operation config register */
+ u_int8_t hw_tcr; /* Transfer Control register */
+ u_int8_t hw_or; /* Output register */
+ u_int16_t hw_irq; /* IRQ; polarity bits only */
+};
+
+struct bpp_softc {
+ struct lsi64854_softc sc_lsi64854; /* base device */
+
+ size_t sc_bufsz; /* temp buffer */
+ caddr_t sc_buf;
+
+ int sc_error; /* bottom-half error */
+ int sc_flags;
+#define BPP_LOCKED 0x01 /* DMA in progress */
+#define BPP_WANT 0x02 /* Waiting for DMA */
+
+ /* Hardware state */
+ struct hwstate sc_hwstate;
+};
+
+int bppmatch(struct device *, void *, void *);
+void bppattach(struct device *, struct device *, void *);
+int bppintr (void *);
+void bpp_setparams(struct bpp_softc *, struct hwstate *);
+
+const struct cfattach bpp_ca = {
+ sizeof(struct bpp_softc), bppmatch, bppattach
+};
+
+struct cfdriver bpp_cd = {
+ NULL, "bpp", DV_DULL
+};
+
+#define BPPUNIT(dev) (minor(dev))
+
+int
+bppmatch(struct device *parent, void *vcf, void *aux)
+{
+ struct sbus_attach_args *sa = aux;
+
+ return (strcmp("SUNW,bpp", sa->sa_name) == 0);
+}
+
+void
+bppattach(struct device *parent, struct device *self, void *aux)
+{
+ struct sbus_attach_args *sa = aux;
+ struct bpp_softc *dsc = (void *)self;
+ struct lsi64854_softc *sc = &dsc->sc_lsi64854;
+ int burst, sbusburst;
+ int node;
+
+ node = sa->sa_node;
+
+ sc->sc_bustag = sa->sa_bustag;
+ sc->sc_dmatag = sa->sa_dmatag;
+
+ /* Map device registers */
+ if (sa->sa_npromvaddrs != 0) {
+ if (sbus_bus_map(sa->sa_bustag, 0, sa->sa_promvaddrs[0],
+ sa->sa_size, /* ???? */
+ BUS_SPACE_MAP_PROMADDRESS, 0, &sc->sc_regs) != 0) {
+ printf(": cannot map registers\n", self->dv_xname);
+ return;
+ }
+ } else if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset,
+ sa->sa_size, 0, 0, &sc->sc_regs) != 0) {
+ printf(": cannot map registers\n", self->dv_xname);
+ return;
+ }
+
+ /* Check for the interrupt property */
+ if (sa->sa_nintr == 0) {
+ printf(": no interrupt property\n");
+ return;
+ }
+
+ /*
+ * Get transfer burst size from PROM and plug it into the
+ * controller registers. This is needed on the Sun4m; do
+ * others need it too?
+ */
+ sbusburst = ((struct sbus_softc *)parent)->sc_burst;
+ if (sbusburst == 0)
+ sbusburst = SBUS_BURST_32 - 1; /* 1->16 */
+
+ burst = getpropint(node, "burst-sizes", -1);
+ if (burst == -1)
+ /* take SBus burst sizes */
+ burst = sbusburst;
+
+ /* Clamp at parent's burst sizes */
+ burst &= sbusburst;
+ sc->sc_burst = (burst & SBUS_BURST_32) ? 32 :
+ (burst & SBUS_BURST_16) ? 16 : 0;
+
+ /* Initialize the DMA channel */
+ sc->sc_channel = L64854_CHANNEL_PP;
+ if (lsi64854_attach(sc) != 0)
+ return;
+
+ /* Establish interrupt handler */
+ sc->sc_intrchain = bppintr;
+ sc->sc_intrchainarg = dsc;
+ (void)bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_TTY, 0,
+ bppintr, sc, self->dv_xname);
+
+ /* Allocate buffer XXX - should actually use dmamap_uio() */
+ dsc->sc_bufsz = 1024;
+ dsc->sc_buf = malloc(dsc->sc_bufsz, M_DEVBUF, M_NOWAIT);
+
+ /* XXX read default state */
+ {
+ bus_space_handle_t h = sc->sc_regs;
+ struct hwstate *hw = &dsc->sc_hwstate;
+ int ack_rate = sa->sa_frequency/1000000;
+
+ hw->hw_hcr = bus_space_read_2(sc->sc_bustag, h, L64854_REG_HCR);
+ hw->hw_ocr = bus_space_read_2(sc->sc_bustag, h, L64854_REG_OCR);
+ hw->hw_tcr = bus_space_read_1(sc->sc_bustag, h, L64854_REG_TCR);
+ hw->hw_or = bus_space_read_1(sc->sc_bustag, h, L64854_REG_OR);
+
+ DPRINTF(("bpp: hcr %x ocr %x tcr %x or %x\n",
+ hw->hw_hcr, hw->hw_ocr, hw->hw_tcr, hw->hw_or));
+ /* Set these to sane values */
+ hw->hw_hcr = ((ack_rate<<BPP_HCR_DSS_SHFT)&BPP_HCR_DSS_MASK)
+ | ((ack_rate<<BPP_HCR_DSW_SHFT)&BPP_HCR_DSW_MASK);
+ hw->hw_ocr |= BPP_OCR_ACK_OP;
+ }
+}
+
+void
+bpp_setparams(struct bpp_softc *sc, struct hwstate *hw)
+{
+ u_int16_t irq;
+ bus_space_tag_t t = sc->sc_lsi64854.sc_bustag;
+ bus_space_handle_t h = sc->sc_lsi64854.sc_regs;
+
+ bus_space_write_2(t, h, L64854_REG_HCR, hw->hw_hcr);
+ bus_space_write_2(t, h, L64854_REG_OCR, hw->hw_ocr);
+ bus_space_write_1(t, h, L64854_REG_TCR, hw->hw_tcr);
+ bus_space_write_1(t, h, L64854_REG_OR, hw->hw_or);
+
+ /* Only change IRP settings in interrupt status register */
+ irq = bus_space_read_2(t, h, L64854_REG_ICR);
+ irq &= ~BPP_ALLIRP;
+ irq |= (hw->hw_irq & BPP_ALLIRP);
+ bus_space_write_2(t, h, L64854_REG_ICR, irq);
+ DPRINTF(("bpp_setparams: hcr %x ocr %x tcr %x or %x, irq %x\n",
+ hw->hw_hcr, hw->hw_ocr, hw->hw_tcr, hw->hw_or, irq));
+}
+
+int
+bppopen(dev_t dev, int flags, int mode, struct proc *p)
+{
+ int unit = BPPUNIT(dev);
+ struct bpp_softc *sc;
+ struct lsi64854_softc *lsi;
+ u_int16_t irq;
+ int s;
+
+ if (unit >= bpp_cd.cd_ndevs)
+ return (ENXIO);
+ if ((sc = bpp_cd.cd_devs[unit]) == NULL)
+ return (ENXIO);
+
+ lsi = &sc->sc_lsi64854;
+
+ /* Set default parameters */
+ s = splbpp();
+ bpp_setparams(sc, &sc->sc_hwstate);
+ splx(s);
+
+ /* Enable interrupts */
+ irq = BPP_ERR_IRQ_EN;
+ irq |= sc->sc_hwstate.hw_irq;
+ bus_space_write_2(lsi->sc_bustag, lsi->sc_regs, L64854_REG_ICR, irq);
+ return (0);
+}
+
+int
+bppclose(dev_t dev, int flags, int mode, struct proc *p)
+{
+ struct bpp_softc *sc = bpp_cd.cd_devs[BPPUNIT(dev)];
+ struct lsi64854_softc *lsi = &sc->sc_lsi64854;
+ u_int16_t irq;
+
+ /* Turn off all interrupt enables */
+ irq = sc->sc_hwstate.hw_irq | BPP_ALLIRQ;
+ irq &= ~BPP_ALLEN;
+ bus_space_write_2(lsi->sc_bustag, lsi->sc_regs, L64854_REG_ICR, irq);
+
+ sc->sc_flags = 0;
+ return (0);
+}
+
+int
+bppwrite(dev_t dev, struct uio *uio, int flags)
+{
+ struct bpp_softc *sc = bpp_cd.cd_devs[BPPUNIT(dev)];
+ struct lsi64854_softc *lsi = &sc->sc_lsi64854;
+ int error = 0;
+ int s;
+
+ /*
+ * Wait until the DMA engine is free.
+ */
+ s = splbpp();
+ while ((sc->sc_flags & BPP_LOCKED) != 0) {
+ if ((flags & IO_NDELAY) != 0) {
+ splx(s);
+ return (EWOULDBLOCK);
+ }
+
+ sc->sc_flags |= BPP_WANT;
+ error = tsleep(sc->sc_buf, PZERO | PCATCH, "bppwrite", 0);
+ if (error != 0) {
+ splx(s);
+ return (error);
+ }
+ }
+ sc->sc_flags |= BPP_LOCKED;
+ splx(s);
+
+ /*
+ * Move data from user space into our private buffer
+ * and start DMA.
+ */
+ while (uio->uio_resid > 0) {
+ caddr_t bp = sc->sc_buf;
+ size_t len = min(sc->sc_bufsz, uio->uio_resid);
+
+ if ((error = uiomove(bp, len, uio)) != 0)
+ break;
+
+ while (len > 0) {
+ u_int8_t tcr;
+ size_t size = len;
+ DMA_SETUP(lsi, &bp, &len, 0, &size);
+
+#ifdef DEBUG
+ if (bppdebug) {
+ int i;
+ printf("bpp: writing %ld : ", len);
+ for (i=0; i<len; i++) printf("%c(0x%x)", bp[i], bp[i]);
+ printf("\n");
+ }
+#endif
+
+ /* Clear direction control bit */
+ tcr = bus_space_read_1(lsi->sc_bustag, lsi->sc_regs,
+ L64854_REG_TCR);
+ tcr &= ~BPP_TCR_DIR;
+ bus_space_write_1(lsi->sc_bustag, lsi->sc_regs,
+ L64854_REG_TCR, tcr);
+
+ /* Enable DMA */
+ s = splbpp();
+ DMA_GO(lsi);
+ error = tsleep(sc, PZERO | PCATCH, "bppdma", 0);
+ splx(s);
+ if (error != 0)
+ goto out;
+
+ /* Bail out if bottom half reported an error */
+ if ((error = sc->sc_error) != 0)
+ goto out;
+
+ /*
+ * DMA_INTR() does this part.
+ *
+ * len -= size;
+ */
+ }
+ }
+
+out:
+ DPRINTF(("bpp done %x\n", error));
+ s = splbpp();
+ sc->sc_flags &= ~BPP_LOCKED;
+ if ((sc->sc_flags & BPP_WANT) != 0) {
+ sc->sc_flags &= ~BPP_WANT;
+ wakeup(sc->sc_buf);
+ }
+ splx(s);
+ return (error);
+}
+
+int
+bppioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ int error = 0;
+
+ switch(cmd) {
+ default:
+ error = ENODEV;
+ break;
+ }
+
+ return (error);
+}
+
+int
+bppintr(void *arg)
+{
+ struct bpp_softc *sc = arg;
+ struct lsi64854_softc *lsi = &sc->sc_lsi64854;
+ u_int16_t irq;
+
+ /* First handle any possible DMA interrupts */
+ if (DMA_INTR(lsi) == -1)
+ sc->sc_error = 1;
+
+ irq = bus_space_read_2(lsi->sc_bustag, lsi->sc_regs, L64854_REG_ICR);
+ /* Ack all interrupts */
+ bus_space_write_2(lsi->sc_bustag, lsi->sc_regs, L64854_REG_ICR,
+ irq | BPP_ALLIRQ);
+
+ DPRINTF(("bpp_intr: %x\n", irq));
+ /* Did our device interrupt? */
+ if ((irq & BPP_ALLIRQ) == 0)
+ return (0);
+
+ if ((sc->sc_flags & BPP_LOCKED) != 0)
+ wakeup(sc);
+ else if ((sc->sc_flags & BPP_WANT) != 0) {
+ sc->sc_flags &= ~BPP_WANT;
+ wakeup(sc->sc_buf);
+ }
+ return (1);
+}
diff --git a/sys/dev/sbus/bppreg.h b/sys/dev/sbus/bppreg.h
new file mode 100644
index 00000000000..99dd0e58e1e
--- /dev/null
+++ b/sys/dev/sbus/bppreg.h
@@ -0,0 +1,100 @@
+/* $OpenBSD: bppreg.h,v 1.1 2007/02/28 18:48:35 miod Exp $ */
+/* $NetBSD: bppreg.h,v 1.1 1998/09/21 21:20:48 pk Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Hardware Configuration Register */
+#define BPP_HCR_DSS_MASK 0x003f /* Data before strobe */
+#define BPP_HCR_DSS_SHFT 0 /* (in Sbus clocks)*/
+#define BPP_HCR_DSW_MASK 0x7f00 /* Data Strobe Width */
+#define BPP_HCR_DSW_SHFT 8 /* (in Sbus clocks)*/
+#define BPP_HCR_TEST 0x8000 /* */
+
+
+/* Operation Configuration Register */
+#define BPP_OCR_IDLE 0x0008 /* State machines are idle */
+#define BPP_OCR_SRST 0x0080 /* Reset bit */
+#define BPP_OCR_ACK_OP 0x0100 /* ACK handshake operation */
+#define BPP_OCR_BUSY_OP 0x0200 /* BUSY handshake operation */
+#define BPP_OCR_EN_DIAG 0x0400 /* */
+#define BPP_OCR_ACK_DSEL 0x0800 /* ack line is bidirectional */
+#define BPP_OCR_BUSY_DSEL 0x1000 /* busy line is bidirectional */
+#define BPP_OCR_DS_DSEL 0x2000 /* data strobe line is bidirectional */
+#define BPP_OCR_DATA_SRC 0x4000 /* Data source for `memory clear' */
+#define BPP_OCR_MEM_SRC 0x8000 /* Enable `memory clear' */
+
+/* Transfer Control Register */
+#define BPP_TCR_DS 0x01 /* Data Strobe */
+#define BPP_TCR_ACK 0x02 /* Acknowledge */
+#define BPP_TCR_BUSY 0x04 /* Busy */
+#define BPP_TCR_DIR 0x08 /* Direction control */
+
+/* Output Register */
+#define BPP_OR_SLCTIN 0x01 /* Select */
+#define BPP_OR_AFXN 0x02 /* Auto Feed */
+#define BPP_OR_INIT 0x04 /* Initialize */
+
+/* Input Register (read-only) */
+#define BPP_IR_ERR 0x01 /* Err input pin */
+#define BPP_IR_SLCT 0x02 /* Select input pin */
+#define BPP_IR_PE 0x04 /* Paper Out input pin */
+
+/* Interrupt Control Register */
+#define BPP_ERR_IRQ_EN 0x0001 /* Error interrupt enable */
+#define BPP_ERR_IRP 0x0002 /* ERR interrupt polarity */
+#define BPP_SLCT_IRQ_EN 0x0004 /* Select interrupt enable */
+#define BPP_SLCT_IRP 0x0008 /* Select interrupt polarity */
+#define BPP_PE_IRQ_EN 0x0010 /* Paper Empty interrupt enable */
+#define BPP_PE_IRP 0x0020 /* PE interrupt polarity */
+#define BPP_BUSY_IRQ_EN 0x0040 /* BUSY interrupt enable */
+#define BPP_BUSY_IRP 0x0080 /* BUSY interrupt polarity */
+#define BPP_ACK_IRQ_EN 0x0100 /* ACK interrupt enable */
+#define BPP_DS_IRQ_EN 0x0200 /* Data Strobe interrupt enable */
+#define BPP_ERR_IRQ 0x0400 /* ERR interrupt pending */
+#define BPP_SLCT_IRQ 0x0800 /* SLCT interrupt pending */
+#define BPP_PE_IRQ 0x1000 /* PE interrupt pending */
+#define BPP_BUSY_IRQ 0x2000 /* BUSY interrupt pending */
+#define BPP_ACK_IRQ 0x4000 /* ACK interrupt pending */
+#define BPP_DS_IRQ 0x8000 /* DS interrupt pending */
+
+/* Define mask for each of all irq request, all polarity and all enable bits */
+#define BPP_ALLIRQ (BPP_ERR_IRQ|BPP_SLCT_IRQ|BPP_PE_IRQ| \
+ BPP_BUSY_IRQ|BPP_ACK_IRQ|BPP_DS_IRQ)
+#define BPP_ALLEN (BPP_ERR_IRQ_EN|BPP_SLCT_IRQ_EN| \
+ BPP_PE_IRQ_EN|BPP_BUSY_IRQ_EN| \
+ BPP_ACK_IRQ_EN|BPP_DS_IRQ_EN)
+#define BPP_ALLIRP (BPP_ERR_IRP|BPP_PE_IRP|BPP_BUSY_IRP)
diff --git a/sys/dev/sbus/files.sbus b/sys/dev/sbus/files.sbus
index 6c7b26bc6f0..42c323030df 100644
--- a/sys/dev/sbus/files.sbus
+++ b/sys/dev/sbus/files.sbus
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sbus,v 1.35 2006/12/09 20:06:48 miod Exp $
+# $OpenBSD: files.sbus,v 1.36 2007/02/28 18:48:35 miod Exp $
# $NetBSD: files.sbus,v 1.16 2000/12/08 17:29:12 martin Exp $
#
# Config file and device description for machine-independent SBUS code.
@@ -133,3 +133,8 @@ file dev/sbus/stp4020.c stp
device xbox {}
attach xbox at sbus
file dev/sbus/xbox.c xbox
+
+# LSI64854 based bi-directional parallel port
+device bpp {}: lsi64854
+attach bpp at sbus
+file dev/sbus/bpp.c bpp needs-flag