static int an_pccard_attach(device_t dev) { struct an_softc *sc = device_get_softc(dev); struct ifnet *ifp = &sc->arpcom.ac_if; int flags = device_get_flags(dev); int error; an_alloc_port(dev, sc->port_rid, AN_IOSIZ); an_alloc_irq(dev, sc->irq_rid, 0); sc->an_bhandle = rman_get_bushandle(sc->port_res); sc->an_btag = rman_get_bustag(sc->port_res); error = an_attach(sc, dev, flags); if (error) goto fail; /* * Must setup the interrupt after the an_attach to prevent racing. */ error = bus_setup_intr(dev, sc->irq_res, INTR_MPSAFE, an_intr, sc, &sc->irq_handle, sc->arpcom.ac_if.if_serializer); if (error) { ether_ifdetach(&sc->arpcom.ac_if); ifmedia_removeall(&sc->an_ifmedia); goto fail; } ifp->if_cpuid = ithread_cpuid(rman_get_start(sc->irq_res)); KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus); return 0; fail: an_release_resources(dev); return (error); }
static int ep_pccard_attach(device_t dev) { struct ep_softc * sc = device_get_softc(dev); struct ifnet * ifp = &sc->arpcom.ac_if; int error = 0; if ((error = ep_alloc(dev))) { device_printf(dev, "ep_alloc() failed! (%d)\n", error); goto bad; } sc->epb.cmd_off = 0; sc->epb.prod_id = get_e(sc, EEPROM_PROD_ID); if (!ep_pccard_card_attach(&sc->epb)) { sc->epb.cmd_off = 2; sc->epb.prod_id = get_e(sc, EEPROM_PROD_ID); sc->epb.res_cfg = get_e(sc, EEPROM_RESOURCE_CFG); if (!ep_pccard_card_attach(&sc->epb)) { device_printf(dev, "Probe found ID, attach failed so ignore card!\n"); error = ENXIO; goto bad; } } /* ROM size = 0, ROM base = 0 */ /* For now, ignore AUTO SELECT feature of 3C589B and later. */ outw(BASE + EP_W0_ADDRESS_CFG, get_e(sc, EEPROM_ADDR_CFG) & 0xc000); /* Fake IRQ must be 3 */ outw(BASE + EP_W0_RESOURCE_CFG, (sc->epb.res_cfg & 0x0fff) | 0x3000); outw(BASE + EP_W0_PRODUCT_ID, sc->epb.prod_id); if (sc->epb.mii_trans) { /* * turn on the MII transciever */ GO_WINDOW(3); outw(BASE + EP_W3_OPTIONS, 0x8040); DELAY(1000); outw(BASE + EP_W3_OPTIONS, 0xc040); outw(BASE + EP_COMMAND, RX_RESET); outw(BASE + EP_COMMAND, TX_RESET); while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS); DELAY(1000); outw(BASE + EP_W3_OPTIONS, 0x8040); } else { ep_get_media(sc); } if ((error = ep_attach(sc))) { device_printf(dev, "ep_attach() failed! (%d)\n", error); goto bad; } error = bus_setup_intr(dev, sc->irq, INTR_MPSAFE, ep_intr, sc, &sc->ep_intrhand, sc->arpcom.ac_if.if_serializer); if (error) { device_printf(dev, "bus_setup_intr() failed! (%d)\n", error); goto bad; } ifp->if_cpuid = ithread_cpuid(rman_get_start(sc->irq)); KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus); return (0); bad: ep_free(dev); return (error); }
static int txp_attach(device_t dev) { struct txp_softc *sc; struct ifnet *ifp; uint16_t p1; uint32_t p2; uint8_t enaddr[ETHER_ADDR_LEN]; int error = 0, rid; sc = device_get_softc(dev); callout_init(&sc->txp_stat_timer); ifp = &sc->sc_arpcom.ac_if; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); pci_enable_busmaster(dev); rid = TXP_RID; sc->sc_res = bus_alloc_resource_any(dev, TXP_RES, &rid, RF_ACTIVE); if (sc->sc_res == NULL) { device_printf(dev, "couldn't map ports/memory\n"); return(ENXIO); } sc->sc_bt = rman_get_bustag(sc->sc_res); sc->sc_bh = rman_get_bushandle(sc->sc_res); /* Allocate interrupt */ rid = 0; sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); if (sc->sc_irq == NULL) { device_printf(dev, "couldn't map interrupt\n"); error = ENXIO; goto fail; } if (txp_chip_init(sc)) { error = ENXIO; goto fail; } sc->sc_fwbuf = contigmalloc(32768, M_DEVBUF, M_WAITOK, 0, 0xffffffff, PAGE_SIZE, 0); error = txp_download_fw(sc); contigfree(sc->sc_fwbuf, 32768, M_DEVBUF); sc->sc_fwbuf = NULL; if (error) goto fail; sc->sc_ldata = contigmalloc(sizeof(struct txp_ldata), M_DEVBUF, M_WAITOK | M_ZERO, 0, 0xffffffff, PAGE_SIZE, 0); if (txp_alloc_rings(sc)) { error = ENXIO; goto fail; } if (txp_command(sc, TXP_CMD_MAX_PKT_SIZE_WRITE, TXP_MAX_PKTLEN, 0, 0, NULL, NULL, NULL, 1)) { error = ENXIO; goto fail; } if (txp_command(sc, TXP_CMD_STATION_ADDRESS_READ, 0, 0, 0, &p1, &p2, NULL, 1)) { error = ENXIO; goto fail; } txp_set_filter(sc); enaddr[0] = ((uint8_t *)&p1)[1]; enaddr[1] = ((uint8_t *)&p1)[0]; enaddr[2] = ((uint8_t *)&p2)[3]; enaddr[3] = ((uint8_t *)&p2)[2]; enaddr[4] = ((uint8_t *)&p2)[1]; enaddr[5] = ((uint8_t *)&p2)[0]; ifmedia_init(&sc->sc_ifmedia, 0, txp_ifmedia_upd, txp_ifmedia_sts); ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_10_T, 0, NULL); ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL); ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL); ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL); ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_100_TX|IFM_HDX, 0, NULL); ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL); ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL); sc->sc_xcvr = TXP_XCVR_AUTO; txp_command(sc, TXP_CMD_XCVR_SELECT, TXP_XCVR_AUTO, 0, 0, NULL, NULL, NULL, 0); ifmedia_set(&sc->sc_ifmedia, IFM_ETHER|IFM_AUTO); ifp->if_softc = sc; ifp->if_mtu = ETHERMTU; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = txp_ioctl; ifp->if_start = txp_start; ifp->if_watchdog = txp_watchdog; ifp->if_init = txp_init; ifp->if_baudrate = 100000000; ifq_set_maxlen(&ifp->if_snd, TX_ENTRIES); ifq_set_ready(&ifp->if_snd); ifp->if_hwassist = 0; txp_capabilities(sc); ether_ifattach(ifp, enaddr, NULL); error = bus_setup_intr(dev, sc->sc_irq, INTR_MPSAFE, txp_intr, sc, &sc->sc_intrhand, ifp->if_serializer); if (error) { device_printf(dev, "couldn't set up irq\n"); ether_ifdetach(ifp); goto fail; } ifp->if_cpuid = ithread_cpuid(rman_get_start(sc->sc_irq)); KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus); return(0); fail: txp_release_resources(dev); return(error); }
static int le_pci_attach(device_t dev) { struct le_pci_softc *lesc; struct lance_softc *sc; int error, i; lesc = device_get_softc(dev); sc = &lesc->sc_am79900.lsc; pci_enable_busmaster(dev); pci_enable_io(dev, PCIM_CMD_PORTEN); lesc->sc_rrid = PCIR_BAR(0); lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &lesc->sc_rrid, RF_ACTIVE); if (lesc->sc_rres == NULL) { device_printf(dev, "cannot allocate registers\n"); error = ENXIO; goto fail_mtx; } lesc->sc_regt = rman_get_bustag(lesc->sc_rres); lesc->sc_regh = rman_get_bushandle(lesc->sc_rres); lesc->sc_irid = 0; if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &lesc->sc_irid, RF_SHAREABLE | RF_ACTIVE)) == NULL) { device_printf(dev, "cannot allocate interrupt\n"); error = ENXIO; goto fail_rres; } error = bus_dma_tag_create( NULL, /* parent */ 1, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ 0, /* nsegments */ BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ BUS_DMA_WAITOK, /* flags */ &lesc->sc_pdmat); if (error != 0) { device_printf(dev, "cannot allocate parent DMA tag\n"); goto fail_ires; } sc->sc_memsize = PCNET_MEMSIZE; /* * For Am79C970A, Am79C971 and Am79C978 the init block must be 2-byte * aligned and the ring descriptors must be 16-byte aligned when using * a 32-bit software style. */ error = bus_dma_tag_create( lesc->sc_pdmat, /* parent */ 16, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ sc->sc_memsize, /* maxsize */ 1, /* nsegments */ sc->sc_memsize, /* maxsegsize */ BUS_DMA_WAITOK, /* flags */ &lesc->sc_dmat); if (error != 0) { device_printf(dev, "cannot allocate buffer DMA tag\n"); goto fail_pdtag; } error = bus_dmamem_alloc(lesc->sc_dmat, (void **)&sc->sc_mem, BUS_DMA_WAITOK | BUS_DMA_COHERENT, &lesc->sc_dmam); if (error != 0) { device_printf(dev, "cannot allocate DMA buffer memory\n"); goto fail_dtag; } sc->sc_addr = 0; error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem, sc->sc_memsize, le_pci_dma_callback, sc, 0); if (error != 0 || sc->sc_addr == 0) { device_printf(dev, "cannot load DMA buffer map\n"); goto fail_dmem; } sc->sc_flags = LE_BSWAP; sc->sc_conf3 = 0; sc->sc_mediastatus = NULL; switch (pci_get_device(dev)) { case AMD_PCNET_HOME: sc->sc_mediachange = le_pci_mediachange; sc->sc_supmedia = le_home_supmedia; sc->sc_nsupmedia = sizeof(le_home_supmedia) / sizeof(int); sc->sc_defaultmedia = le_home_supmedia[0]; break; default: sc->sc_mediachange = le_pci_mediachange; sc->sc_supmedia = le_pci_supmedia; sc->sc_nsupmedia = sizeof(le_pci_supmedia) / sizeof(int); sc->sc_defaultmedia = le_pci_supmedia[0]; } /* * Extract the physical MAC address from the ROM. */ for (i = 0; i < sizeof(sc->sc_enaddr); i++) sc->sc_enaddr[i] = bus_space_read_1(lesc->sc_regt, lesc->sc_regh, i); sc->sc_copytodesc = lance_copytobuf_contig; sc->sc_copyfromdesc = lance_copyfrombuf_contig; sc->sc_copytobuf = lance_copytobuf_contig; sc->sc_copyfrombuf = lance_copyfrombuf_contig; sc->sc_zerobuf = lance_zerobuf_contig; sc->sc_rdcsr = le_pci_rdcsr; sc->sc_wrcsr = le_pci_wrcsr; sc->sc_hwreset = le_pci_hwreset; sc->sc_hwinit = NULL; sc->sc_hwintr = NULL; sc->sc_nocarrier = NULL; error = am79900_config(&lesc->sc_am79900, device_get_name(dev), device_get_unit(dev)); if (error != 0) { device_printf(dev, "cannot attach Am79900\n"); goto fail_dmap; } error = bus_setup_intr(dev, lesc->sc_ires, INTR_MPSAFE, am79900_intr, sc, &lesc->sc_ih, sc->ifp->if_serializer); if (error != 0) { device_printf(dev, "cannot set up interrupt\n"); goto fail_am79900; } sc->ifp->if_cpuid = ithread_cpuid(rman_get_start(lesc->sc_ires)); KKASSERT(sc->ifp->if_cpuid >= 0 && sc->ifp->if_cpuid < ncpus); return (0); fail_am79900: am79900_detach(&lesc->sc_am79900); fail_dmap: bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam); fail_dmem: bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam); fail_dtag: bus_dma_tag_destroy(lesc->sc_dmat); fail_pdtag: bus_dma_tag_destroy(lesc->sc_pdmat); fail_ires: bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires); fail_rres: bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres); fail_mtx: return (error); }
static int le_isa_attach(device_t dev) { struct le_isa_softc *lesc; struct lance_softc *sc; bus_size_t macstart, rap, rdp; int error, i, macstride; lesc = device_get_softc(dev); sc = &lesc->sc_am7990.lsc; lesc->sc_rrid = 0; switch (ISA_PNP_PROBE(device_get_parent(dev), dev, le_isa_ids)) { case 0: lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &lesc->sc_rrid, RF_ACTIVE); rap = PCNET_RAP; rdp = PCNET_RDP; macstart = 0; macstride = 1; break; case ENOENT: for (i = 0; i < sizeof(le_isa_params) / sizeof(le_isa_params[0]); i++) { if (le_isa_probe_legacy(dev, &le_isa_params[i]) == 0) { lesc->sc_rres = bus_alloc_resource(dev, SYS_RES_IOPORT, &lesc->sc_rrid, 0, ~0, le_isa_params[i].iosize, RF_ACTIVE); rap = le_isa_params[i].rap; rdp = le_isa_params[i].rdp; macstart = le_isa_params[i].macstart; macstride = le_isa_params[i].macstride; goto found; } } /* FALLTHROUGH */ case ENXIO: default: device_printf(dev, "cannot determine chip\n"); error = ENXIO; goto fail_mtx; } found: if (lesc->sc_rres == NULL) { device_printf(dev, "cannot allocate registers\n"); error = ENXIO; goto fail_mtx; } lesc->sc_regt = rman_get_bustag(lesc->sc_rres); lesc->sc_regh = rman_get_bushandle(lesc->sc_rres); lesc->sc_rap = rap; lesc->sc_rdp = rdp; lesc->sc_drid = 0; if ((lesc->sc_dres = bus_alloc_resource_any(dev, SYS_RES_DRQ, &lesc->sc_drid, RF_ACTIVE)) == NULL) { device_printf(dev, "cannot allocate DMA channel\n"); error = ENXIO; goto fail_rres; } lesc->sc_irid = 0; if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &lesc->sc_irid, RF_SHAREABLE | RF_ACTIVE)) == NULL) { device_printf(dev, "cannot allocate interrupt\n"); error = ENXIO; goto fail_dres; } error = bus_dma_tag_create( NULL, /* parent */ 1, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_24BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ 0, /* nsegments */ BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ BUS_DMA_WAITOK, /* flags */ &lesc->sc_pdmat); if (error != 0) { device_printf(dev, "cannot allocate parent DMA tag\n"); goto fail_ires; } sc->sc_memsize = LE_ISA_MEMSIZE; /* * For Am79C90, Am79C961 and Am79C961A the init block must be 2-byte * aligned and the ring descriptors must be 8-byte aligned. */ error = bus_dma_tag_create( lesc->sc_pdmat, /* parent */ 8, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_24BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ sc->sc_memsize, /* maxsize */ 1, /* nsegments */ sc->sc_memsize, /* maxsegsize */ BUS_DMA_WAITOK, /* flags */ &lesc->sc_dmat); if (error != 0) { device_printf(dev, "cannot allocate buffer DMA tag\n"); goto fail_pdtag; } error = bus_dmamem_alloc(lesc->sc_dmat, (void **)&sc->sc_mem, BUS_DMA_WAITOK | BUS_DMA_COHERENT, &lesc->sc_dmam); if (error != 0) { device_printf(dev, "cannot allocate DMA buffer memory\n"); goto fail_dtag; } sc->sc_addr = 0; error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem, sc->sc_memsize, le_isa_dma_callback, sc, 0); if (error != 0 || sc->sc_addr == 0) { device_printf(dev, "cannot load DMA buffer map\n"); goto fail_dmem; } isa_dmacascade(rman_get_start(lesc->sc_dres)); sc->sc_flags = 0; sc->sc_conf3 = 0; /* * Extract the physical MAC address from the ROM. */ for (i = 0; i < sizeof(sc->sc_enaddr); i++) sc->sc_enaddr[i] = bus_space_read_1(lesc->sc_regt, lesc->sc_regh, macstart + i * macstride); sc->sc_copytodesc = lance_copytobuf_contig; sc->sc_copyfromdesc = lance_copyfrombuf_contig; sc->sc_copytobuf = lance_copytobuf_contig; sc->sc_copyfrombuf = lance_copyfrombuf_contig; sc->sc_zerobuf = lance_zerobuf_contig; sc->sc_rdcsr = le_isa_rdcsr; sc->sc_wrcsr = le_isa_wrcsr; sc->sc_hwreset = NULL; sc->sc_hwinit = NULL; sc->sc_hwintr = NULL; sc->sc_nocarrier = NULL; sc->sc_mediachange = NULL; sc->sc_mediastatus = NULL; sc->sc_supmedia = NULL; error = am7990_config(&lesc->sc_am7990, device_get_name(dev), device_get_unit(dev)); if (error != 0) { device_printf(dev, "cannot attach Am7990\n"); goto fail_dmap; } error = bus_setup_intr(dev, lesc->sc_ires, INTR_MPSAFE, am7990_intr, sc, &lesc->sc_ih, sc->ifp->if_serializer); if (error != 0) { device_printf(dev, "cannot set up interrupt\n"); goto fail_am7990; } sc->ifp->if_cpuid = ithread_cpuid(rman_get_start(lesc->sc_ires)); KKASSERT(sc->ifp->if_cpuid >= 0 && sc->ifp->if_cpuid < ncpus); return (0); fail_am7990: am7990_detach(&lesc->sc_am7990); fail_dmap: bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam); fail_dmem: bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam); fail_dtag: bus_dma_tag_destroy(lesc->sc_dmat); fail_pdtag: bus_dma_tag_destroy(lesc->sc_pdmat); fail_ires: bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires); fail_dres: bus_release_resource(dev, SYS_RES_DRQ, lesc->sc_drid, lesc->sc_dres); fail_rres: bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres); fail_mtx: return (error); }