Index: if_fe.c =================================================================== RCS file: /home/ncvs/src/sys/i386/isa/if_fe.c,v retrieving revision 1.59 diff -u -r1.59 if_fe.c --- if_fe.c 2000/03/29 12:44:19 1.59 +++ if_fe.c 2000/04/26 07:27:39 @@ -80,6 +80,10 @@ #include #include +#include +#include +#include + #include #include #include @@ -220,6 +224,12 @@ int defmedia; /* default media */ void (* msel)(struct fe_softc *); /* media selector. */ + int port_rid; /* resource id for port range */ + struct resource *port_res; /* resource for port range */ + int irq_rid; /* resource id for irq */ + struct resource *irq_res; /* resource for irq */ + void *sc_ih; /* handle for irq handler */ + } fe_softc[NFE]; #define sc_if arpcom.ac_if @@ -2620,7 +2630,6 @@ } #endif /* PC98 */ -#if NCARD > 0 /* * Probe and initialization for Fujitsu MBH10302 PCMCIA Ethernet interface. * Note that this is for 10302 only; MBH10304 is handled by fe_probe_tdk(). @@ -2743,7 +2752,6 @@ */ return 16; } -#endif /* NCARD > 0 */ /* * Install interface into kernel networking data structures @@ -4333,3 +4341,209 @@ (void)ifp; (void)ifmr; } + +/* + * PC-Card (PCMCIA) specific code by iwasaki@FreeBSD.org + * -- kludge version -- + */ +#if 0 +#include "fe.h" +#include "opt_fe.h" +#endif + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +static void +fe_pccard_intr(void *arg) +{ + struct fe_softc *sc = (struct fe_softc *) arg; + + feintr(sc->sc_unit); +} + +static void +fe_deactivate(device_t dev) +{ + struct fe_softc *sc = &fe_softc[device_get_unit(dev)]; + + if (sc->sc_ih) { + bus_teardown_intr(dev, sc->irq_res, sc->sc_ih); + sc->sc_ih = NULL; + } + + if (sc->port_res) { + bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid, + sc->port_res); + sc->port_res = NULL; + } + + if (sc->irq_res) { + bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, + sc->irq_res); + sc->irq_res = NULL; + } + + return; +} + +static int +fe_activate(device_t dev) +{ + struct fe_softc *sc = &fe_softc[device_get_unit(dev)]; + int error; + + sc->port_rid = 0; + sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, + 0, ~0, 16, RF_ACTIVE); + if (sc->port_res == NULL) { + device_printf(dev, "Cannot allocate ioport\n"); + return(ENOMEM); + } + + sc->irq_rid = 0; + sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, + 0, ~0, 1, RF_ACTIVE); + if (sc->irq_res == NULL) { + device_printf(dev, "Cannot allocate irq\n"); + fe_deactivate(dev); + return(ENOMEM); + } + + error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, + fe_pccard_intr, sc, &sc->sc_ih); + if (error != 0) { + fe_deactivate(dev); + return(error); + } + + return(0); +} + +static int +fe_pccard_probe(device_t dev) +{ + struct fe_softc *sc = &fe_softc[device_get_unit(dev)]; + struct isa_device *isa_dev = device_get_ivars(dev); + int error; + + /* validate unit number. */ + if (device_get_unit(dev) >= NFE) { + return(ENODEV); + } + + /* Prepare for the device probe process. */ + sc->sc_unit = device_get_unit(dev); + + error = fe_activate(dev); + if (error) { + return(error); + } + + sc->iobase = rman_get_start(sc->port_res); + + /* + * When this function is called, the dev_desc::misc holds a + * six-byte value set by the pccard daemon. If the + * corresponding entry in /etc/pccard.conf has an "ether" + * keyword, the value is the Ethernet MAC address extracted + * from CIS area of the card. If the entry has no "ether" + * keyword, the daemon fills the field with binary zero, + * instead. We passes the value (either MAC address or zero) + * to model-specific sub-probe routines through sc->sc_enaddr + * (it actually is sc->sc_arpcom.ar_enaddr, BTW) so that the + * sub-probe routies can use that info. + */ + pccard_get_ether(dev, sc->sc_enaddr); + + isa_dev = device_get_ivars(dev); + isa_dev->id_irq = rman_get_start(sc->irq_res); + + /* Probe for supported cards. */ + if (fe_probe_mbh(isa_dev, sc) == 0 && + fe_probe_tdk(isa_dev, sc) == 0) { + fe_deactivate(dev); + return(ENXIO); + } + + fe_deactivate(dev); + return(0); +} + +static int +fe_pccard_attach(device_t dev) +{ + struct fe_softc *sc = &fe_softc[device_get_unit(dev)]; + struct isa_device *isa_dev = device_get_ivars(dev); + int error; + + /* We've got a supported card. Attach it, then. */ + error = fe_activate(dev); + if (error) { + return(error); + } + + fe_stop(sc); + + if (fe_attach(isa_dev) == 0) { + fe_deactivate(dev); + return(ENXIO); + } + + return(0); +} + +static int +fe_pccard_detach(device_t dev) +{ + struct fe_softc *sc = &fe_softc[device_get_unit(dev)]; + + fe_stop(sc); + if_detach(&sc->arpcom.ac_if); + fe_deactivate(dev); + + return(0); +} + +static device_method_t fe_pccard_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, fe_pccard_probe), + DEVMETHOD(device_attach, fe_pccard_attach), + DEVMETHOD(device_detach, fe_pccard_detach), + + { 0, 0 } +}; + +static driver_t fe_pccard_driver = { + "fe", + fe_pccard_methods, + sizeof(struct fe_softc), +}; + +static devclass_t fe_devclass; + +DRIVER_MODULE(fe, pccard, fe_pccard_driver, fe_devclass, 0, 0); +