static int ed_isa_attach(device_t dev) { struct ed_softc *sc = device_get_softc(dev); int error; if (sc->port_used > 0) ed_alloc_port(dev, 0, sc->port_used); if (sc->mem_used) ed_alloc_memory(dev, 0, sc->mem_used); ed_alloc_irq(dev, 0, 0); if (sc->sc_media_ioctl == NULL) ed_gen_ifmedia_init(sc); error = ed_attach(dev); if (error) { ed_release_resources(dev); return (error); } error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, NULL, edintr, sc, &sc->irq_handle); if (error) ed_release_resources(dev); return (error); }
static int ed_pci_attach(device_t dev) { struct ed_softc *sc = device_get_softc(dev); int flags = 0; int error; error = ed_probe_Novell(dev, PCIR_MAPS, flags); if (error) return (error); error = ed_alloc_irq(dev, 0, RF_SHAREABLE); if (error) { ed_release_resources(dev); return (error); } error = ed_attach(dev); if (error == 0) { struct ifnet *ifp = &sc->arpcom.ac_if; error = bus_setup_intr(dev, sc->irq_res, INTR_MPSAFE, edintr, sc, &sc->irq_handle, ifp->if_serializer); if (error) { ed_pci_detach(dev); } else { ifp->if_cpuid = rman_get_cpuid(sc->irq_res); KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus); } } else { ed_release_resources(dev); } return (error); }
static int ed_pci_attach(device_t dev) { struct ed_softc *sc = device_get_softc(dev); int flags = 0; int error; error = ed_probe_Novell_generic(dev, PCIR_MAPS, flags); if (error) return (error); error = ed_alloc_irq(dev, 0, RF_SHAREABLE); if (error) { ed_release_resources(dev); return (error); } error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, edintr, sc, &sc->irq_handle); if (error) { ed_release_resources(dev); return (error); } error = ed_attach(sc, device_get_unit(dev), flags); return (error); }
/* * Detach the driver from the hardware and other systems in the kernel. */ int ed_detach(device_t dev) { struct ed_softc *sc = device_get_softc(dev); struct ifnet *ifp = sc->ifp; if (mtx_initialized(ED_MUTEX(sc))) ED_ASSERT_UNLOCKED(sc); if (ifp) { ED_LOCK(sc); if (bus_child_present(dev)) ed_stop(sc); ifp->if_drv_flags &= ~IFF_DRV_RUNNING; ED_UNLOCK(sc); ether_ifdetach(ifp); callout_drain(&sc->tick_ch); } if (sc->irq_res != NULL && sc->irq_handle) bus_teardown_intr(dev, sc->irq_res, sc->irq_handle); ed_release_resources(dev); if (sc->miibus) device_delete_child(dev, sc->miibus); if (mtx_initialized(ED_MUTEX(sc))) ED_LOCK_DESTROY(sc); bus_generic_detach(dev); return (0); }
static int ed_pci_attach(device_t dev) { struct ed_softc *sc = device_get_softc(dev); int error = ENXIO; /* * Probe RTL8029 cards, but allow failure and try as a generic * ne-2000. QEMU 0.9 and earlier use the RTL8029 PCI ID, but * are areally just generic ne-2000 cards. */ if (pci_get_devid(dev) == ED_RTL8029_PCI_ID) error = ed_probe_RTL80x9(dev, PCIR_BAR(0), 0); if (error) error = ed_probe_Novell(dev, PCIR_BAR(0), ED_FLAGS_FORCE_16BIT_MODE); if (error) { ed_release_resources(dev); return (error); } ed_Novell_read_mac(sc); error = ed_alloc_irq(dev, 0, RF_SHAREABLE); if (error) { ed_release_resources(dev); return (error); } if (sc->sc_media_ioctl == NULL) ed_gen_ifmedia_init(sc); error = ed_attach(dev); if (error) { ed_release_resources(dev); return (error); } error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, NULL, edintr, sc, &sc->irq_handle); if (error) ed_release_resources(dev); return (error); }
static int ed_pci_detach(device_t dev) { struct ed_softc *sc = device_get_softc(dev); struct ifnet *ifp = &sc->arpcom.ac_if; lwkt_serialize_enter(ifp->if_serializer); if (sc->gone) { device_printf(dev, "already unloaded\n"); lwkt_serialize_exit(ifp->if_serializer); return (0); } ed_stop(sc); ifp->if_flags &= ~IFF_RUNNING; sc->gone = 1; bus_teardown_intr(dev, sc->irq_res, sc->irq_handle); lwkt_serialize_exit(ifp->if_serializer); ether_ifdetach(ifp); ed_release_resources(dev); return (0); }
static int ed_isa_probe(device_t dev) { struct ed_softc *sc = device_get_softc(dev); int flags = device_get_flags(dev); int error = 0; /* Check isapnp ids */ error = ISA_PNP_PROBE(device_get_parent(dev), dev, ed_ids); /* If the card had a PnP ID that didn't match any we know about */ if (error == ENXIO) goto end; /* If we had some other problem. */ if (!(error == 0 || error == ENOENT)) goto end; /* Heuristic probes */ error = ed_probe_WD80x3(dev, 0, flags); if (error == 0) goto end; ed_release_resources(dev); error = ed_probe_RTL80x9(dev, 0, flags); if (error == 0) { ed_Novell_read_mac(sc); goto end; } ed_release_resources(dev); #ifdef ED_3C503 error = ed_probe_3Com(dev, 0, flags); if (error == 0) goto end; ed_release_resources(dev); #endif #ifdef ED_SIC error = ed_probe_SIC(dev, 0, flags); if (error == 0) goto end; ed_release_resources(dev); #endif error = ed_isa_probe_Novell(dev); if (error == 0) goto end; ed_release_resources(dev); #ifdef ED_HPP error = ed_probe_HP_pclanp(dev, 0, flags); if (error == 0) goto end; ed_release_resources(dev); #endif end: if (error == 0) error = ed_alloc_irq(dev, 0, 0); ed_release_resources(dev); return (error); }
static int ed_pccard_attach(device_t dev) { u_char sum; u_char enaddr[ETHER_ADDR_LEN]; const struct ed_product *pp; int error, i, flags, port_rid, modem_rid; struct ed_softc *sc = device_get_softc(dev); u_long size; static uint16_t *intr_vals[] = {NULL, NULL}; sc->dev = dev; if ((pp = (const struct ed_product *) pccard_product_lookup(dev, (const struct pccard_product *) ed_pccard_products, sizeof(ed_pccard_products[0]), NULL)) == NULL) { printf("Can't find\n"); return (ENXIO); } modem_rid = port_rid = -1; if (pp->flags & NE2000DVF_MODEM) { for (i = 0; i < 4; i++) { size = bus_get_resource_count(dev, SYS_RES_IOPORT, i); if (size == ED_NOVELL_IO_PORTS) port_rid = i; else if (size == 8) modem_rid = i; } if (port_rid == -1) { device_printf(dev, "Cannot locate my ports!\n"); return (ENXIO); } } else { port_rid = 0; } /* Allocate the port resource during setup. */ error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS); if (error) { printf("alloc_port failed\n"); return (error); } if (rman_get_size(sc->port_res) == ED_NOVELL_IO_PORTS / 2) { port_rid++; sc->port_res2 = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid, 0ul, ~0ul, 1, RF_ACTIVE); if (sc->port_res2 == NULL || rman_get_size(sc->port_res2) != ED_NOVELL_IO_PORTS / 2) { error = ENXIO; goto bad; } } error = ed_alloc_irq(dev, 0, 0); if (error) goto bad; /* * Determine which chipset we are. Almost all the PC Card chipsets * have the Novel ASIC and NIC offsets. There's 2 known cards that * follow the WD80x3 conventions, which are handled as a special case. */ sc->asic_offset = ED_NOVELL_ASIC_OFFSET; sc->nic_offset = ED_NOVELL_NIC_OFFSET; error = ENXIO; flags = device_get_flags(dev); if (error != 0) error = ed_pccard_dl100xx(dev, pp); if (error != 0) error = ed_pccard_ax88x90(dev, pp); if (error != 0) error = ed_pccard_tc5299j(dev, pp); if (error != 0) { error = ed_probe_Novell_generic(dev, flags); printf("Novell generic probe failed: %d\n", error); } if (error != 0 && (pp->flags & NE2000DVF_TOSHIBA)) { flags |= ED_FLAGS_TOSH_ETHER; flags |= ED_FLAGS_PCCARD; sc->asic_offset = ED_WD_ASIC_OFFSET; sc->nic_offset = ED_WD_NIC_OFFSET; error = ed_probe_WD80x3_generic(dev, flags, intr_vals); } if (error) goto bad; /* * There are several ways to get the MAC address for the card. * Some of the above probe routines can fill in the enaddr. If * not, we run through a number of 'well known' locations: * (1) From the PC Card FUNCE * (2) From offset 0 in the shared memory * (3) From a hinted offset in attribute memory * (4) From 0xff0 in attribute memory * If we can't get a non-zero MAC address from this list, we fail. */ for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++) sum |= sc->enaddr[i]; if (sum == 0) { pccard_get_ether(dev, enaddr); if (bootverbose) device_printf(dev, "CIS MAC %6D\n", enaddr, ":"); for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++) sum |= enaddr[i]; if (sum == 0 && ed_pccard_rom_mac(dev, enaddr)) { if (bootverbose) device_printf(dev, "ROM mac %6D\n", enaddr, ":"); sum++; } if (sum == 0 && pp->flags & NE2000DVF_ENADDR) { for (i = 0; i < ETHER_ADDR_LEN; i++) { pccard_attr_read_1(dev, pp->enoff + i * 2, enaddr + i); sum |= enaddr[i]; } if (bootverbose) device_printf(dev, "Hint %x MAC %6D\n", pp->enoff, enaddr, ":"); } if (sum == 0) { for (i = 0; i < ETHER_ADDR_LEN; i++) { pccard_attr_read_1(dev, ED_DEFAULT_MAC_OFFSET + i * 2, enaddr + i); sum |= enaddr[i]; } if (bootverbose) device_printf(dev, "Fallback MAC %6D\n", enaddr, ":"); } if (sum == 0) { device_printf(dev, "Cannot extract MAC address.\n"); ed_release_resources(dev); return (ENXIO); } bcopy(enaddr, sc->enaddr, ETHER_ADDR_LEN); } error = ed_attach(dev); if (error) goto bad; if (sc->chip_type == ED_CHIP_TYPE_DL10019 || sc->chip_type == ED_CHIP_TYPE_DL10022) { /* Try to attach an MII bus, but ignore errors. */ ed_pccard_dl100xx_mii_reset(sc); (void)mii_attach(dev, &sc->miibus, sc->ifp, ed_ifmedia_upd, ed_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, MIIF_FORCEANEG); } else if (sc->chip_type == ED_CHIP_TYPE_AX88190 || sc->chip_type == ED_CHIP_TYPE_AX88790 || sc->chip_type == ED_CHIP_TYPE_TC5299J) { error = mii_attach(dev, &sc->miibus, sc->ifp, ed_ifmedia_upd, ed_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, MIIF_FORCEANEG); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto bad; } } if (sc->miibus != NULL) { sc->sc_tick = ed_pccard_tick; sc->sc_mediachg = ed_pccard_mediachg; sc->sc_media_ioctl = ed_pccard_media_ioctl; ed_pccard_kick_phy(sc); } else { ed_gen_ifmedia_init(sc); } if (modem_rid != -1) ed_pccard_add_modem(dev); error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, NULL, edintr, sc, &sc->irq_handle); if (error) { device_printf(dev, "setup intr failed %d \n", error); goto bad; } return (0); bad: ed_detach(dev); return (error); }
static int ed_cbus_probe(device_t dev) { struct ed_softc *sc = device_get_softc(dev); int flags = device_get_flags(dev); int error = 0; sc->type = ED_TYPE98(flags); #ifdef ED_DEBUG device_printf(dev, "ed_cbus_probe: sc->type=%x\n", sc->type); #endif /* Check isapnp ids */ error = ISA_PNP_PROBE(device_get_parent(dev), dev, ed_ids); #ifdef ED_DEBUG device_printf(dev, "ed_cbus_probe: ISA_PNP_PROBE returns %d\n", error); #endif /* If the card had a PnP ID that didn't match any we know about */ if (error == ENXIO) goto end; /* If we had some other problem. */ if (!(error == 0 || error == ENOENT)) goto end; /* Heuristic probes */ #ifdef ED_DEBUG device_printf(dev, "ed_cbus_probe: Heuristic probes start\n"); #endif switch (sc->type) { case ED_TYPE98_GENERIC: /* * CAUTION! * sc->type of these boards are overwritten by PC/AT's value. */ /* * SMC EtherEZ98 */ error = ed_probe_EZ98(dev, 0, flags); if (error == 0) goto end; ed_release_resources(dev); /* * Allied Telesis CenterCom LA-98-T */ error = ed_probe_Novell(dev, 0, flags); if (error == 0) { ed_Novell_read_mac(sc); goto end; } break; /* * NE2000-like boards probe routine */ case ED_TYPE98_BDN: /* * ELECOM LANEED LD-BDN * PLANET SMART COM 98 EN-2298 */ case ED_TYPE98_LGY: /* * MELCO LGY-98, IND-SP, IND-SS * MACNICA NE2098 */ case ED_TYPE98_ICM: /* * ICM DT-ET-25, DT-ET-T5, IF-2766ET, IF-2771ET * D-Link DE-298P, DE-298 */ case ED_TYPE98_EGY: /* * MELCO EGY-98 * Contec C-NET(98)E-A, C-NET(98)L-A */ case ED_TYPE98_108: /* * NEC PC-9801-107,108 */ case ED_TYPE98_NC5098: /* * NextCom NC5098 */ error = ed98_probe_Novell(dev, 0, flags); break; /* * other boards with special probe routine */ case ED_TYPE98_SIC: /* * Allied Telesis SIC-98 */ error = ed_probe_SIC98(dev, 0, flags); break; case ED_TYPE98_CNET98EL: /* * Contec C-NET(98)E/L */ error = ed_probe_CNET98EL(dev, 0, flags); break; case ED_TYPE98_CNET98: /* * Contec C-NET(98) */ error = ed_probe_CNET98(dev, 0, flags); break; case ED_TYPE98_LA98: /* * IO-DATA LA/T-98 * NEC PC-9801-77,78 */ error = ed_probe_NEC77(dev, 0, flags); break; case ED_TYPE98_NW98X: /* * Networld EC/EP-98X */ error = ed_probe_NW98X(dev, 0, flags); break; case ED_TYPE98_SB98: /* * Soliton SB-9801 * Fujikura FN-9801 */ error = ed_probe_SB98(dev, 0, flags); break; } end: #ifdef ED_DEBUG device_printf(dev, "ed_cbus_probe: end, error=%d\n", error); #endif if (error == 0) error = ed_alloc_irq(dev, 0, 0); ed_release_resources(dev); return (error); }