void wdc_spd_attach(device_t parent, device_t self, void *aux) { struct spd_attach_args *spa = aux; struct wdc_spd_softc *sc = device_private(self); struct wdc_softc *wdc = &sc->sc_wdcdev; struct ata_channel *ch = &sc->sc_channel; aprint_normal(": %s\n", spa->spa_product_name); sc->sc_wdcdev.sc_atac.atac_dev = self; sc->sc_wdcdev.regs = &sc->sc_wdc_regs; wdc->sc_atac.atac_cap = ATAC_CAP_DMA | ATAC_CAP_UDMA | ATAC_CAP_DATA16; wdc->sc_atac.atac_pio_cap = 0; sc->sc_chanlist[0] = &sc->sc_channel; wdc->sc_atac.atac_channels = sc->sc_chanlist; wdc->sc_atac.atac_nchannels = 1; ch->ch_channel = 0; ch->ch_atac = &sc->sc_wdcdev.sc_atac; ch->ch_queue = &sc->sc_chqueue; ch->ch_ndrive = 2; __wdc_spd_bus_space(ch); spd_intr_establish(SPD_HDD, wdcintr, &sc->sc_channel); __wdc_spd_enable(); wdcattach(&sc->sc_channel); }
void smap_attach(struct device *parent, struct device *self, void *aux) { struct spd_attach_args *spa = aux; struct smap_softc *sc = (void *)self; struct emac3_softc *emac3 = &sc->emac3; struct ifnet *ifp = &sc->ethercom.ec_if; struct mii_data *mii = &emac3->mii; void *txbuf, *rxbuf; u_int16_t r; #ifdef SMAP_DEBUG __sc = sc; #endif printf(": %s\n", spa->spa_product_name); /* SPD EEPROM */ if (smap_get_eaddr(sc, emac3->eaddr) != 0) return; printf("%s: Ethernet address %s\n", DEVNAME, ether_sprintf(emac3->eaddr)); /* disable interrupts */ r = _reg_read_2(SPD_INTR_ENABLE_REG16); r &= ~(SPD_INTR_RXEND | SPD_INTR_TXEND | SPD_INTR_RXDNV | SPD_INTR_EMAC3); _reg_write_2(SPD_INTR_ENABLE_REG16, r); emac3_intr_disable(); /* clear pending interrupts */ _reg_write_2(SPD_INTR_CLEAR_REG16, SPD_INTR_RXEND | SPD_INTR_TXEND | SPD_INTR_RXDNV); emac3_intr_clear(); /* buffer descriptor mode */ _reg_write_1(SMAP_DESC_MODE_REG8, 0); if (smap_fifo_init(sc) != 0) return; if (emac3_init(&sc->emac3) != 0) return; emac3_intr_disable(); emac3_disable(); smap_desc_init(sc); /* allocate temporary buffer */ txbuf = malloc(ETHER_MAX_LEN - ETHER_CRC_LEN + SMAP_FIFO_ALIGN + 16, M_DEVBUF, M_NOWAIT); if (txbuf == NULL) { printf("%s: no memory.\n", DEVNAME); return; } rxbuf = malloc(ETHER_MAX_LEN + SMAP_FIFO_ALIGN + 16, M_DEVBUF, M_NOWAIT); if (rxbuf == NULL) { printf("%s: no memory.\n", DEVNAME); free(txbuf, M_DEVBUF); return; } sc->tx_buf = (u_int32_t *)ROUND16((vaddr_t)txbuf); sc->rx_buf = (u_int32_t *)ROUND16((vaddr_t)rxbuf); /* * setup MI layer */ strcpy(ifp->if_xname, DEVNAME); ifp->if_softc = sc; ifp->if_start = smap_start; ifp->if_ioctl = smap_ioctl; ifp->if_init = smap_init; ifp->if_stop = smap_stop; ifp->if_watchdog= smap_watchdog; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; IFQ_SET_READY(&ifp->if_snd); /* ifmedia setup. */ mii->mii_ifp = ifp; mii->mii_readreg = emac3_phy_readreg; mii->mii_writereg = emac3_phy_writereg; mii->mii_statchg = emac3_phy_statchg; sc->ethercom.ec_mii = mii; ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus); mii_attach(&emac3->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_NONE, 0, NULL); ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_NONE); } else { ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO); } if_attach(ifp); ether_ifattach(ifp, emac3->eaddr); spd_intr_establish(SPD_NIC, smap_intr, sc); #if NRND > 0 rnd_attach_source(&sc->rnd_source, DEVNAME, RND_TYPE_NET, RND_FLAG_DEFAULT); #endif }