/* * Attach all the sub-devices we can find */ 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; } /* * 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; /* Allocate a bus tag */ 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; /* 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); } }
void dmaattach_sbus(device_t parent, device_t self, void *aux) { struct dma_softc *dsc = device_private(self); struct lsi64854_softc *sc = &dsc->sc_lsi64854; struct sbus_attach_args *sa = aux; struct sbus_softc *sbsc = device_private(parent); bus_space_tag_t sbt; int sbusburst, burst; int node; node = sa->sa_node; sc->sc_dev = self; sc->sc_bustag = sa->sa_bustag; sc->sc_dmatag = sa->sa_dmatag; /* Map registers */ if (sa->sa_npromvaddrs) { sbus_promaddr_to_handle(sa->sa_bustag, sa->sa_promvaddrs[0], &sc->sc_regs); } else { if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset, sa->sa_size, 0, &sc->sc_regs) != 0) { aprint_error(": cannot map registers\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 = sbsc->sc_burst; if (sbusburst == 0) sbusburst = SBUS_BURST_32 - 1; /* 1->16 */ burst = prom_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; if (device_is_a(self, "ledma")) { char *cabletype; uint32_t csr; /* * Check to see which cable type is currently active and * set the appropriate bit in the ledma csr so that it * gets used. If we didn't netboot, the PROM won't have * the "cable-selection" property; default to TP and then * the user can change it via a "media" option to ifconfig. */ cabletype = prom_getpropstring(node, "cable-selection"); csr = L64854_GCSR(sc); if (strcmp(cabletype, "tpe") == 0) { csr |= E_TP_AUI; } else if (strcmp(cabletype, "aui") == 0) { csr &= ~E_TP_AUI; } else { /* assume TP if nothing there */ csr |= E_TP_AUI; } L64854_SCSR(sc, csr); delay(20000); /* manual says we need a 20ms delay */ sc->sc_channel = L64854_CHANNEL_ENET; } else { sc->sc_channel = L64854_CHANNEL_SCSI; } sbus_establish(&dsc->sc_sd, self); if ((sbt = bus_space_tag_alloc(sc->sc_bustag, dsc)) == NULL) { aprint_error(": out of memory\n"); return; } sbt->sparc_intr_establish = dmabus_intr_establish; lsi64854_attach(sc); /* Attach children */ for (node = firstchild(sa->sa_node); node; node = nextsibling(node)) { struct sbus_attach_args sax; sbus_setup_attach_args(sbsc, sbt, sc->sc_dmatag, node, &sax); (void)config_found(self, (void *)&sax, dmaprint_sbus); sbus_destroy_attach_args(&sax); } }