diff options
| author | 2002-05-13 15:12:12 +0000 | |
|---|---|---|
| committer | 2002-05-13 15:12:12 +0000 | |
| commit | d041fd8f05ed510cbd4d3b1639401d78e6fd41be (patch) | |
| tree | d7bf3983f3f7c392b784adf948399117c3bf43ea | |
| parent | Don't leak memory when bus_dmamap_load_mbuf fails. (diff) | |
| download | wireguard-openbsd-d041fd8f05ed510cbd4d3b1639401d78e6fd41be.tar.xz wireguard-openbsd-d041fd8f05ed510cbd4d3b1639401d78e6fd41be.zip | |
From netbsd:
driver for le at lebuffer type devices
| -rw-r--r-- | sys/dev/sbus/if_le_lebuffer.c | 215 | ||||
| -rw-r--r-- | sys/dev/sbus/lebuffer.c | 164 |
2 files changed, 379 insertions, 0 deletions
diff --git a/sys/dev/sbus/if_le_lebuffer.c b/sys/dev/sbus/if_le_lebuffer.c new file mode 100644 index 00000000000..3a99fc4dfd3 --- /dev/null +++ b/sys/dev/sbus/if_le_lebuffer.c @@ -0,0 +1,215 @@ +/* $OpenBSD: if_le_lebuffer.c,v 1.1 2002/05/13 15:12:12 jason Exp $ */ +/* $NetBSD: if_le_lebuffer.c,v 1.10 2002/03/11 16:00:56 pk Exp $ */ + +/*- + * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace + * Simulation Facility, NASA Ames Research Center; 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 "bpfilter.h" + +#include <sys/cdefs.h> +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/syslog.h> +#include <sys/socket.h> +#include <sys/device.h> +#include <sys/malloc.h> + +#include <net/if.h> +#include <net/if_media.h> + +#ifdef INET +#include <netinet/in.h> +#include <netinet/if_ether.h> +#endif + +#include <machine/bus.h> +#include <machine/intr.h> +#include <machine/autoconf.h> + +#include <dev/sbus/sbusvar.h> +#include <dev/sbus/lebuffervar.h> + +#include <dev/ic/am7990reg.h> +#include <dev/ic/am7990var.h> + +/* + * LANCE registers. + */ +#define LEREG1_RDP 0 /* Register Data port */ +#define LEREG1_RAP 2 /* Register Address port */ + +struct le_softc { + struct am7990_softc sc_am7990; /* glue to MI code */ + struct sbusdev sc_sd; /* sbus device */ + bus_space_tag_t sc_bustag; + bus_dma_tag_t sc_dmatag; + bus_space_handle_t sc_reg; /* LANCE registers */ +}; + + +int lematch_lebuffer __P((struct device *, void *, void *)); +void leattach_lebuffer __P((struct device *, struct device *, void *)); + +struct cfattach le_lebuffer_ca = { + sizeof(struct le_softc), lematch_lebuffer, leattach_lebuffer +}; + +extern struct cfdriver le_cd; + +#if defined(_KERNEL_OPT) +#include "opt_ddb.h" +#endif + +#ifdef DDB +#define integrate +#define hide +#else +#define integrate static __inline +#define hide static +#endif + +static void lewrcsr __P((struct am7990_softc *, u_int16_t, u_int16_t)); +static u_int16_t lerdcsr __P((struct am7990_softc *, u_int16_t)); + +static void +lewrcsr(sc, port, val) + struct am7990_softc *sc; + u_int16_t port, val; +{ + struct le_softc *lesc = (struct le_softc *)sc; + + bus_space_write_2(lesc->sc_bustag, lesc->sc_reg, LEREG1_RAP, port); + bus_space_write_2(lesc->sc_bustag, lesc->sc_reg, LEREG1_RDP, val); + +#if defined(SUN4M) + /* + * We need to flush the Sbus->Mbus write buffers. This can most + * easily be accomplished by reading back the register that we + * just wrote (thanks to Chris Torek for this solution). + */ + if (CPU_ISSUN4M) { + volatile u_int16_t discard; + discard = bus_space_read_2(lesc->sc_bustag, lesc->sc_reg, + LEREG1_RDP); + } +#endif +} + +static u_int16_t +lerdcsr(sc, port) + struct am7990_softc *sc; + u_int16_t port; +{ + struct le_softc *lesc = (struct le_softc *)sc; + + bus_space_write_2(lesc->sc_bustag, lesc->sc_reg, LEREG1_RAP, port); + return (bus_space_read_2(lesc->sc_bustag, lesc->sc_reg, LEREG1_RDP)); +} + +int +lematch_lebuffer(parent, vcf, aux) + struct device *parent; + void *vcf; + void *aux; +{ + struct sbus_attach_args *sa = aux; + struct cfdata *cf = vcf; + + return (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0); +} + + +void +leattach_lebuffer(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct sbus_attach_args *sa = aux; + struct le_softc *lesc = (struct le_softc *)self; + struct am7990_softc *sc = &lesc->sc_am7990; + struct lebuf_softc *lebuf = (struct lebuf_softc *)parent; + /* XXX the following declarations should be elsewhere */ + extern void myetheraddr __P((u_char *)); + + lesc->sc_bustag = sa->sa_bustag; + lesc->sc_dmatag = sa->sa_dmatag; + + if (sbus_bus_map(sa->sa_bustag, + sa->sa_slot, + sa->sa_offset, + sa->sa_size, + 0, 0, &lesc->sc_reg)) { + printf("%s @ lebuffer: cannot map registers\n", self->dv_xname); + return; + } + + sc->sc_mem = lebuf->sc_buffer; + sc->sc_memsize = lebuf->sc_bufsiz; + sc->sc_addr = 0; /* Lance view is offset by buffer location */ + lebuf->attached = 1; + + /* That old black magic... */ + sc->sc_conf3 = getpropint(sa->sa_node, "busmaster-regval", + LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON); + + /* Assume SBus is grandparent */ + lesc->sc_sd.sd_reset = (void *)am7990_reset; + sbus_establish(&lesc->sc_sd, parent); + + myetheraddr(sc->sc_arpcom.ac_enaddr); + + sc->sc_copytodesc = am7990_copytobuf_contig; + sc->sc_copyfromdesc = am7990_copyfrombuf_contig; + sc->sc_copytobuf = am7990_copytobuf_contig; + sc->sc_copyfrombuf = am7990_copyfrombuf_contig; + sc->sc_zerobuf = am7990_zerobuf_contig; + + sc->sc_rdcsr = lerdcsr; + sc->sc_wrcsr = lewrcsr; + + am7990_config(&lesc->sc_am7990); + + /* Establish interrupt handler */ + if (sa->sa_nintr != 0) + (void)bus_intr_establish(lesc->sc_bustag, sa->sa_pri, + IPL_NET, 0, am7990_intr, sc); +} + +struct cfdriver lebuffer_cd = { + NULL, "lebuffer", DV_DULL +}; diff --git a/sys/dev/sbus/lebuffer.c b/sys/dev/sbus/lebuffer.c new file mode 100644 index 00000000000..6b75662d8a2 --- /dev/null +++ b/sys/dev/sbus/lebuffer.c @@ -0,0 +1,164 @@ +/* $OpenBSD: lebuffer.c,v 1.1 2002/05/13 15:12:12 jason Exp $ */ +/* $NetBSD: lebuffer.c,v 1.12 2002/03/11 16:00:57 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. + */ + +#include <sys/cdefs.h> +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/errno.h> +#include <sys/device.h> +#include <sys/malloc.h> + +#include <machine/bus.h> +#include <machine/autoconf.h> +#include <machine/cpu.h> + +#include <dev/sbus/sbusvar.h> +#include <dev/sbus/lebuffervar.h> + +int lebufprint(void *, const char *); +int lebufmatch(struct device *, void *, void *); +void lebufattach(struct device *, struct device *, void *); + +struct cfattach lebuffer_ca = { + sizeof(struct lebuf_softc), lebufmatch, lebufattach +}; + +int +lebufprint(aux, busname) + void *aux; + const char *busname; +{ + struct sbus_attach_args *sa = aux; + bus_space_tag_t t = sa->sa_bustag; + struct lebuf_softc *sc = t->cookie; + + sa->sa_bustag = sc->sc_bustag; /* XXX */ + sbus_print(aux, busname); /* XXX */ + sa->sa_bustag = t; /* XXX */ + return (UNCONF); +} + +int +lebufmatch(parent, vcf, aux) + struct device *parent; + void *vcf; + void *aux; +{ + struct sbus_attach_args *sa = aux; + struct cfdata *cf = vcf; + + return (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0); +} + +/* + * Attach all the sub-devices we can find + */ +void +lebufattach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct sbus_attach_args *sa = aux; + struct lebuf_softc *sc = (void *)self; + int node; + int sbusburst; + bus_space_tag_t sbt; + bus_space_handle_t bh; + + sc->sc_bustag = sa->sa_bustag; + sc->sc_dmatag = sa->sa_dmatag; + + if (sbus_bus_map(sa->sa_bustag, + sa->sa_slot, sa->sa_offset, sa->sa_size, + BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { + printf("%s: attach: cannot map registers\n", self->dv_xname); + return; + } + + /* + * This device's "register space" is just a buffer where the + * Lance ring-buffers can be stored. Note the buffer's location + * and size, so the `le' driver can pick them up. + */ + sc->sc_buffer = (void *)bus_space_vaddr(sa->sa_bustag, bh); + sc->sc_bufsiz = sa->sa_size; + + node = sc->sc_node = sa->sa_node; + + /* + * Get transfer burst size from PROM + */ + sbusburst = ((struct sbus_softc *)parent)->sc_burst; + if (sbusburst == 0) + sbusburst = SBUS_BURST_32 - 1; /* 1->16 */ + + sc->sc_burst = getpropint(node, "burst-sizes", -1); + if (sc->sc_burst == -1) + /* take SBus burst sizes */ + sc->sc_burst = sbusburst; + + /* Clamp at parent's burst sizes */ + sc->sc_burst &= sbusburst; + + sbus_establish(&sc->sc_sd, &sc->sc_dev); + + /* Allocate a bus tag */ + sbt = (bus_space_tag_t) malloc(sizeof(struct sparc_bus_space_tag), + M_DEVBUF, M_NOWAIT); + if (sbt == NULL) { + printf("%s: attach: out of memory\n", self->dv_xname); + return; + } + bzero(sbt, sizeof(struct sparc_bus_space_tag)); + + printf(": %dK memory\n", sc->sc_bufsiz / 1024); + + sbt->cookie = sc; + sbt->parent = sc->sc_bustag; + + /* search through children */ + for (node = firstchild(node); node; node = nextsibling(node)) { + struct sbus_attach_args sa; + sbus_setup_attach_args((struct sbus_softc *)parent, + sbt, sc->sc_dmatag, node, &sa); + (void)config_found(&sc->sc_dev, (void *)&sa, lebufprint); + sbus_destroy_attach_args(&sa); + } +} |
