int wdc_obio_detach(struct device *self, int flags) { struct wdc_obio_softc *sc = (struct wdc_obio_softc *)self; struct channel_softc *chp = &sc->wdc_channel; int error; if ((error = wdcdetach(chp, flags)) != 0) return (error); free(chp->ch_queue, M_DEVBUF); if (sc->sc_use_dma) { unmapiodev((void *)sc->sc_dmareg, sc->sc_dmasize); dbdma_free(sc->sc_dbdma); } mac_intr_disestablish(NULL, sc->sc_ih); bus_space_unmap(chp->cmd_iot, chp->cmd_ioh, sc->sc_cmdsize); bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap); return (0); }
void mc_attach(struct device *parent, struct device *self, void *aux) { struct confargs *ca = aux; struct mc_softc *sc = (struct mc_softc *)self; struct ifnet *ifp = &sc->sc_arpcom.ac_if; u_int8_t lladdr[ETHER_ADDR_LEN]; int nseg, error; if (OF_getprop(ca->ca_node, "local-mac-address", lladdr, ETHER_ADDR_LEN) != ETHER_ADDR_LEN) { printf(": failed to get MAC address.\n"); return; } ca->ca_reg[0] += ca->ca_baseaddr; ca->ca_reg[2] += ca->ca_baseaddr; ca->ca_reg[4] += ca->ca_baseaddr; if ((sc->sc_reg = mapiodev(ca->ca_reg[0], ca->ca_reg[1])) == NULL) { printf(": cannot map registers\n"); return; } sc->sc_dmat = ca->ca_dmat; sc->sc_tail = 0; if ((sc->sc_txdma = mapiodev(ca->ca_reg[2], ca->ca_reg[3])) == NULL) { printf(": cannot map TX DMA registers\n"); goto notxdma; } if ((sc->sc_rxdma = mapiodev(ca->ca_reg[4], ca->ca_reg[5])) == NULL) { printf(": cannot map RX DMA registers\n"); goto norxdma; } if ((sc->sc_txdbdma = dbdma_alloc(sc->sc_dmat, 2)) == NULL) { printf(": cannot alloc TX DMA descriptors\n"); goto notxdbdma; } sc->sc_txdmacmd = sc->sc_txdbdma->d_addr; if ((sc->sc_rxdbdma = dbdma_alloc(sc->sc_dmat, 8 + 1)) == NULL) { printf(": cannot alloc RX DMA descriptors\n"); goto norxdbdma; } sc->sc_rxdmacmd = sc->sc_rxdbdma->d_addr; if ((error = bus_dmamem_alloc(sc->sc_dmat, MACE_BUFSZ, PAGE_SIZE, 0, sc->sc_bufseg, 1, &nseg, BUS_DMA_NOWAIT))) { printf(": cannot allocate DMA mem (%d)\n", error); goto nodmamem; } if ((error = bus_dmamem_map(sc->sc_dmat, sc->sc_bufseg, nseg, MACE_BUFSZ, &sc->sc_txbuf, BUS_DMA_NOWAIT))) { printf(": cannot map DMA mem (%d)\n", error); goto nodmamap; } if ((error = bus_dmamap_create(sc->sc_dmat, MACE_BUFSZ, 1, MACE_BUFSZ, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_bufmap))) { printf(": cannot create DMA map (%d)\n", error); goto nodmacreate; } if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_bufmap, sc->sc_txbuf, MACE_BUFSZ, NULL, BUS_DMA_NOWAIT))) { printf(": cannot load DMA map (%d)\n", error); goto nodmaload; } sc->sc_txbuf_pa = sc->sc_bufmap->dm_segs->ds_addr; sc->sc_rxbuf = sc->sc_txbuf + MACE_BUFLEN * MACE_TXBUFS; sc->sc_rxbuf_pa = sc->sc_txbuf_pa + MACE_BUFLEN * MACE_TXBUFS; printf(": irq %d,%d,%d", ca->ca_intr[0], ca->ca_intr[1], ca->ca_intr[2]); /* disable receive DMA */ dbdma_reset(sc->sc_rxdma); /* disable transmit DMA */ dbdma_reset(sc->sc_txdma); /* install interrupt handlers */ mac_intr_establish(parent, ca->ca_intr[2], IST_LEVEL, IPL_NET, mc_dmaintr, sc, sc->sc_dev.dv_xname); mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_NET, mc_intr, sc, sc->sc_dev.dv_xname); sc->sc_biucc = XMTSP_64; sc->sc_fifocc = XMTFW_16 | RCVFW_64 | XMTFWU | RCVFWU | XMTBRST | RCVBRST; sc->sc_plscc = PORTSEL_GPSI | ENPLSIO; /* reset the chip and disable all interrupts */ NIC_PUT(sc, MACE_BIUCC, SWRST); DELAY(100); NIC_PUT(sc, MACE_IMR, ~0); bcopy(lladdr, sc->sc_enaddr, ETHER_ADDR_LEN); bcopy(sc->sc_enaddr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN); printf(": address %s\n", ether_sprintf(lladdr)); bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); ifp->if_softc = sc; ifp->if_ioctl = mc_ioctl; ifp->if_start = mc_start; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; ifp->if_watchdog = mc_watchdog; ifp->if_timer = 0; IFQ_SET_READY(&ifp->if_snd); if_attach(ifp); ether_ifattach(ifp); return; nodmaload: bus_dmamap_destroy(sc->sc_dmat, sc->sc_bufmap); nodmacreate: bus_dmamem_unmap(sc->sc_dmat, sc->sc_txbuf, MACE_BUFSZ); nodmamap: bus_dmamem_free(sc->sc_dmat, sc->sc_bufseg, 1); nodmamem: dbdma_free(sc->sc_rxdbdma); norxdbdma: dbdma_free(sc->sc_txdbdma); notxdbdma: unmapiodev((void *)sc->sc_rxdma, ca->ca_reg[5]); norxdma: unmapiodev((void *)sc->sc_txdma, ca->ca_reg[3]); notxdma: unmapiodev(sc->sc_reg, ca->ca_reg[1]); }
static void mbattach(struct device *parent, struct device *self, void *aux) { struct mainbus_softc *sc = (struct mainbus_softc *)self; struct confargs nca; char name[64], *t = NULL; int reg[4], cpucnt; int node, len, slen; node = OF_peer(0); len = OF_getprop(node, "model", name, sizeof(name)); if (len > 1) { name[len] = '\0'; slen = strlen(name)+1; if ((t = malloc(slen, M_DEVBUF, M_NOWAIT)) != NULL) strlcpy(t, name, slen); } len = OF_getprop(node, "compatible", name, sizeof(name)); if (len > 1) { name[len] = '\0'; /* Old World Macintosh */ if ((strncmp(name, "AAPL", 4)) == 0) { hw_vendor = "Apple Computer, Inc."; slen = strlen(t) + strlen(name) - 3; if ((hw_prod = malloc(slen, M_DEVBUF, M_NOWAIT)) != NULL) { snprintf(hw_prod, slen, "%s %s", t, name + 5); free(t, M_DEVBUF); } } else { /* New World Macintosh or Unknown */ hw_vendor = "Apple Computer, Inc."; hw_prod = t; } } printf(": model %s\n", hw_prod); sc->sc_bus.bh_dv = (struct device *)sc; sc->sc_bus.bh_type = BUS_MAIN; sc->sc_bus.bh_intr_establish = mb_intr_establish; sc->sc_bus.bh_intr_disestablish = mb_intr_disestablish; sc->sc_bus.bh_matchname = mb_matchname; /* * Try to find and attach all of the CPUs in the machine. */ cpucnt = 0; node = OF_finddevice("/cpus"); if (node != -1) { for (node = OF_child(node); node != 0; node = OF_peer(node)) { u_int32_t cpunum; int len; len = OF_getprop(node, "reg", &cpunum, sizeof cpunum); if (len == 4 && cpucnt == cpunum) { nca.ca_name = "cpu"; nca.ca_bus = &sc->sc_bus; nca.ca_reg = reg; reg[0] = cpucnt; config_found(self, &nca, mbprint); cpucnt++; } } } if (cpucnt == 0) { nca.ca_name = "cpu"; nca.ca_bus = &sc->sc_bus; nca.ca_reg = reg; reg[0] = 0; config_found(self, &nca, mbprint); } /* * Special hack for SMP old world macs which lack /cpus and only have * one cpu node. */ node = OF_finddevice("/hammerhead"); if (node != -1) { len = OF_getprop(node, "reg", reg, sizeof(reg)); if (len >= 2) { u_char *hh_base; int twoway = 0; if ((hh_base = mapiodev(reg[0], reg[1])) != NULL) { twoway = in32rb(hh_base + HH_REG_CONF) & 0x02; unmapiodev(hh_base, reg[1]); } if (twoway) { nca.ca_name = "cpu"; nca.ca_bus = &sc->sc_bus; nca.ca_reg = reg; reg[0] = 1; config_found(self, &nca, mbprint); } } } for (node = OF_child(OF_peer(0)); node; node=OF_peer(node)) { bzero (name, sizeof(name)); if (OF_getprop(node, "device_type", name, sizeof(name)) <= 0) { if (OF_getprop(node, "name", name, sizeof(name)) <= 0) printf ("name not found on node %x\n", node); continue; } if (strcmp(name, "memory") == 0) { nca.ca_name = "mem"; nca.ca_node = node; nca.ca_bus = &sc->sc_bus; config_found(self, &nca, mbprint); } if (strcmp(name, "memory-controller") == 0) { nca.ca_name = "memc"; nca.ca_node = node; nca.ca_bus = &sc->sc_bus; config_found(self, &nca, mbprint); } if (strcmp(name, "pci") == 0) { nca.ca_name = "mpcpcibr"; nca.ca_node = node; nca.ca_bus = &sc->sc_bus; config_found(self, &nca, mbprint); } if (strcmp(name, "ht") == 0) { nca.ca_name = "ht"; nca.ca_node = node; nca.ca_bus = &sc->sc_bus; config_found(self, &nca, mbprint); } if (strcmp(name, "smu") == 0) { nca.ca_name = "smu"; nca.ca_node = node; nca.ca_bus = &sc->sc_bus; config_found(self, &nca, mbprint); } } }
void xlights_attach(struct device *parent, struct device *self, void *aux) { struct xlights_softc *sc = (struct xlights_softc *)self; struct confargs *ca = aux; int nseg, error, intr[6]; u_int32_t reg[4]; int type; sc->sc_node = OF_child(ca->ca_node); OF_getprop(sc->sc_node, "reg", reg, sizeof(reg)); ca->ca_reg[0] += ca->ca_baseaddr; ca->ca_reg[2] += ca->ca_baseaddr; if ((sc->sc_reg = mapiodev(ca->ca_reg[0], ca->ca_reg[1])) == NULL) { printf(": cannot map registers\n"); return; } sc->sc_dmat = ca->ca_dmat; if ((sc->sc_dma = mapiodev(ca->ca_reg[2], ca->ca_reg[3])) == NULL) { printf(": cannot map DMA registers\n"); goto nodma; } if ((sc->sc_dbdma = dbdma_alloc(sc->sc_dmat, BL_DBDMA_CMDS)) == NULL) { printf(": cannot alloc DMA descriptors\n"); goto nodbdma; } sc->sc_dmacmd = sc->sc_dbdma->d_addr; if ((error = bus_dmamem_alloc(sc->sc_dmat, BL_BUFSZ, 0, 0, sc->sc_bufseg, 1, &nseg, BUS_DMA_NOWAIT))) { printf(": cannot allocate DMA mem (%d)\n", error); goto nodmamem; } if ((error = bus_dmamem_map(sc->sc_dmat, sc->sc_bufseg, nseg, BL_BUFSZ, (caddr_t *)&sc->sc_buf, BUS_DMA_NOWAIT))) { printf(": cannot map DMA mem (%d)\n", error); goto nodmamap; } sc->sc_bufpos = sc->sc_buf; if ((error = bus_dmamap_create(sc->sc_dmat, BL_BUFSZ, 1, BL_BUFSZ, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_bufmap))) { printf(": cannot create DMA map (%d)\n", error); goto nodmacreate; } if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_bufmap, sc->sc_buf, BL_BUFSZ, NULL, BUS_DMA_NOWAIT))) { printf(": cannot load DMA map (%d)\n", error); goto nodmaload; } /* XXX: Should probably extract this from the clock data * property of the soundchip node */ sc->sc_freq = 16384; OF_getprop(sc->sc_node, "interrupts", intr, sizeof(intr)); /* output interrupt */ sc->sc_intr = intr[2]; type = intr[3] ? IST_LEVEL : IST_EDGE; printf(": irq %d\n", sc->sc_intr); macobio_enable(I2SClockOffset, I2S0EN); out32rb(sc->sc_reg + I2S_INT, I2S_INT_CLKSTOPPEND); macobio_disable(I2SClockOffset, I2S0CLKEN); for (error = 0; error < 1000; error++) { if (in32rb(sc->sc_reg + I2S_INT) & I2S_INT_CLKSTOPPEND) { error = 0; break; } delay(1); } if (error) { printf("%s: i2s timeout\n", sc->sc_dev.dv_xname); goto nodmaload; } mac_intr_establish(parent, sc->sc_intr, intr[3] ? IST_LEVEL : type, IPL_AUDIO, xlights_intr, sc, sc->sc_dev.dv_xname); out32rb(sc->sc_reg + I2S_FORMAT, CLKSRC_VS); macobio_enable(I2SClockOffset, I2S0CLKEN); kthread_create_deferred(xlights_deferred, sc); timeout_set(&sc->sc_tmo, xlights_timeout, sc); return; nodmaload: bus_dmamap_destroy(sc->sc_dmat, sc->sc_bufmap); nodmacreate: bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_buf, BL_BUFSZ); nodmamap: bus_dmamem_free(sc->sc_dmat, sc->sc_bufseg, nseg); nodmamem: dbdma_free(sc->sc_dbdma); nodbdma: unmapiodev((void *)sc->sc_dma, ca->ca_reg[3]); nodma: unmapiodev(sc->sc_reg, ca->ca_reg[1]); }