summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormiod <miod@openbsd.org>2009-02-12 22:03:46 +0000
committermiod <miod@openbsd.org>2009-02-12 22:03:46 +0000
commit65c7bb6d74ba8474accbd23d1c90e8d62911c405 (patch)
treef9c8e69ffee585e7f2edea9534401d1057113583
parentAdd a pm_statistics struct to all pmap, and keep track of resident (diff)
downloadwireguard-openbsd-65c7bb6d74ba8474accbd23d1c90e8d62911c405.tar.xz
wireguard-openbsd-65c7bb6d74ba8474accbd23d1c90e8d62911c405.zip
BPP routines for ``intelligent'' Motorola MVME boards. Currently not used
by anything, will eventually be used by the vx(4) MVME332 driver (once I take the time to fix it) and the vsbic(4) MVME327 driver being worked on.
-rw-r--r--sys/arch/mvme88k/conf/files.mvme88k14
-rw-r--r--sys/arch/mvme88k/dev/bpp.c369
-rw-r--r--sys/arch/mvme88k/dev/bppvar.h193
3 files changed, 575 insertions, 1 deletions
diff --git a/sys/arch/mvme88k/conf/files.mvme88k b/sys/arch/mvme88k/conf/files.mvme88k
index c6d5323745a..26a76100559 100644
--- a/sys/arch/mvme88k/conf/files.mvme88k
+++ b/sys/arch/mvme88k/conf/files.mvme88k
@@ -1,4 +1,4 @@
-# $OpenBSD: files.mvme88k,v 1.41 2006/05/02 21:43:07 miod Exp $
+# $OpenBSD: files.mvme88k,v 1.42 2009/02/12 22:03:46 miod Exp $
#
maxpartitions 16
@@ -83,20 +83,32 @@ file arch/mvme88k/dev/bugio.c
file arch/mvme88k/dev/mainbus.c
file arch/mvme88k/dev/memdevs.c nvram | sram
+define bpp
+file arch/mvme88k/dev/bpp.c bpp
+
attach ie at pcctwo: ifnet, ether
file arch/mvme88k/dev/if_ie.c ie
+# MVME376
attach le at vmes
file arch/mvme88k/dev/if_le.c le
+# MVME374
#device vp: ether, ifnet, ifmedia
#attach vp at vmes
#file arch/mvme88k/dev/if_vp.c vp
+# MVME332
device vx: tty
attach vx at vmes
file arch/mvme88k/dev/vx.c vx needs-count
+# MVME328
device vs: scsi
attach vs at vmes
file arch/mvme88k/dev/vs.c vs
+
+# MVME327
+device vsbic: bpp, scsi
+attach vsbic at vmes
+file arch/mvme88k/dev/vsbic.c vsbic
diff --git a/sys/arch/mvme88k/dev/bpp.c b/sys/arch/mvme88k/dev/bpp.c
new file mode 100644
index 00000000000..05e0fe4cbc1
--- /dev/null
+++ b/sys/arch/mvme88k/dev/bpp.c
@@ -0,0 +1,369 @@
+/* $OpenBSD: bpp.c,v 1.1 2009/02/12 22:03:47 miod Exp $ */
+
+/*
+ * Copyright (c) 2008, 2009 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies. And
+ * I won't mind if you keep the disclaimer below.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* BPP cards live in an A24/D16 world */
+#define __BUS_SPACE_RESTRICT_D16__
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+
+#include <mvme88k/dev/bppvar.h>
+
+int bpp_csr_command(struct bpp_softc *, uint, bus_addr_t);
+
+void
+bpp_attach(struct bpp_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh,
+ int ipl, int vec)
+{
+ sc->sc_ipl = ipl;
+ sc->sc_vec = vec;
+
+ sc->sc_iot = iot;
+ sc->sc_ioh = ioh;
+}
+
+/*
+ * CSR Command Protocol
+ *
+ * This protocol relies on atomic test-and-set instructions to claim the
+ * device for ourselves, using the test-and-set register.
+ *
+ * However, OpenBSD expects to be the only software talking to the BPP
+ * device, so it isn't really necessary to perform atomic operations here
+ * (such operations are not provided by the bus_space API anyway).
+ *
+ * Moreover, some MVME197 boards with early BusSwitch version, can not
+ * reliably perform test and set operations (xmem) on non-local memory
+ * addresses. Fun fun fun.
+ */
+
+/*
+ * Send a command to the board through the (limited) CSR command protocol.
+ */
+int
+bpp_csr_command(struct bpp_softc *sc, uint command, bus_addr_t addr)
+{
+ uint16_t csr, tas;
+#if 1
+ uint8_t tas8;
+ int tmo, tmo2, stat;
+ vaddr_t tasaddr;
+
+ tasaddr = (vaddr_t)bus_space_vaddr(sc->sc_iot, sc->sc_ioh) + CSR_TAS;
+#else
+ int tmo, stat;
+#endif
+
+#if 1
+ for (tmo = 1000; tmo != 0; tmo--) {
+ /* wait for the BUSY bit to clear */
+ for (tmo2 = 1000; tmo2 != 0; tmo2--) {
+ csr = bus_space_read_2(sc->sc_iot, sc->sc_ioh,
+ CSR_CONTROL);
+ if (!ISSET(csr, CSR_BUSY))
+ break;
+ delay(100);
+ }
+ if (tmo2 == 0)
+ return STATUS_ERRNO + EAGAIN;
+
+ /*
+ * Claim the TAS register. Note that, since there is no
+ * 16 bits modifier for xmem, we need to use the byte
+ * version.
+ */
+ tas8 = TAS_TAS >> 8;
+ __asm__ __volatile__ ("xmem.bu %0, %2, r0" :
+ "+r"(tas8), "+m"(tasaddr) : "r"(tasaddr));
+
+ if (!ISSET(tas8, TAS_TAS >> 8))
+ break;
+
+ delay(100);
+ }
+ if (tmo == 0)
+ return STATUS_ERRNO + EAGAIN;
+#else
+ /* wait for the BUSY bit to clear */
+ for (tmo = 1000; tmo != 0; tmo--) {
+ csr = bus_space_read_2(sc->sc_iot, sc->sc_ioh, CSR_CONTROL);
+ if (!ISSET(csr, CSR_BUSY))
+ break;
+ delay(100);
+ }
+ if (tmo == 0)
+ return STATUS_ERRNO + EAGAIN;
+
+ /*
+ * Claim the TAS register.
+ */
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, CSR_TAS, TAS_TAS);
+#endif
+
+ /* write the command information */
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, CSR_ADDR, addr);
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh, CSR_ADDR_MOD, ADRM_EXT_S_D);
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh, CSR_DATA_WIDTH, MEMT_D32);
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, CSR_TAS,
+ TAS_TAS | TAS_VALID_COMMAND | command);
+
+ /* signal the board */
+ bpp_attention(sc);
+
+ /* wait for the command to complete */
+ for (tmo = 1000; tmo != 0; tmo--) {
+ tas = bus_space_read_2(sc->sc_iot, sc->sc_ioh, CSR_TAS);
+ if (ISSET(tas, TAS_VALID_STATUS))
+ break;
+ delay(100);
+ }
+ if (tmo == 0)
+ return STATUS_ERRNO + EAGAIN;
+
+ stat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, CSR_STATUS);
+
+ /* release the board */
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, CSR_TAS,
+ TAS_TAS | TAS_COMMAND_COMPLETE |
+ bus_space_read_2(sc->sc_iot, sc->sc_ioh, CSR_TAS));
+ bpp_attention(sc);
+
+ return (stat);
+}
+
+/*
+ * Interrupt the board.
+ */
+void
+bpp_attention(struct bpp_softc *sc)
+{
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, CSR_CONTROL,
+ bus_space_read_2(sc->sc_iot, sc->sc_ioh, CSR_CONTROL) |
+ CSR_ATTENTION);
+}
+
+/*
+ * Reset the board. This will take several seconds.
+ */
+int
+bpp_reset(struct bpp_softc *sc)
+{
+ uint16_t csr;
+ int tmo;
+
+ /* reset the board */
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, CSR_CONTROL, CSR_RESET);
+ delay(1000);
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, CSR_CONTROL, 0);
+
+ /* wait for BUSY to clear in 10s */
+ for (tmo = 10000; tmo != 0; tmo--) {
+ csr = bus_space_read_2(sc->sc_iot, sc->sc_ioh, CSR_CONTROL);
+ if (!ISSET(csr, CSR_BUSY)) {
+ return 0;
+ }
+
+ delay(1000);
+ }
+
+ return ENXIO;
+}
+
+/*
+ * CSR operations
+ */
+
+int
+bpp_create_channel(struct bpp_softc *sc, struct bpp_chan *chan, int pri)
+{
+ struct bpp_channel *channel = chan->ch;
+ struct bpp_envelope *envcmd, *envsts;
+
+ /*
+ * Setup the initial null envelopes.
+ */
+
+ envcmd = bpp_get_envelope(sc);
+ if (envcmd == NULL)
+ return STATUS_ERRNO + ENOMEM;
+ envsts = bpp_get_envelope(sc);
+ if (envsts == NULL)
+ return STATUS_ERRNO + ENOMEM;
+
+ (*sc->bpp_env_sync)(sc, envcmd, BUS_DMASYNC_PREWRITE);
+ (*sc->bpp_env_sync)(sc, envsts, BUS_DMASYNC_PREWRITE);
+
+ /*
+ * Setup channel header.
+ */
+
+ memset(channel, 0, sizeof (*channel));
+ channel->ch_cmd_head = channel->ch_cmd_tail =
+ htobe32((*sc->bpp_env_pa)(sc, envcmd));
+ channel->ch_status_head = channel->ch_status_tail =
+ htobe32((*sc->bpp_env_pa)(sc, envsts));
+ channel->ch_ipl = sc->sc_ipl;
+ channel->ch_ivec = sc->sc_vec;
+ channel->ch_priority = pri;
+ channel->ch_addrmod = ADRM_EXT_S_D;
+ channel->ch_buswidth = MEMT_D32;
+
+ (*sc->bpp_chan_sync)(sc, channel, BUS_DMASYNC_PREWRITE);
+
+ chan->envcmd = envcmd;
+ chan->envsts = envsts;
+
+ return bpp_csr_command(sc, COMMAND_CHANNEL_CREATE,
+ (*sc->bpp_chan_pa)(sc, channel));
+}
+
+/*
+ * BPP operations and envelope management
+ */
+
+/*
+ * Initialize the free list as a set of contiguous envelopes.
+ */
+void
+bpp_initialize_envelopes(struct bpp_softc *sc, struct bpp_envelope *env,
+ uint cnt)
+{
+ sc->sc_env_free = NULL;
+ while (cnt-- != 0)
+ bpp_put_envelope(sc, env++);
+}
+
+/*
+ * Get a new envelope from the free list.
+ */
+struct bpp_envelope *
+bpp_get_envelope(struct bpp_softc *sc)
+{
+ struct bpp_envelope *env;
+
+ env = sc->sc_env_free;
+ if (env != NULL) {
+ sc->sc_env_free = (struct bpp_envelope *)env->env_link;
+ memset(env, 0, sizeof(*env));
+ /* env->env_valid = ENVELOPE_INVALID; */
+ }
+
+ return env;
+}
+
+/*
+ * Put an envelope into the free list.
+ */
+void
+bpp_put_envelope(struct bpp_softc *sc, struct bpp_envelope *env)
+{
+ env->env_link = (uint32_t)sc->sc_env_free;
+ sc->sc_env_free = env;
+}
+
+/*
+ * Send a command packet, replacing the NULL envelope with the given one,
+ * and enqueue it to the command pipe.
+ */
+void
+bpp_queue_envelope(struct bpp_softc *sc, struct bpp_chan *chan,
+ struct bpp_envelope *tail, paddr_t cmdpa, uint32_t cmdextra)
+{
+ struct bpp_envelope *env;
+ struct bpp_channel *channel;
+ paddr_t tailpa;
+
+ /* tail assumed to be unmodified since bpp_get_envelope(),
+ no need to memset() */
+ (*sc->bpp_env_sync)(sc, tail, BUS_DMASYNC_PREWRITE);
+ tailpa = (*sc->bpp_env_pa)(sc, tail);
+
+ /*
+ * Update the existing NULL envelope with data.
+ */
+
+ env = chan->envcmd;
+ env->env_link = htobe32(tailpa);
+ env->env_pkt = htobe32(cmdpa);
+ env->env_extra = cmdextra;
+ (*sc->bpp_env_sync)(sc, env, BUS_DMASYNC_PREWRITE); /* paranoia */
+ env->env_valid = ENVELOPE_VALID;
+ (*sc->bpp_env_sync)(sc, env, BUS_DMASYNC_PREWRITE);
+
+ /*
+ * Update the channel's command tail pointer to point to the
+ * new envelope.
+ */
+
+ channel = chan->ch;
+ channel->ch_cmd_tail = htobe32(tailpa);
+ /* really necessary? */
+ (*sc->bpp_chan_sync)(sc, channel, BUS_DMASYNC_PREWRITE);
+
+ chan->envcmd = tail;
+
+ bpp_attention(sc);
+}
+
+/*
+ * Dequeue an envelope from the status pipe, and return the command it
+ * was carrying. The envelope itself is returned to the free list.
+ */
+int
+bpp_dequeue_envelope(struct bpp_softc *sc, struct bpp_chan *chan,
+ paddr_t *cmdpa, uint32_t *cmdextra)
+{
+ struct bpp_envelope *env;
+ struct bpp_channel *channel;
+ paddr_t headpa;
+
+ /*
+ * Look at the head envelope.
+ */
+
+ env = chan->envsts;
+ (*sc->bpp_env_sync)(sc, env, BUS_DMASYNC_POSTREAD);
+
+ if (env->env_valid == ENVELOPE_INVALID)
+ return EAGAIN;
+
+ /*
+ * Dequeue the envelope, compute the new head envelope index, and
+ * finally release the envelope.
+ */
+
+ headpa = betoh32(env->env_link);
+ if (cmdpa != NULL)
+ *cmdpa = betoh32(env->env_pkt);
+ if (cmdextra != NULL)
+ *cmdextra = env->env_extra;
+ chan->envsts = (*sc->bpp_env_va)(sc, headpa);
+
+ channel = chan->ch;
+ channel->ch_status_head = htobe32(headpa);
+ /* really necessary? */
+ (*sc->bpp_chan_sync)(sc, channel, BUS_DMASYNC_PREWRITE);
+
+ bpp_put_envelope(sc, env);
+
+ return 0;
+}
diff --git a/sys/arch/mvme88k/dev/bppvar.h b/sys/arch/mvme88k/dev/bppvar.h
new file mode 100644
index 00000000000..88bb95eba75
--- /dev/null
+++ b/sys/arch/mvme88k/dev/bppvar.h
@@ -0,0 +1,193 @@
+/* $OpenBSD: bppvar.h,v 1.1 2009/02/12 22:03:47 miod Exp $ */
+
+/*
+ * Copyright (c) 2008, 2009 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies. And
+ * I won't mind if you keep the disclaimer below.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Register and structure definitions for MVME boards using the Motorola
+ * Buffered Pipe Protocol.
+ */
+
+/*
+ * Register layout (CSR space)
+ */
+
+#define CSR_ADDR 0x00 /* 32 */
+#define CSR_ADDR_MOD 0x04 /* 8 */
+#define CSR_DATA_WIDTH 0x05 /* 8 */
+/* IPC control register */
+#define CSR_CONTROL 0x06 /* 16 */
+#define CSR_STATUS 0x08 /* 8 */
+#define CSR_DIAG 0x09 /* 8 */
+#define CSR_TAS 0x0e /* 16 */
+
+/* CSR bits */
+#define CSR_BUSY 0x8000 /* firmware busy */
+#define CSR_RESET 0x4000 /* reset board */
+#define CSR_ATTENTION 0x2000 /* interrupt firmware */
+#define CSR_INHIBIT_SYSFAIL 0x1000
+
+/* TAS bits */
+#define TAS_TAS 0x8000 /* test and set bit */
+#define TAS_VALID_COMMAND 0x4000
+#define TAS_VALID_STATUS 0x2000
+#define TAS_COMMAND_COMPLETE 0x1000
+#define TAS_COMMAND_MASK 0x0fff
+
+/* TAS commands */
+#define COMMAND_CHANNEL_CREATE 0x001
+#define COMMAND_CHANNEL_DELETE 0x002
+#define COMMAND_DUMP_MEMORY 0x101
+
+/* command status values */
+#define STATUS_OK 0x00
+#define STATUS_INVALID_COMMAND 0x01
+#define STATUS_READ_CHANNEL_HEADER 0x02
+#define STATUS_WRITE_CHANNEL_HEADER 0x03
+#define STATUS_DMA_READ 0x04
+#define STATUS_DMA_WRITE 0x05
+#define STATUS_NO_MORE_CHANNELS 0x06
+#define STATUS_NO_SUCH_CHANNEL 0x07
+/* catastrophic errors start here... */
+#define STATUS_LOCAL_ADDRESS_ERROR 0xaa
+#define STATUS_ACFAIL 0xac
+#define STATUS_LOCAL_BUS_ERROR 0xbb
+#define STATUS_CONFIDENCE_FAILED 0xcc
+#define STATUS_UNEXPECTED_ERROR 0xee
+#define STATUS_ERRNO 0x100 /* not from status reg */
+
+/*
+ * BPP Channel header
+ */
+
+struct bpp_channel {
+ uint32_t ch_cmd_head; /* command pipe head */
+ uint32_t ch_cmd_tail; /* command pipe tail */
+ uint32_t ch_status_head; /* status pipe head */
+ uint32_t ch_status_tail; /* status pipe tail */
+ uint8_t ch_ipl; /* channel interrupt level */
+ uint8_t ch_ivec; /* channel interrupt vector */
+ uint8_t ch_priority; /* channel priority */
+#define BPP_PRIORITY_HIGHEST 0x00
+#define BPP_PRIORITY_LOWEST 0xff
+ uint8_t ch_addrmod; /* envelope memory address modifier */
+ uint8_t ch_num; /* set by firmware */
+ uint8_t ch_valid; /* set by firmware */
+ uint8_t ch_buswidth; /* unused */
+ uint8_t reserved;
+};
+
+/*
+ * BPP Envelope structure
+ */
+
+struct bpp_envelope {
+ uint32_t env_link; /* next envelope */
+ uint32_t env_pkt; /* command packet physical address */
+ uint8_t env_valid;
+#define ENVELOPE_INVALID 0x00
+#define ENVELOPE_VALID 0x01 /* any nonzero value will do */
+ uint8_t reserved[3];
+ /*
+ * The following is not part of the envelope as defined by the
+ * firmware, but is used to page the envelope to a 68040/88200
+ * cache line boundary.
+ * Plus this allows us to associate extra information to the
+ * envelope.
+ */
+ uint32_t env_extra;
+ /* total size 0x10 bytes */
+};
+
+/*
+ * Data bus width
+ */
+
+#define MEMT_D16 1
+#define MEMT_D32 2
+
+/*
+ * The following defines ought to be in a MI vme header file...
+ */
+
+/*
+ * VME addressing modes
+ */
+
+#define ADRM_STD_S_P 0x3e /* standard supervisory program */
+#define ADRM_STD_S_D 0x3d /* standard supervisory data */
+#define ADRM_STD_N_P 0x3a /* standard normal program */
+#define ADRM_STD_N_D 0x39 /* standard normal data */
+#define ADRM_SHT_S_IO 0x2d /* short supervisory I/O */
+#define ADRM_SHT_N_IO 0x29 /* short normal I/O */
+#define ADRM_EXT_S_P 0x0e /* extended supervisory program */
+#define ADRM_EXT_S_D 0x0d /* extended supervisory data */
+#define ADRM_EXT_N_P 0x0a /* extended normal program */
+#define ADRM_EXT_N_D 0x09 /* extended normal data */
+#define ADRM_EXT_S_BM 0x0f /* extended supervisory block mode */
+#define ADRM_EXT_S_D64 0x0c /* extended supervisory D64 mode */
+
+/*
+ * Per channel information
+ */
+
+struct bpp_chan {
+ struct bpp_channel *ch; /* bpp communication channel */
+
+ struct bpp_envelope *envcmd; /* command tail envelope */
+ struct bpp_envelope *envsts; /* status head envelope */
+};
+
+/*
+ * Device superset
+ */
+
+struct bpp_softc {
+ struct device sc_dev;
+
+ bus_space_tag_t sc_iot; /* CSR registers access */
+ bus_space_handle_t sc_ioh;
+
+ int sc_vec; /* interrupt vector */
+ int sc_ipl; /* interrupt level */
+
+ struct bpp_envelope *sc_env_free; /* head of free envelope list */
+
+ /* channel function pointers */
+ paddr_t (*bpp_chan_pa)(struct bpp_softc *, struct bpp_channel *);
+ void (*bpp_chan_sync)(struct bpp_softc *, struct bpp_channel *, int);
+
+ /* envelope function pointers */
+ paddr_t (*bpp_env_pa)(struct bpp_softc *, struct bpp_envelope *);
+ struct bpp_envelope *(*bpp_env_va)(struct bpp_softc *, paddr_t);
+ void (*bpp_env_sync)(struct bpp_softc *, struct bpp_envelope *, int);
+};
+
+void bpp_attach(struct bpp_softc *, bus_space_tag_t, bus_space_handle_t,
+ int, int);
+void bpp_attention(struct bpp_softc *);
+int bpp_create_channel(struct bpp_softc *, struct bpp_chan *, int);
+int bpp_dequeue_envelope(struct bpp_softc *, struct bpp_chan *, paddr_t *,
+ uint32_t *);
+struct bpp_envelope *
+ bpp_get_envelope(struct bpp_softc *);
+void bpp_initialize_envelopes(struct bpp_softc *, struct bpp_envelope *,
+ uint);
+void bpp_put_envelope(struct bpp_softc *, struct bpp_envelope *);
+void bpp_queue_envelope(struct bpp_softc *, struct bpp_chan *,
+ struct bpp_envelope *, paddr_t, uint32_t);
+int bpp_reset(struct bpp_softc *);