static int le_isa_detach(device_t dev) { struct le_isa_softc *lesc; struct lance_softc *sc; lesc = device_get_softc(dev); sc = &lesc->sc_am7990.lsc; bus_teardown_intr(dev, lesc->sc_ires, lesc->sc_ih); am7990_detach(&lesc->sc_am7990); bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam); bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam); bus_dma_tag_destroy(lesc->sc_dmat); bus_dma_tag_destroy(lesc->sc_pdmat); bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(lesc->sc_ires), lesc->sc_ires); bus_release_resource(dev, SYS_RES_DRQ, rman_get_rid(lesc->sc_dres), lesc->sc_dres); bus_release_resource(dev, SYS_RES_IOPORT, rman_get_rid(lesc->sc_rres), lesc->sc_rres); LE_LOCK_DESTROY(sc); return (0); }
static int le_dma_detach(device_t dev) { struct le_dma_softc *lesc; struct lance_softc *sc; int error; lesc = device_get_softc(dev); sc = &lesc->sc_am7990.lsc; bus_teardown_intr(dev, lesc->sc_ires, lesc->sc_ih); am7990_detach(&lesc->sc_am7990); bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam); bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam); bus_dma_tag_destroy(lesc->sc_dmat); error = lsi64854_detach(lesc->sc_dma); if (error != 0) return (error); bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(lesc->sc_ires), lesc->sc_ires); bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lesc->sc_rres), lesc->sc_rres); LE_LOCK_DESTROY(sc); return (0); }
static int le_lebuffer_detach(device_t dev) { struct le_lebuffer_softc *lesc; struct lance_softc *sc; lesc = device_get_softc(dev); sc = &lesc->sc_am7990.lsc; bus_teardown_intr(dev, lesc->sc_ires, lesc->sc_ih); am7990_detach(&lesc->sc_am7990); bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires); bus_release_resource(dev, SYS_RES_MEMORY, lesc->sc_rrid, lesc->sc_rres); bus_release_resource(device_get_parent(dev), SYS_RES_MEMORY, lesc->sc_brid, lesc->sc_bres); LE_LOCK_DESTROY(sc); return (0); }
static int le_lebuffer_attach(device_t dev) { struct le_lebuffer_softc *lesc; struct lance_softc *sc; int error, i; lesc = device_get_softc(dev); sc = &lesc->sc_am7990.lsc; LE_LOCK_INIT(sc, device_get_nameunit(dev)); /* * The "register space" of the parent is just a buffer where the * the LANCE descriptor rings and the RX/TX buffers can be stored. */ i = 0; lesc->sc_bres = bus_alloc_resource_any(device_get_parent(dev), SYS_RES_MEMORY, &i, RF_ACTIVE); if (lesc->sc_bres == NULL) { device_printf(dev, "cannot allocate LANCE buffer\n"); error = ENXIO; goto fail_mtx; } /* Allocate LANCE registers. */ i = 0; lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i, RF_ACTIVE); if (lesc->sc_rres == NULL) { device_printf(dev, "cannot allocate LANCE registers\n"); error = ENXIO; goto fail_bres; } /* Allocate LANCE interrupt. */ i = 0; if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i, RF_SHAREABLE | RF_ACTIVE)) == NULL) { device_printf(dev, "cannot allocate interrupt\n"); error = ENXIO; goto fail_rres; } /* * LANCE view is offset by buffer location. * Note that we don't use sc->sc_mem. */ sc->sc_addr = 0; sc->sc_memsize = rman_get_size(lesc->sc_bres); sc->sc_flags = 0; /* That old black magic... */ if (OF_getprop(ofw_bus_get_node(dev), "busmaster-regval", &sc->sc_conf3, sizeof(sc->sc_conf3)) == -1) sc->sc_conf3 = LE_C3_ACON | LE_C3_BCON; /* * Make sure LE_C3_BSWP is cleared so that for cards where * that flag actually works le_lebuffer_copy{from,to}buf() * don't fail... */ sc->sc_conf3 &= ~LE_C3_BSWP; OF_getetheraddr(dev, sc->sc_enaddr); sc->sc_copytodesc = le_lebuffer_copytodesc; sc->sc_copyfromdesc = le_lebuffer_copyfromdesc; sc->sc_copytobuf = le_lebuffer_copytobuf; sc->sc_copyfrombuf = le_lebuffer_copyfrombuf; sc->sc_zerobuf = le_lebuffer_zerobuf; sc->sc_rdcsr = le_lebuffer_rdcsr; sc->sc_wrcsr = le_lebuffer_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 = le_lebuffer_media; sc->sc_nsupmedia = NLEMEDIA; sc->sc_defaultmedia = le_lebuffer_media[0]; 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_ires; } error = bus_setup_intr(dev, lesc->sc_ires, INTR_TYPE_NET | INTR_MPSAFE, NULL, am7990_intr, sc, &lesc->sc_ih); if (error != 0) { device_printf(dev, "cannot set up interrupt\n"); goto fail_am7990; } return (0); fail_am7990: am7990_detach(&lesc->sc_am7990); fail_ires: bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(lesc->sc_ires), lesc->sc_ires); fail_rres: bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lesc->sc_rres), lesc->sc_rres); fail_bres: bus_release_resource(device_get_parent(dev), SYS_RES_MEMORY, rman_get_rid(lesc->sc_bres), lesc->sc_bres); fail_mtx: LE_LOCK_DESTROY(sc); 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, j, macstride; lesc = device_get_softc(dev); sc = &lesc->sc_am7990.lsc; LE_LOCK_INIT(sc, device_get_nameunit(dev)); j = 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, &j, 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, &j, 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_rap = rap; lesc->sc_rdp = rdp; i = 0; if ((lesc->sc_dres = bus_alloc_resource_any(dev, SYS_RES_DRQ, &i, RF_ACTIVE)) == NULL) { device_printf(dev, "cannot allocate DMA channel\n"); error = ENXIO; goto fail_rres; } i = 0; if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i, RF_SHAREABLE | RF_ACTIVE)) == NULL) { device_printf(dev, "cannot allocate interrupt\n"); error = ENXIO; goto fail_dres; } error = bus_dma_tag_create( bus_get_dma_tag(dev), /* 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 */ 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &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 */ 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &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_read_1(lesc->sc_rres, 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_TYPE_NET | INTR_MPSAFE, NULL, am7990_intr, sc, &lesc->sc_ih); if (error != 0) { device_printf(dev, "cannot set up interrupt\n"); goto fail_am7990; } 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, rman_get_rid(lesc->sc_ires), lesc->sc_ires); fail_dres: bus_release_resource(dev, SYS_RES_DRQ, rman_get_rid(lesc->sc_dres), lesc->sc_dres); fail_rres: bus_release_resource(dev, SYS_RES_IOPORT, rman_get_rid(lesc->sc_rres), lesc->sc_rres); fail_mtx: LE_LOCK_DESTROY(sc); 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; LE_LOCK_INIT(sc, device_get_nameunit(dev)); pci_enable_busmaster(dev); i = PCIR_BAR(0); lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &i, RF_ACTIVE); if (lesc->sc_rres == NULL) { device_printf(dev, "cannot allocate registers\n"); error = ENXIO; goto fail_mtx; } i = 0; if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i, RF_SHAREABLE | RF_ACTIVE)) == NULL) { device_printf(dev, "cannot allocate interrupt\n"); error = ENXIO; goto fail_rres; } error = bus_dma_tag_create( bus_get_dma_tag(dev), /* 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 */ 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &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 */ 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &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. */ bus_read_region_1(lesc->sc_rres, 0, sc->sc_enaddr, sizeof(sc->sc_enaddr)); 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_TYPE_NET | INTR_MPSAFE, NULL, am79900_intr, sc, &lesc->sc_ih); if (error != 0) { device_printf(dev, "cannot set up interrupt\n"); goto fail_am79900; } 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, rman_get_rid(lesc->sc_ires), lesc->sc_ires); fail_rres: bus_release_resource(dev, SYS_RES_IOPORT, rman_get_rid(lesc->sc_rres), lesc->sc_rres); fail_mtx: LE_LOCK_DESTROY(sc); return (error); }
static int le_dma_attach(device_t dev) { struct le_dma_softc *lesc; struct lsi64854_softc *dma; struct lance_softc *sc; int error, i; lesc = device_get_softc(dev); sc = &lesc->sc_am7990.lsc; LE_LOCK_INIT(sc, device_get_nameunit(dev)); /* * Establish link to `ledma' device. * XXX hackery. */ dma = (struct lsi64854_softc *)device_get_softc(device_get_parent(dev)); lesc->sc_dma = dma; lesc->sc_dma->sc_client = lesc; i = 0; lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i, RF_ACTIVE); if (lesc->sc_rres == NULL) { device_printf(dev, "cannot allocate registers\n"); error = ENXIO; goto fail_mtx; } i = 0; if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i, RF_SHAREABLE | RF_ACTIVE)) == NULL) { device_printf(dev, "cannot allocate interrupt\n"); error = ENXIO; goto fail_rres; } /* Attach the DMA engine. */ error = lsi64854_attach(dma); if (error != 0) { device_printf(dev, "lsi64854_attach failed\n"); goto fail_ires; } sc->sc_memsize = LEDMA_MEMSIZE; error = bus_dma_tag_create( dma->sc_parent_dmat, /* parent */ LEDMA_ALIGNMENT, /* alignment */ LEDMA_BOUNDARY, /* boundary */ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ sc->sc_memsize, /* maxsize */ 1, /* nsegments */ sc->sc_memsize, /* maxsegsize */ 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &lesc->sc_dmat); if (error != 0) { device_printf(dev, "cannot allocate buffer DMA tag\n"); goto fail_lsi; } 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; } lesc->sc_laddr = 0; error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem, sc->sc_memsize, le_dma_dma_callback, lesc, 0); if (error != 0 || lesc->sc_laddr == 0) { device_printf(dev, "cannot load DMA buffer map\n"); goto fail_dmem; } sc->sc_addr = lesc->sc_laddr & 0xffffff; sc->sc_flags = 0; sc->sc_conf3 = LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON; sc->sc_mediachange = le_dma_supmediachange; sc->sc_mediastatus = le_dma_supmediastatus; sc->sc_supmedia = le_dma_supmedia; sc->sc_nsupmedia = nitems(le_dma_supmedia); sc->sc_defaultmedia = le_dma_supmedia[0]; OF_getetheraddr(dev, sc->sc_enaddr); 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_dma_rdcsr; sc->sc_wrcsr = le_dma_wrcsr; sc->sc_hwreset = le_dma_hwreset; sc->sc_hwintr = le_dma_hwintr; sc->sc_nocarrier = le_dma_nocarrier; 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_TYPE_NET | INTR_MPSAFE, NULL, am7990_intr, sc, &lesc->sc_ih); if (error != 0) { device_printf(dev, "cannot set up interrupt\n"); goto fail_am7990; } 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_lsi: lsi64854_detach(dma); fail_ires: bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(lesc->sc_ires), lesc->sc_ires); fail_rres: bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lesc->sc_rres), lesc->sc_rres); fail_mtx: LE_LOCK_DESTROY(sc); return (error); }