int snc_attach(device_t dev) { struct snc_softc *sc = device_get_softc(dev); u_int8_t myea[ETHER_ADDR_LEN]; int error; if (snc_nec16_register_irq(sc, rman_get_start(sc->irq)) == 0 || snc_nec16_register_mem(sc, rman_get_start(sc->iomem)) == 0) { snc_release_resources(dev); return(ENOENT); } snc_nec16_get_enaddr(sc->sc_iot, sc->sc_ioh, myea); device_printf(dev, "%s Ethernet\n", snc_nec16_detect_type(myea)); sc->sc_dev = dev; sc->sncr_dcr = DCR_SYNC | DCR_WAIT0 | DCR_DMABLOCK | DCR_RFT16 | DCR_TFT28; sc->sncr_dcr2 = 0; /* XXX */ sc->bitmode = 0; /* 16 bit card */ sc->sc_nic_put = snc_nec16_nic_put; sc->sc_nic_get = snc_nec16_nic_get; sc->sc_writetodesc = snc_nec16_writetodesc; sc->sc_readfromdesc = snc_nec16_readfromdesc; sc->sc_copytobuf = snc_nec16_copytobuf; sc->sc_copyfrombuf = snc_nec16_copyfrombuf; sc->sc_zerobuf = snc_nec16_zerobuf; /* sncsetup returns 1 if something fails */ if (sncsetup(sc, myea)) { snc_release_resources(dev); return(ENOENT); } mtx_init(&sc->sc_lock, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF); callout_init_mtx(&sc->sc_timer, &sc->sc_lock, 0); error = sncconfig(sc, NULL, 0, 0, myea); if (error) { snc_release_resources(dev); mtx_destroy(&sc->sc_lock); return (error); } error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, NULL, sncintr, sc, &sc->irq_handle); if (error) { printf("snc_isa_attach: bus_setup_intr() failed\n"); ether_ifdetach(sc->sc_ifp); snc_release_resources(dev); mtx_destroy(&sc->sc_lock); return (error); } return 0; }
static int snc_pccard_attach(device_t dev) { struct snc_softc *sc = device_get_softc(dev); int error; /* * Not sure that this belongs here or in snc_pccard_attach */ if ((error = snc_alloc_port(dev, 0)) != 0) goto err; if ((error = snc_alloc_memory(dev, 0)) != 0) goto err; if ((error = snc_alloc_irq(dev, 0, 0)) != 0) goto err; if ((error = snc_probe(dev, SNEC_TYPE_PNP)) != 0) goto err; /* This interface is always enabled. */ sc->sc_enabled = 1; /* pccard_get_ether(dev, ether_addr); */ if ((error = snc_attach(dev)) != 0) goto err; return 0; err:; snc_release_resources(dev); return error; }
static int snc_pccard_attach(device_t dev) { struct snc_softc *sc = device_get_softc(dev); int error; bzero(sc, sizeof(struct snc_softc)); snc_alloc_port(dev, 0); snc_alloc_memory(dev, 0); snc_alloc_irq(dev, 0, 0); error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, sncintr, sc, &sc->irq_handle); if (error) { printf("snc_isa_attach: bus_setup_intr() failed\n"); snc_release_resources(dev); return (error); } /* This interface is always enabled. */ sc->sc_enabled = 1; /* pccard_get_ether(dev, ether_addr); */ return snc_attach(dev); }
/* * Probe framework for pccards. Replicates the standard framework, * minus the pccard driver registration and ignores the ether address * supplied (from the CIS), relying on the probe to find it instead. */ static int snc_pccard_probe(device_t dev) { int error; error = snc_alloc_port(dev, 0); error = max(error, snc_alloc_memory(dev, 0)); error = max(error, snc_alloc_irq(dev, 0, 0)); if (!error && !snc_probe(dev, SNEC_TYPE_PNP)) error = ENOENT; snc_release_resources(dev); return (error); }
/* * snc_pccard_detach - unload the driver and clear the table. * XXX TODO: * This is usually called when the card is ejected, but * can be caused by a modunload of a controller driver. * The idea is to reset the driver's view of the device * and ensure that any driver entry points such as * read and write do not hang. */ static int snc_pccard_detach(device_t dev) { struct snc_softc *sc = device_get_softc(dev); struct ifnet *ifp = &sc->sc_if; if (sc->gone) { device_printf(dev, "already unloaded\n"); return (0); } sncshutdown(sc); ifp->if_flags &= ~IFF_RUNNING; if_detach(ifp); sc->gone = 1; bus_teardown_intr(dev, sc->irq, sc->irq_handle); snc_release_resources(dev); return (0); }
/* * snc_pccard_detach - detach this instance from the device. */ static int snc_pccard_detach(device_t dev) { struct snc_softc *sc = device_get_softc(dev); struct ifnet *ifp = sc->sc_ifp; if (sc->gone) { device_printf(dev, "already unloaded\n"); return (0); } SNC_LOCK(sc); sncshutdown(sc); SNC_UNLOCK(sc); callout_drain(&sc->sc_timer); ether_ifdetach(ifp); sc->gone = 1; bus_teardown_intr(dev, sc->irq, sc->irq_handle); snc_release_resources(dev); mtx_destroy(&sc->sc_lock); return (0); }
static int snc_isa_probe(device_t dev) { struct snc_softc *sc = device_get_softc(dev); int type; int error = 0; bzero(sc, sizeof(struct snc_softc)); /* Check isapnp ids */ error = ISA_PNP_PROBE(device_get_parent(dev), dev, snc_ids); /* If the card had a PnP ID that didn't match any we know about */ if (error == ENXIO) { return(error); } switch (error) { case 0: /* Matched PnP */ type = SNEC_TYPE_PNP; break; case ENOENT: /* Legacy ISA */ type = SNEC_TYPE_LEGACY; break; default: /* If we had some other problem. */ return(error); } if (type == SNEC_TYPE_PNP && isa_get_portsize(dev) == 0) { int port; int rid = 0; struct resource *res = NULL; for (port = 0x0888; port <= 0x3888; port += 0x1000) { bus_set_resource(dev, SYS_RES_IOPORT, rid, port, SNEC_NREGS); res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0ul, ~0ul, SNEC_NREGS, 0 /* !RF_ACTIVE */); if (res) break; } printf("snc_isa_probe: broken PnP resource, "); if (res) { printf("use port 0x%x\n", port); bus_release_resource(dev, SYS_RES_IOPORT, rid, res); snc_isapnp_reconfig(dev); } else { printf("and can't find port\n"); } } error = snc_alloc_port(dev, 0); error = max(error, snc_alloc_memory(dev, 0)); error = max(error, snc_alloc_irq(dev, 0, 0)); if (!error && !snc_probe(dev, type)) error = ENOENT; snc_release_resources(dev); return (error); }