diff options
author | mdodd <mdodd@FreeBSD.org> | 2002-03-29 11:22:22 +0000 |
---|---|---|
committer | mdodd <mdodd@FreeBSD.org> | 2002-03-29 11:22:22 +0000 |
commit | 84c21f1d8ff69f47f8e2bef01392d5b39cf9ce02 (patch) | |
tree | acee2dafe452f857b35aa52d9223075e812b1e18 /sys/dev/pdq/if_fpa.c | |
parent | fdbdd2f5af8ced636e98ffa82c0898512b04bfba (diff) | |
download | FreeBSD-src-84c21f1d8ff69f47f8e2bef01392d5b39cf9ce02.zip FreeBSD-src-84c21f1d8ff69f47f8e2bef01392d5b39cf9ce02.tar.gz |
- Merge the pdq driver (if_fpa and if_fea) from NetBSD.
Among other things this gets us ifmedia support.
- Update fddi_ifattach() to take an additional argument.
Diffstat (limited to 'sys/dev/pdq/if_fpa.c')
-rw-r--r-- | sys/dev/pdq/if_fpa.c | 172 |
1 files changed, 125 insertions, 47 deletions
diff --git a/sys/dev/pdq/if_fpa.c b/sys/dev/pdq/if_fpa.c index 9eb3f50..c01b8ad 100644 --- a/sys/dev/pdq/if_fpa.c +++ b/sys/dev/pdq/if_fpa.c @@ -32,22 +32,29 @@ */ #include <sys/param.h> +#include <sys/systm.h> #include <sys/kernel.h> #include <sys/socket.h> -#include <net/if.h> +#include <sys/module.h> +#include <sys/bus.h> -#include <net/ethernet.h> -#include <net/if_arp.h> -#include <dev/pdq/pdqvar.h> -#include <dev/pdq/pdqreg.h> +#include <machine/bus_memio.h> +#include <machine/bus_pio.h> #include <machine/bus.h> #include <machine/resource.h> -#include <sys/bus.h> -#include <sys/rman.h> -#include <pci/pcivar.h> -#include <pci/pcireg.h> +#include <sys/rman.h> +#include <net/if.h> +#include <net/if_arp.h> +#include <net/if_media.h> +#include <net/fddi.h> + +#include <dev/pci/pcivar.h> +#include <dev/pci/pcireg.h> + +#include <dev/pdq/pdq_freebsd.h> +#include <dev/pdq/pdqreg.h> #define DEC_VENDORID 0x1011 #define DEFPA_CHIPID 0x000F @@ -58,13 +65,26 @@ #define PCI_CBMA 0x10 /* Configuration Base Memory Address */ #define PCI_CBIO 0x14 /* Configuration Base I/O Address */ +static int pdq_pci_probe (device_t); +static int pdq_pci_attach (device_t); +static int pdq_pci_detach (device_t); +static void pdq_pci_shutdown (device_t); +static void pdq_pci_ifintr (void *); + static void pdq_pci_ifintr(void *arg) { + device_t dev; pdq_softc_t *sc; - sc = device_get_softc(arg); + dev = (device_t)arg; + sc = device_get_softc(dev); + + PDQ_LOCK(sc); (void) pdq_interrupt(sc->sc_pdq); + PDQ_UNLOCK(sc); + + return; } /* @@ -76,61 +96,112 @@ pdq_pci_probe(device_t dev) if (pci_get_vendor(dev) == DEC_VENDORID && pci_get_device(dev) == DEFPA_CHIPID) { device_set_desc(dev, "Digital DEFPA PCI FDDI Controller"); - return 0; + return (0); } - return ENXIO; + + return (ENXIO); } static int pdq_pci_attach(device_t dev) { pdq_softc_t *sc; - int data; - struct resource *memres, *irqres; - int rid; - void *ih; + struct ifnet *ifp; + u_int32_t command; + int error; - memres = NULL; - irqres = NULL; sc = device_get_softc(dev); + ifp = &sc->arpcom.ac_if; + + sc->dev = dev; - data = pci_read_config(dev, PCIR_LATTIMER, 1); - if (data < DEFPA_LATENCY) { - data = DEFPA_LATENCY; - pci_write_config(dev, PCIR_LATTIMER, data, 1); + /* + * Map control/status registers. + */ + pci_enable_busmaster(dev); + pci_enable_io(dev, SYS_RES_IOPORT); + pci_enable_io(dev, SYS_RES_MEMORY); + command = pci_read_config(dev, PCIR_COMMAND, 4); + + if (!(command & PCIM_CMD_PORTEN)) { + device_printf(dev, "Failed to enable PCI I/O ports.\n"); + error = ENXIO; + goto bad; } - rid = PCI_CBMA; - memres = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 1, RF_ACTIVE); - if (!memres) + if (!(command & PCIM_CMD_MEMEN)) { + device_printf(dev, "Failed to enable PCI memory mapping.\n"); + error = ENXIO; goto bad; + } + + command = pci_read_config(dev, PCIR_LATTIMER, 1); + if (command < DEFPA_LATENCY) { + command = DEFPA_LATENCY; + pci_write_config(dev, PCIR_LATTIMER, command, 1); + } - sc->sc_if.if_name = "fpa"; - sc->sc_if.if_unit = device_get_unit(dev); - sc->sc_membase = (pdq_bus_memaddr_t) rman_get_virtual(memres); - sc->sc_pdq = pdq_initialize(PDQ_BUS_PCI, sc->sc_membase, - sc->sc_if.if_name, sc->sc_if.if_unit, - (void *) sc, PDQ_DEFPA); - if (sc->sc_pdq == NULL) + sc->mem_rid = PCI_CBMA; + sc->mem_type = SYS_RES_MEMORY; + sc->mem = bus_alloc_resource(dev, sc->mem_type, &sc->mem_rid, + 0, ~0, 1, RF_ACTIVE); + if (!sc->mem) { + device_printf(dev, "Unable to allocate I/O space resource.\n"); + error = ENXIO; goto bad; - bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, sc->sc_ac.ac_enaddr, 6); - pdq_ifattach(sc, NULL); - rid = 0; - irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, - RF_SHAREABLE | RF_ACTIVE); - if (!irqres) + } + sc->mem_bsh = rman_get_bushandle(sc->mem); + sc->mem_bst = rman_get_bustag(sc->mem); + + sc->irq_rid = 0; + sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, + 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE); + if (!sc->irq) { + device_printf(dev, "Unable to allocate interrupt resource.\n"); + error = ENXIO; goto bad; - if (bus_setup_intr(dev, irqres, INTR_TYPE_NET, pdq_pci_ifintr, - (void *)dev, &ih)) + } + + ifp->if_name = "fpa"; + ifp->if_unit = device_get_unit(dev); + + sc->sc_pdq = pdq_initialize(sc->mem_bst, sc->mem_bsh, + ifp->if_name, ifp->if_unit, + (void *)sc, PDQ_DEFPA); + if (sc->sc_pdq == NULL) { + device_printf(dev, "Initialization failed.\n"); + error = ENXIO; goto bad; - return 0; + } + error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, + pdq_pci_ifintr, dev, &sc->irq_ih); + if (error) { + device_printf(dev, "Failed to setup interrupt handler.\n"); + error = ENXIO; + goto bad; + } + + bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, + (caddr_t) sc->arpcom.ac_enaddr, FDDI_ADDR_LEN); + pdq_ifattach(sc); + + return (0); bad: - if (memres) - bus_release_resource(dev, SYS_RES_MEMORY, PCI_CBMA, memres); - if (irqres) - bus_release_resource(dev, SYS_RES_IRQ, 0, irqres); - return ENXIO; + pdq_free(dev); + return (error); +} + +static int +pdq_pci_detach (dev) + device_t dev; +{ + pdq_softc_t *sc; + + sc = device_get_softc(dev); + pdq_ifdetach(sc); + + return (0); } static void @@ -140,19 +211,26 @@ pdq_pci_shutdown(device_t dev) sc = device_get_softc(dev); pdq_hwreset(sc->sc_pdq); + + return; } static device_method_t pdq_pci_methods[] = { /* Device interface */ DEVMETHOD(device_probe, pdq_pci_probe), DEVMETHOD(device_attach, pdq_pci_attach), + DEVMETHOD(device_detach, pdq_pci_detach), DEVMETHOD(device_shutdown, pdq_pci_shutdown), + { 0, 0 } }; + static driver_t pdq_pci_driver = { "fpa", pdq_pci_methods, sizeof(pdq_softc_t), }; -static devclass_t pdq_devclass; + DRIVER_MODULE(if_fpa, pci, pdq_pci_driver, pdq_devclass, 0, 0); +/* MODULE_DEPEND(if_fpa, pci, 1, 1, 1); */ +MODULE_DEPEND(if_fpa, fddi, 1, 1, 1); |