Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
/*
 * 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);
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
0
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);
}