#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 *);
const struct cfattach lebuffer_ca = {
sizeof(struct lebuf_softc), lebufmatch, lebufattach
};
int
lebufprint(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;
sbus_print(aux, busname);
sa->sa_bustag = t;
return (UNCONF);
}
int
lebufmatch(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
lebufattach(struct device *parent, struct device *self, void *aux)
{
struct sbus_attach_args *sa = aux;
struct lebuf_softc *sc = (void *)self;
int node;
int sbusburst;
struct sparc_bus_space_tag *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;
}
sc->sc_buffer = (void *)bus_space_vaddr(sa->sa_bustag, bh);
sc->sc_bufsiz = sa->sa_size;
node = sc->sc_node = sa->sa_node;
sbusburst = ((struct sbus_softc *)parent)->sc_burst;
if (sbusburst == 0)
sbusburst = SBUS_BURST_32 - 1;
sc->sc_burst = getpropint(node, "burst-sizes", -1);
if (sc->sc_burst == -1)
sc->sc_burst = sbusburst;
sc->sc_burst &= sbusburst;
sbt = malloc(sizeof(*sbt), M_DEVBUF, M_NOWAIT | M_ZERO);
if (sbt == NULL) {
printf("%s: attach: out of memory\n", self->dv_xname);
return;
}
printf(": %dK memory\n", sc->sc_bufsiz / 1024);
sbt->cookie = sc;
sbt->parent = sc->sc_bustag;
sbt->asi = sbt->parent->asi;
sbt->sasi = sbt->parent->sasi;
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);
}
}