void com_macebus_attach(struct device *parent, struct device *self, void *aux) { struct com_softc *sc = (void *)self; struct macebus_attach_args *maa = aux; sc->sc_iot = maa->maa_iot; sc->sc_hwflags = 0; sc->sc_swflags = 0; sc->sc_iobase = maa->maa_baseaddr; sc->sc_frequency = 1843200; /* If it's in use as the console, then it's there. */ if (maa->maa_baseaddr == comconsaddr && !comconsattached) { if (comcnattach(sc->sc_iot, sc->sc_iobase, comconsrate, sc->sc_frequency, (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) panic("failed to setup serial console!"); sc->sc_ioh = comconsioh; } else { if (bus_space_map(sc->sc_iot, maa->maa_baseaddr, COM_NPORTS, 0, &sc->sc_ioh)) { printf(": can't map i/o space\n"); return; } } com_attach_subr(sc); macebus_intr_establish(maa->maa_intr, maa->maa_mace_intr, IST_EDGE, IPL_TTY, comintr, (void *)sc, sc->sc_dev.dv_xname); }
void power_macebus_attach(struct device *parent, struct device *self, void *aux) { struct macebus_attach_args *maa = aux; /* Establish interrupt handler. */ if (macebus_intr_establish(maa->maa_intr, maa->maa_mace_intr, IST_EDGE, IPL_TTY, power_intr, self, self->dv_xname)) printf("\n"); else printf(": unable to establish interrupt!\n"); }
void mec_attach(struct device *parent, struct device *self, void *aux) { struct mec_softc *sc = (void *)self; struct confargs *ca = aux; struct ifnet *ifp = &sc->sc_ac.ac_if; uint32_t command; struct mii_softc *child; bus_dma_segment_t seg; int i, err, rseg; sc->sc_st = ca->ca_iot; if (bus_space_map(sc->sc_st, ca->ca_baseaddr, MEC_NREGS, 0, &sc->sc_sh) != 0) { printf(": can't map i/o space\n"); return; } /* Set up DMA structures. */ sc->sc_dmat = ca->ca_dmat; /* * Allocate the control data structures, and create and load the * DMA map for it. */ if ((err = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct mec_control_data), MEC_CONTROL_DATA_ALIGN, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { printf(": unable to allocate control data, error = %d\n", err); goto fail_0; } /* * XXX needs re-think... * control data structures contain whole RX data buffer, so * BUS_DMA_COHERENT (which disables cache) may cause some performance * issue on copying data from the RX buffer to mbuf on normal memory, * though we have to make sure all bus_dmamap_sync(9) ops are called * properly in that case. */ if ((err = bus_dmamem_map(sc->sc_dmat, &seg, rseg, sizeof(struct mec_control_data), (caddr_t *)&sc->sc_control_data, /*BUS_DMA_COHERENT*/ 0)) != 0) { printf(": unable to map control data, error = %d\n", err); goto fail_1; } memset(sc->sc_control_data, 0, sizeof(struct mec_control_data)); if ((err = bus_dmamap_create(sc->sc_dmat, sizeof(struct mec_control_data), 1, sizeof(struct mec_control_data), 0, 0, &sc->sc_cddmamap)) != 0) { printf(": unable to create control data DMA map, error = %d\n", err); goto fail_2; } if ((err = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap, sc->sc_control_data, sizeof(struct mec_control_data), NULL, BUS_DMA_NOWAIT)) != 0) { printf(": unable to load control data DMA map, error = %d\n", err); goto fail_3; } /* Create TX buffer DMA maps. */ for (i = 0; i < MEC_NTXDESC; i++) { if ((err = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 0, &sc->sc_txsoft[i].txs_dmamap)) != 0) { printf(": unable to create tx DMA map %d, error = %d\n", i, err); goto fail_4; } } timeout_set(&sc->sc_tick_ch, mec_tick, sc); /* Use the Ethernet address from the ARCBIOS. */ enaddr_aton(bios_enaddr, sc->sc_ac.ac_enaddr); /* Reset device. */ mec_reset(sc); command = bus_space_read_8(sc->sc_st, sc->sc_sh, MEC_MAC_CONTROL); printf(": MAC-110 rev %d, address %s\n", (command & MEC_MAC_REVISION) >> MEC_MAC_REVISION_SHIFT, ether_sprintf(sc->sc_ac.ac_enaddr)); /* Done, now attach everything. */ sc->sc_mii.mii_ifp = ifp; sc->sc_mii.mii_readreg = mec_mii_readreg; sc->sc_mii.mii_writereg = mec_mii_writereg; sc->sc_mii.mii_statchg = mec_statchg; /* Set up PHY properties. */ ifmedia_init(&sc->sc_mii.mii_media, 0, mec_mediachange, mec_mediastatus); mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); child = LIST_FIRST(&sc->sc_mii.mii_phys); if (child == NULL) { /* No PHY attached. */ ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL, 0, NULL); ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL); } else { ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO); sc->sc_phyaddr = child->mii_phy; } bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = mec_ioctl; ifp->if_start = mec_start; ifp->if_watchdog = mec_watchdog; IFQ_SET_READY(&ifp->if_snd); if_attach(ifp); IFQ_SET_MAXLEN(&ifp->if_snd, MEC_NTXDESC - 1); ether_ifattach(ifp); /* Establish interrupt handler. */ macebus_intr_establish(NULL, ca->ca_intr, IST_EDGE, IPL_NET, mec_intr, sc, sc->sc_dev.dv_xname); /* Set hook to stop interface on shutdown. */ sc->sc_sdhook = shutdownhook_establish(mec_shutdown, sc); return; /* * Free any resources we've allocated during the failed attach * attempt. Do this in reverse order and fall though. */ fail_4: for (i = 0; i < MEC_NTXDESC; i++) { if (sc->sc_txsoft[i].txs_dmamap != NULL) bus_dmamap_destroy(sc->sc_dmat, sc->sc_txsoft[i].txs_dmamap); } bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap); fail_3: bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap); fail_2: bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data, sizeof(struct mec_control_data)); fail_1: bus_dmamem_free(sc->sc_dmat, &seg, rseg); fail_0: return; }