void macgpio_gpio_attach(struct device *parent, struct device *self, void *aux) { struct gpio_softc *sc = (struct gpio_softc *)self; struct confargs *ca = aux; sc->sc_port = ((struct gpio_softc *) parent)->sc_port; mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_HIGH, gpio_intr, sc, "gpio/adb"); printf(" irq %d\n", ca->ca_intr[0]); }
void * pciide_machdep_compat_intr_establish(struct device *dev, struct pci_attach_args *pa, int chan, int (*func)(void *), void *arg) { int irq; void *cookie; irq = PCIIDE_COMPAT_IRQ(chan); cookie = mac_intr_establish(NULL, irq, IST_EDGE, IPL_BIO, func, arg, dev->dv_xname); return (cookie); }
/* * Attach a found zs. * * Match slave number to zs unit number, so that misconfiguration will * not set up the keyboard as ttya, etc. */ void zsc_attach(struct device *parent, struct device *self, void *aux) { struct zsc_softc *zsc = (void *)self; struct confargs *ca = aux; struct zsc_attach_args zsc_args; volatile struct zschan *zc; struct xzs_chanstate *xcs; struct zs_chanstate *cs; struct zsdevice *zsd; int zsc_unit, channel; int s, theflags; int node, intr[3][3]; u_int regs[16]; zsc_unit = zsc->zsc_dev.dv_unit; zsd = mapiodev(ca->ca_baseaddr + ca->ca_reg[0], ca->ca_reg[1]); node = OF_child(ca->ca_node); /* ch-a */ for (channel = 0; channel < 2; channel++) { if (OF_getprop(node, "AAPL,interrupts", intr[channel], sizeof(intr[0])) == -1 && OF_getprop(node, "interrupts", intr[channel], sizeof(intr[0])) == -1) { printf(": cannot find interrupt property\n"); return; } if (OF_getprop(node, "reg", regs, sizeof(regs)) < 24) { printf(": cannot find reg property\n"); return; } regs[2] += ca->ca_baseaddr; regs[4] += ca->ca_baseaddr; #ifdef ZS_TXDMA zsc->zsc_txdmareg[channel] = mapiodev(regs[2], regs[3]); zsc->zsc_txdmacmd[channel] = dbdma_alloc(sizeof(dbdma_command_t) * 3); memset(zsc->zsc_txdmacmd[channel], 0, sizeof(dbdma_command_t) * 3); dbdma_reset(zsc->zsc_txdmareg[channel]); #endif node = OF_peer(node); /* ch-b */ } printf(": irq %d,%d\n", intr[0][0], intr[1][0]); /* * Initialize software state for each channel. */ for (channel = 0; channel < 2; channel++) { zsc_args.channel = channel; zsc_args.hwflags = zs_hwflags[zsc_unit][channel]; xcs = &zsc->xzsc_xcs_store[channel]; cs = &xcs->xzs_cs; zsc->zsc_cs[channel] = cs; cs->cs_channel = channel; cs->cs_private = NULL; cs->cs_ops = &zsops_null; zc = (channel == 0) ? &zsd->zs_chan_a : &zsd->zs_chan_b; cs->cs_reg_csr = &zc->zc_csr; cs->cs_reg_data = &zc->zc_data; memcpy(cs->cs_creg, zs_init_reg, 16); memcpy(cs->cs_preg, zs_init_reg, 16); /* Current BAUD rate generator clock. */ /* RTxC is 230400*16, so use 230400 */ cs->cs_brg_clk = PCLK / 16; if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE) cs->cs_defspeed = zs_get_speed(cs); else cs->cs_defspeed = zs_defspeed[zsc_unit][channel]; cs->cs_defcflag = zs_def_cflag; /* Make these correspond to cs_defcflag (-crtscts) */ cs->cs_rr0_dcd = ZSRR0_DCD; cs->cs_rr0_cts = 0; cs->cs_wr5_dtr = ZSWR5_DTR; cs->cs_wr5_rts = 0; #ifdef __notyet__ cs->cs_slave_type = ZS_SLAVE_NONE; #endif /* Define BAUD rate stuff. */ xcs->cs_clocks[0].clk = PCLK; xcs->cs_clocks[0].flags = ZSC_RTXBRG | ZSC_RTXDIV; xcs->cs_clocks[1].flags = ZSC_RTXBRG | ZSC_RTXDIV | ZSC_VARIABLE | ZSC_EXTERN; xcs->cs_clocks[2].flags = ZSC_TRXDIV | ZSC_VARIABLE; xcs->cs_clock_count = 3; if (channel == 0) { theflags = 0; /*mac68k_machine.modem_flags;*/ /*xcs->cs_clocks[1].clk = mac68k_machine.modem_dcd_clk;*/ /*xcs->cs_clocks[2].clk = mac68k_machine.modem_cts_clk;*/ xcs->cs_clocks[1].clk = 0; xcs->cs_clocks[2].clk = 0; } else { theflags = 0; /*mac68k_machine.print_flags;*/ xcs->cs_clocks[1].flags = ZSC_VARIABLE; /* * Yes, we aren't defining ANY clock source enables for the * printer's DCD clock in. The hardware won't let us * use it. But a clock will freak out the chip, so we * let you set it, telling us to bar interrupts on the line. */ /*xcs->cs_clocks[1].clk = mac68k_machine.print_dcd_clk;*/ /*xcs->cs_clocks[2].clk = mac68k_machine.print_cts_clk;*/ xcs->cs_clocks[1].clk = 0; xcs->cs_clocks[2].clk = 0; } if (xcs->cs_clocks[1].clk) zsc_args.hwflags |= ZS_HWFLAG_NO_DCD; if (xcs->cs_clocks[2].clk) zsc_args.hwflags |= ZS_HWFLAG_NO_CTS; /* Set defaults in our "extended" chanstate. */ xcs->cs_csource = 0; xcs->cs_psource = 0; xcs->cs_cclk_flag = 0; /* Nothing fancy by default */ xcs->cs_pclk_flag = 0; if (theflags & ZSMAC_RAW) { zsc_args.hwflags |= ZS_HWFLAG_RAW; printf(" (raw defaults)"); } /* * XXX - This might be better done with a "stub" driver * (to replace zstty) that ignores LocalTalk for now. */ if (theflags & ZSMAC_LOCALTALK) { printf(" shielding from LocalTalk"); cs->cs_defspeed = 1; cs->cs_creg[ZSRR_BAUDLO] = cs->cs_preg[ZSRR_BAUDLO] = 0xff; cs->cs_creg[ZSRR_BAUDHI] = cs->cs_preg[ZSRR_BAUDHI] = 0xff; zs_write_reg(cs, ZSRR_BAUDLO, 0xff); zs_write_reg(cs, ZSRR_BAUDHI, 0xff); /* * If we might have LocalTalk, then make sure we have the * Baud rate low-enough to not do any damage. */ } /* * We used to disable chip interrupts here, but we now * do that in zscnprobe, just in case MacOS left the chip on. */ xcs->cs_chip = 0; /* Stash away a copy of the final H/W flags. */ xcs->cs_hwflags = zsc_args.hwflags; /* * Look for a child driver for this channel. * The child attach will setup the hardware. */ if (!config_found(self, (void *)&zsc_args, zsc_print)) { /* No sub-driver. Just reset it. */ u_char reset = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET; s = splzs(); zs_write_reg(cs, 9, reset); splx(s); } } /* XXX - Now safe to install interrupt handlers. */ mac_intr_establish(parent, intr[0][0], IST_LEVEL, IPL_TTY, zshard, NULL, "zs0"); mac_intr_establish(parent, intr[1][0], IST_LEVEL, IPL_TTY, zshard, NULL, "zs1"); #ifdef ZS_TXDMA mac_intr_establish(parent, intr[0][1], IST_LEVEL, IPL_TTY, zs_txdma_int, (void *)0, "zsdma0"); mac_intr_establish(parent, intr[1][1], IST_LEVEL, IPL_TTY, zs_txdma_int, (void *)1, "zsdma1"); #endif zsc->zsc_softintr = softintr_establish(IPL_SOFTTTY, zssoft, zsc); if (zsc->zsc_softintr == NULL) panic("zsattach: could not establish soft interrupt"); /* * Set the master interrupt enable and interrupt vector. * (common to both channels, do it on A) */ cs = zsc->zsc_cs[0]; s = splzs(); /* interrupt vector */ zs_write_reg(cs, 2, zs_init_reg[2]); /* master interrupt control (enable) */ zs_write_reg(cs, 9, zs_init_reg[9]); splx(s); /* connect power management for port 0 */ cs->enable = zs_enable; cs->disable = zs_disable; }
void wdc_obio_attach(struct device *parent, struct device *self, void *aux) { struct wdc_obio_softc *sc = (void *)self; struct confargs *ca = aux; struct channel_softc *chp = &sc->wdc_channel; int intr, error; bus_addr_t cmdbase; sc->sc_use_dma = 0; if (ca->ca_nreg >= 16) sc->sc_use_dma = 1; /* Enable dma */ sc->sc_dmat = ca->ca_dmat; if ((error = bus_dmamap_create(sc->sc_dmat, WDC_DMALIST_MAX * DBDMA_COUNT_MAX, WDC_DMALIST_MAX, DBDMA_COUNT_MAX, NBPG, BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) { printf(": cannot create dma map, error = %d\n", error); return; } if (ca->ca_nintr >= 4 && ca->ca_nreg >= 8) { intr = ca->ca_intr[0]; printf(" irq %d", intr); } else if (ca->ca_nintr == -1) { intr = WDC_DEFAULT_PIO_IRQ; printf(" irq property not found; using %d", intr); } else { printf(": couldn't get irq property\n"); return; } if (sc->sc_use_dma) printf(": DMA"); printf("\n"); chp->cmd_iot = chp->ctl_iot = ca->ca_iot; chp->_vtbl = &wdc_obio_vtbl; cmdbase = ca->ca_reg[0]; sc->sc_cmdsize = ca->ca_reg[1]; if (bus_space_map(chp->cmd_iot, cmdbase, sc->sc_cmdsize, 0, &chp->cmd_ioh) || bus_space_subregion(chp->cmd_iot, chp->cmd_ioh, /* WDC_AUXREG_OFFSET<<4 */ 0x160, 1, &chp->ctl_ioh)) { printf("%s: couldn't map registers\n", sc->sc_wdcdev.sc_dev.dv_xname); return; } chp->data32iot = chp->cmd_iot; chp->data32ioh = chp->cmd_ioh; sc->sc_ih = mac_intr_establish(parent, intr, IST_LEVEL, IPL_BIO, wdcintr, chp, sc->sc_wdcdev.sc_dev.dv_xname); sc->sc_wdcdev.set_modes = wdc_obio_adjust_timing; if (sc->sc_use_dma) { sc->sc_dbdma = dbdma_alloc(sc->sc_dmat, WDC_DMALIST_MAX + 1); sc->sc_dmacmd = sc->sc_dbdma->d_addr; sc->sc_dmareg = mapiodev(ca->ca_baseaddr + ca->ca_reg[2], sc->sc_dmasize = ca->ca_reg[3]); sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA; sc->sc_wdcdev.DMA_cap = 2; if (strcmp(ca->ca_name, "ata-4") == 0) { sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA | WDC_CAPABILITY_MODE; sc->sc_wdcdev.UDMA_cap = 4; sc->sc_wdcdev.set_modes = wdc_obio_ata4_adjust_timing; } if (strcmp(ca->ca_name, "ata-6") == 0) { sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA | WDC_CAPABILITY_MODE; sc->sc_wdcdev.UDMA_cap = 5; sc->sc_wdcdev.set_modes = wdc_obio_ata6_adjust_timing; } } sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16; sc->sc_wdcdev.PIO_cap = 4; sc->wdc_chanptr = chp; sc->sc_wdcdev.channels = &sc->wdc_chanptr; sc->sc_wdcdev.nchannels = 1; sc->sc_wdcdev.dma_arg = sc; sc->sc_wdcdev.dma_init = wdc_obio_dma_init; sc->sc_wdcdev.dma_start = wdc_obio_dma_start; sc->sc_wdcdev.dma_finish = wdc_obio_dma_finish; chp->channel = 0; chp->wdc = &sc->sc_wdcdev; chp->ch_queue = malloc(sizeof(struct channel_queue), M_DEVBUF, M_NOWAIT); if (chp->ch_queue == NULL) { printf("%s: can't allocate memory for command queue", sc->sc_wdcdev.sc_dev.dv_xname); return; } wdcattach(chp); sc->sc_wdcdev.set_modes(chp); wdc_print_current_modes(chp); }
/* * Attach this instance, and then all the sub-devices */ void espattach(struct device *parent, struct device *self, void *aux) { struct confargs *ca = aux; struct esp_softc *esc = (void *)self; struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; u_int *reg; int sz, error; /* * Set up glue for MI code early; we use some of it here. */ sc->sc_glue = &esp_glue; esc->sc_node = ca->ca_node; esc->sc_intr = ca->ca_intr[0]; printf(" irq %d", esc->sc_intr); /* * Map my registers in. */ reg = ca->ca_reg; esc->sc_reg = mapiodev(ca->ca_baseaddr + reg[0], reg[1]); esc->sc_dmareg = mapiodev(ca->ca_baseaddr + reg[2], reg[3]); esc->sc_dmat = ca->ca_dmat; if ((error = bus_dmamap_create(esc->sc_dmat, ESP_DMALIST_MAX * DBDMA_COUNT_MAX, ESP_DMALIST_MAX, DBDMA_COUNT_MAX, NBPG, BUS_DMA_NOWAIT, &esc->sc_dmamap)) != 0) { printf(": cannot create dma map, error = %d\n", error); return; } /* Allocate 16-byte aligned DMA command space */ esc->sc_dbdma = dbdma_alloc(esc->sc_dmat, ESP_DMALIST_MAX); esc->sc_dmacmd = esc->sc_dbdma->d_addr; /* Other settings */ sc->sc_id = 7; sz = OF_getprop(ca->ca_node, "clock-frequency", &sc->sc_freq, sizeof(int)); if (sz != sizeof(int)) sc->sc_freq = 25000000; /* gimme MHz */ sc->sc_freq /= 1000000; /* * Set up static configuration info. */ sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB; sc->sc_cfg2 = NCRCFG2_SCSI2; /* | NCRCFG2_FE */ sc->sc_cfg3 = NCRCFG3_CDB; sc->sc_rev = NCR_VARIANT_NCR53C94; /* * This is the value used to start sync negotiations * Note that the NCR register "SYNCTP" is programmed * in "clocks per byte", and has a minimum value of 4. * The SCSI period used in negotiation is one-fourth * of the time (in nanoseconds) needed to transfer one byte. * Since the chip's clock is given in MHz, we have the following * formula: 4 * period = (1000 / freq) * 4 */ sc->sc_minsync = 1000 / sc->sc_freq; sc->sc_maxxfer = 64 * 1024; /* and the interuppts */ mac_intr_establish(parent, esc->sc_intr, IST_LEVEL, IPL_BIO, ncr53c9x_intr, sc, sc->sc_dev.dv_xname); /* Turn on target selection using the `DMA' method */ sc->sc_features |= NCR_F_DMASELECT; ncr53c9x_attach(sc); }
void bmac_attach(struct device *parent, struct device *self, void *aux) { struct confargs *ca = aux; struct bmac_softc *sc = (void *)self; struct ifnet *ifp = &sc->arpcom.ac_if; struct mii_data *mii = &sc->sc_mii; u_char laddr[6]; int nseg, error; timeout_set(&sc->sc_tick_ch, bmac_mii_tick, sc); sc->sc_flags =0; if (strcmp(ca->ca_name, "ethernet") == 0) { sc->sc_flags |= BMAC_BMACPLUS; } ca->ca_reg[0] += ca->ca_baseaddr; ca->ca_reg[2] += ca->ca_baseaddr; ca->ca_reg[4] += ca->ca_baseaddr; sc->sc_regs = (vaddr_t)mapiodev(ca->ca_reg[0], NBPG); bmac_write_reg(sc, INTDISABLE, NoEventsMask); if (OF_getprop(ca->ca_node, "local-mac-address", laddr, 6) == -1 && OF_getprop(ca->ca_node, "mac-address", laddr, 6) == -1) { printf(": cannot get mac-address\n"); return; } bcopy(laddr, sc->arpcom.ac_enaddr, 6); sc->sc_dmat = ca->ca_dmat; sc->sc_txdma = mapiodev(ca->ca_reg[2], 0x100); sc->sc_rxdma = mapiodev(ca->ca_reg[4], 0x100); sc->sc_txdbdma = dbdma_alloc(sc->sc_dmat, BMAC_TXBUFS); sc->sc_txcmd = sc->sc_txdbdma->d_addr; sc->sc_rxdbdma = dbdma_alloc(sc->sc_dmat, BMAC_RXBUFS + 1); sc->sc_rxcmd = sc->sc_rxdbdma->d_addr; error = bus_dmamem_alloc(sc->sc_dmat, BMAC_BUFSZ, PAGE_SIZE, 0, sc->sc_bufseg, 1, &nseg, BUS_DMA_NOWAIT); if (error) { printf(": cannot allocate buffers (%d)\n", error); return; } error = bus_dmamem_map(sc->sc_dmat, sc->sc_bufseg, nseg, BMAC_BUFSZ, &sc->sc_txbuf, BUS_DMA_NOWAIT); if (error) { printf(": cannot map buffers (%d)\n", error); bus_dmamem_free(sc->sc_dmat, sc->sc_bufseg, 1); return; } error = bus_dmamap_create(sc->sc_dmat, BMAC_BUFSZ, 1, BMAC_BUFSZ, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_bufmap); if (error) { printf(": cannot create buffer dmamap (%d)\n", error); bus_dmamem_unmap(sc->sc_dmat, sc->sc_txbuf, BMAC_BUFSZ); bus_dmamem_free(sc->sc_dmat, sc->sc_bufseg, 1); return; } error = bus_dmamap_load(sc->sc_dmat, sc->sc_bufmap, sc->sc_txbuf, BMAC_BUFSZ, NULL, BUS_DMA_NOWAIT); if (error) { printf(": cannot load buffers dmamap (%d)\n", error); bus_dmamap_destroy(sc->sc_dmat, sc->sc_bufmap); bus_dmamem_unmap(sc->sc_dmat, sc->sc_txbuf, BMAC_BUFSZ); bus_dmamem_free(sc->sc_dmat, sc->sc_bufseg, nseg); return; } sc->sc_txbuf_pa = sc->sc_bufmap->dm_segs->ds_addr; sc->sc_rxbuf = sc->sc_txbuf + BMAC_BUFLEN * BMAC_TXBUFS; sc->sc_rxbuf_pa = sc->sc_txbuf_pa + BMAC_BUFLEN * BMAC_TXBUFS; printf(" irq %d,%d: address %s\n", ca->ca_intr[0], ca->ca_intr[2], ether_sprintf(laddr)); mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_NET, bmac_intr, sc, sc->sc_dev.dv_xname); mac_intr_establish(parent, ca->ca_intr[2], IST_LEVEL, IPL_NET, bmac_rint, sc, sc->sc_dev.dv_xname); bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); ifp->if_softc = sc; ifp->if_ioctl = bmac_ioctl; ifp->if_start = bmac_start; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; ifp->if_watchdog = bmac_watchdog; IFQ_SET_READY(&ifp->if_snd); mii->mii_ifp = ifp; mii->mii_readreg = bmac_mii_readreg; mii->mii_writereg = bmac_mii_writereg; mii->mii_statchg = bmac_mii_statchg; ifmedia_init(&mii->mii_media, 0, bmac_mediachange, bmac_mediastatus); mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); /* Choose a default media. */ if (LIST_FIRST(&mii->mii_phys) == NULL) { ifmedia_add(&mii->mii_media, IFM_ETHER|IFM_10_T, 0, NULL); ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_10_T); } else ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO); bmac_reset_chip(sc); if_attach(ifp); ether_ifattach(ifp); }
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]); }
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]); }