- convert to critical sections
authorJoerg Sonnenberger <joerg@dragonflybsd.org>
Mon, 13 Jun 2005 22:55:15 +0000 (22:55 +0000)
committerJoerg Sonnenberger <joerg@dragonflybsd.org>
Mon, 13 Jun 2005 22:55:15 +0000 (22:55 +0000)
- rewrite error handling in attach
- hook up interrupt last

sys/dev/netif/lnc/if_lnc.c
sys/dev/netif/lnc/if_lnc_isa.c
sys/dev/netif/lnc/if_lnc_pci.c
sys/dev/netif/lnc/if_lncvar.h

index c51b968..4c1e12c 100644 (file)
@@ -28,7 +28,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/lnc/if_lnc.c,v 1.89 2001/07/04 13:00:19 nyan Exp $
- * $DragonFly: src/sys/dev/netif/lnc/Attic/if_lnc.c,v 1.20 2005/06/11 04:26:53 hsu Exp $
+ * $DragonFly: src/sys/dev/netif/lnc/Attic/if_lnc.c,v 1.21 2005/06/13 22:55:15 joerg Exp $
  */
 
 /*
@@ -71,6 +71,7 @@
 #include <sys/socket.h>
 #include <sys/sockio.h>
 #include <sys/syslog.h>
+#include <sys/thread2.h>
 
 #include <machine/bus.h>
 #include <machine/resource.h>
@@ -211,31 +212,6 @@ ether_crc(const u_char *ether_addr)
 #undef POLYNOMIAL
 }
 
-void
-lnc_release_resources(device_t dev)
-{
-       lnc_softc_t *sc = device_get_softc(dev);
-
-       if (sc->irqres) {
-               bus_teardown_intr(dev, sc->irqres, sc->intrhand);
-               bus_release_resource(dev, SYS_RES_IRQ, sc->irqrid, sc->irqres);
-       }
-
-       if (sc->portres)
-               bus_release_resource(dev, SYS_RES_IOPORT,
-                                    sc->portrid, sc->portres);
-       if (sc->drqres)
-               bus_release_resource(dev, SYS_RES_DRQ, sc->drqrid, sc->drqres);
-
-       if (sc->dmat) {
-               if (sc->dmamap) {
-                       bus_dmamap_unload(sc->dmat, sc->dmamap);
-                       bus_dmamem_free(sc->dmat, sc->recv_ring, sc->dmamap);
-               }
-               bus_dma_tag_destroy(sc->dmat);
-       }
-}
-
 /*
  * Set up the logical address filter for multicast packets
  */
@@ -913,19 +889,20 @@ lnc_init(xsc)
        void *xsc;
 {
        struct lnc_softc *sc = xsc;
-       int s, i;
+       int i;
        char *lnc_mem;
 
+       crit_enter();
+
        /* Check that interface has valid address */
 
        if (TAILQ_EMPTY(&sc->arpcom.ac_if.if_addrhead)) { /* XXX unlikely */
-printf("XXX no address?\n");
+               printf("XXX no address?\n");
+               crit_exit();
                return;
        }
 
        /* Shut down interface */
-
-       s = splimp();
        lnc_stop(sc);
        sc->arpcom.ac_if.if_flags |= IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; /* XXX??? */
 
@@ -978,7 +955,7 @@ printf("XXX no address?\n");
                for (i = 0; i < NDESC(sc->nrdre); i++) {
                        if (alloc_mbuf_cluster(sc, sc->recv_ring+i)) {
                                log(LOG_ERR, "Initialisation failed -- no mbufs\n");
-                               splx(s);
+                               crit_exit();
                                return;
                        }
                }
@@ -1087,7 +1064,7 @@ printf("Enabling lnc interrupts\n");
                log(LOG_ERR, "%s: Initialisation failed\n", 
                    sc->arpcom.ac_if.if_xname);
 
-       splx(s);
+       crit_exit();
 }
 
 /*
@@ -1384,9 +1361,9 @@ lnc_ioctl(struct ifnet * ifp, u_long command, caddr_t data, struct ucred *cr)
 {
 
        struct lnc_softc *sc = ifp->if_softc;
-       int s, error = 0;
+       int error = 0;
 
-       s = splimp();
+       crit_enter();
 
        switch (command) {
        case SIOCSIFFLAGS:
@@ -1442,7 +1419,9 @@ lnc_ioctl(struct ifnet * ifp, u_long command, caddr_t data, struct ucred *cr)
                 error = ether_ioctl(ifp, command, data);
                 break;
        }
-       (void) splx(s);
+
+       crit_exit();
+
        return error;
 }
 
index 8b67f78..bf72a01 100644 (file)
@@ -28,7 +28,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/lnc/if_lnc_isa.c,v 1.12 2001/07/04 13:00:19 nyan Exp $
- * $DragonFly: src/sys/dev/netif/lnc/if_lnc_isa.c,v 1.4 2005/05/24 20:59:01 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/lnc/if_lnc_isa.c,v 1.5 2005/06/13 22:55:15 joerg Exp $
  */
 
 #include <sys/param.h>
@@ -41,6 +41,7 @@
 #include <machine/bus.h>
 #include <machine/resource.h>
 #include <sys/rman.h>
+#include <sys/thread2.h>
 
 #include <net/ethernet.h>
 #include <net/if.h>
@@ -51,6 +52,8 @@
 #include <dev/netif/lnc/if_lncvar.h>
 #include <dev/netif/lnc/if_lncreg.h>
 
+static int     lnc_isa_detach(device_t);
+
 static struct isa_pnp_id lnc_pnp_ids[] = {
        {0,     NULL}
 };
@@ -66,7 +69,6 @@ lnc_legacy_probe(device_t dev)
 
        if (! sc->portres) {
                device_printf(dev, "Failed to allocate I/O ports\n");
-               lnc_release_resources(dev);
                return (ENXIO);
        }
 
@@ -88,7 +90,7 @@ lnc_legacy_probe(device_t dev)
        if ((sc->nic.ic = lance_probe(sc))) {
                device_set_desc(dev, "BICC Isolan");
                sc->nic.ident = BICC;
-               lnc_release_resources(dev);
+               lnc_isa_detach(dev);
                return (0);
        } else {
            /* It's not a BICC so try the standard NE2100 ports */
@@ -97,10 +99,10 @@ lnc_legacy_probe(device_t dev)
            if ((sc->nic.ic = lance_probe(sc))) {
                sc->nic.ident = NE2100;
                device_set_desc(dev, "NE2100");
-               lnc_release_resources(dev);
+               lnc_isa_detach(dev);
                return (0);
            } else {
-               lnc_release_resources(dev);
+               lnc_isa_detach(dev);
                return (ENXIO);
            }
        }
@@ -134,29 +136,33 @@ static int
 lnc_isa_attach(device_t dev)
 {
        lnc_softc_t *sc = device_get_softc(dev);
-       int err = 0;
+       int error = 0;
        bus_size_t lnc_mem_size;
 
-       device_printf(dev, "Attaching %s\n", device_get_desc(dev));
+       /*
+        * The probe routines can allocate resources and to make our
+        * live easier, bzero the softc now.
+        */
+       bzero(sc, sizeof(*sc));
 
        sc->portrid = 0;
        sc->portres = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->portrid,
            RF_ACTIVE);
 
-       if (! sc->portres) {
+       if (!sc->portres) {
                device_printf(dev, "Failed to allocate I/O ports\n");
-               lnc_release_resources(dev);
-               return (ENXIO);
+               error = ENXIO;
+               goto fail;
        }
 
        sc->drqrid = 0;
        sc->drqres = bus_alloc_resource_any(dev, SYS_RES_DRQ, &sc->drqrid,
            RF_ACTIVE);
 
-       if (! sc->drqres) {
+       if (!sc->drqres) {
                device_printf(dev, "Failed to allocate DMA channel\n");
-               lnc_release_resources(dev);
-               return (ENXIO);
+               error = ENXIO;
+               goto fail;
        }
 
        if (isa_get_irq(dev) == -1)
@@ -168,17 +174,8 @@ lnc_isa_attach(device_t dev)
 
        if (! sc->irqres) {
                device_printf(dev, "Failed to allocate irq\n");
-               lnc_release_resources(dev);
-               return (ENXIO);
-       }
-
-       err = bus_setup_intr(dev, sc->irqres, INTR_TYPE_NET, lncintr,
-                            sc, &sc->intrhand, NULL);
-
-       if (err) {
-               device_printf(dev, "Failed to setup irq handler\n");
-               lnc_release_resources(dev);
-               return (err);
+               error = ENXIO;
+               goto fail;
        }
 
        /* XXX temp setting for nic */
@@ -203,40 +200,38 @@ lnc_isa_attach(device_t dev)
        lnc_mem_size += (NDESC(sc->nrdre) * RECVBUFSIZE) +
                        (NDESC(sc->ntdre) * TRANSBUFSIZE);
 
-       err = bus_dma_tag_create(NULL,                  /* parent */
-                                4,                     /* alignement */
-                                0,                     /* boundary */
-                                BUS_SPACE_MAXADDR_24BIT,       /* lowaddr */
-                                BUS_SPACE_MAXADDR,     /* highaddr */
-                                NULL, NULL,            /* filter, filterarg */
-                                lnc_mem_size,          /* segsize */
-                                1,                     /* nsegments */
-                                BUS_SPACE_MAXSIZE_32BIT,       /* maxsegsize */
-                                0,                     /* flags */
-                                &sc->dmat);
-
-       if (err) {
+       error = bus_dma_tag_create(NULL,                /* parent */
+                                  4,                   /* alignement */
+                                  0,                   /* boundary */
+                                  BUS_SPACE_MAXADDR_24BIT,     /* lowaddr */
+                                  BUS_SPACE_MAXADDR,   /* highaddr */
+                                  NULL, NULL,          /* filter, filterarg */
+                                  lnc_mem_size,        /* segsize */
+                                  1,                   /* nsegments */
+                                  BUS_SPACE_MAXSIZE_32BIT,     /* maxsegsize */
+                                  BUS_DMA_ALLOCNOW,    /* flags */
+                                  &sc->dmat);
+
+       if (error) {
                device_printf(dev, "Can't create DMA tag\n");
-               lnc_release_resources(dev);
-               return (ENOMEM);
+               goto fail;
        }
 
-       err = bus_dmamem_alloc(sc->dmat, (void **)&sc->recv_ring,
-                              BUS_DMA_NOWAIT, &sc->dmamap);
+       error = bus_dmamem_alloc(sc->dmat, (void **)&sc->recv_ring,
+                              BUS_DMA_WAITOK, &sc->dmamap);
 
-       if (err) {
+       if (error) {
                device_printf(dev, "Couldn't allocate memory\n");
-               lnc_release_resources(dev);
-               return (ENOMEM);
+               goto fail;
        }
 
-       err = bus_dmamap_load(sc->dmat, sc->dmamap, sc->recv_ring, lnc_mem_size,
-                       lnc_alloc_callback, sc->recv_ring, BUS_DMA_NOWAIT);
+       error = bus_dmamap_load(sc->dmat, sc->dmamap, sc->recv_ring,
+                               lnc_mem_size, lnc_alloc_callback,
+                               sc->recv_ring, 0);
 
-       if (err) {
+       if (error) {
                device_printf(dev, "Couldn't load DMA map\n");
-               lnc_release_resources(dev);
-               return (ENOMEM);
+               goto fail;
        }
 
        isa_dmacascade(rman_get_start(sc->drqres));
@@ -244,23 +239,55 @@ lnc_isa_attach(device_t dev)
        /* Call generic attach code */
        if (! lnc_attach_common(dev)) {
                device_printf(dev, "Generic attach code failed\n");
-               lnc_release_resources(dev);
-               return (ENXIO);
+               error = ENXIO;
+               goto fail;
+       }
+
+       error = bus_setup_intr(dev, sc->irqres, INTR_TYPE_NET, lncintr,
+                              sc, &sc->intrhand, NULL);
+       if (error) {
+               device_printf(dev, "Failed to setup irq handler\n");
+               ether_ifdetach(&sc->arpcom.ac_if);
+               goto fail;
        }
+
        return (0);
+
+fail:
+       lnc_isa_detach(dev);
+       return(error);
 }
 
 static int
 lnc_isa_detach(device_t dev)
 {
        lnc_softc_t *sc = device_get_softc(dev);
-       int s = splimp();
 
-       ether_ifdetach(&sc->arpcom.ac_if);
-       splx(s);
+       crit_enter();
 
-       lnc_stop(sc);
-       lnc_release_resources(dev);
+       if (device_is_attached(dev)) {
+               ether_ifdetach(&sc->arpcom.ac_if);
+               lnc_stop(sc);
+       }
+
+       if (sc->intrhand)
+               bus_teardown_intr(dev, sc->irqres, sc->intrhand);
+
+       crit_exit();
+
+       if (sc->irqres)
+               bus_release_resource(dev, SYS_RES_IRQ, sc->irqrid, sc->irqres);
+       if (sc->portres)
+               bus_release_resource(dev, SYS_RES_IOPORT,
+                                    sc->portrid, sc->portres);
+       if (sc->drqres)
+               bus_release_resource(dev, SYS_RES_DRQ, sc->drqrid, sc->drqres);
+       if (sc->dmamap) {
+               bus_dmamap_unload(sc->dmat, sc->dmamap);
+               bus_dmamem_free(sc->dmat, sc->recv_ring, sc->dmamap);
+       }
+       if (sc->dmat)
+               bus_dma_tag_destroy(sc->dmat);
 
        return (0);
 }
index 4858aec..a2f0fb5 100644 (file)
@@ -28,7 +28,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/lnc/if_lnc_pci.c,v 1.25 2001/07/04 13:00:19 nyan Exp $
- * $DragonFly: src/sys/dev/netif/lnc/if_lnc_pci.c,v 1.5 2005/05/24 20:59:01 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/lnc/if_lnc_pci.c,v 1.6 2005/06/13 22:55:15 joerg Exp $
  */
 
 #include <sys/param.h>
@@ -36,6 +36,7 @@
 #include <sys/socket.h>
 #include <sys/malloc.h>
 #include <sys/kernel.h>
+#include <sys/thread2.h>
 
 #include <machine/bus.h>
 #include <machine/resource.h>
@@ -58,6 +59,8 @@
 
 #define LNC_PROBE_PRIORITY -1
 
+static int     lnc_pci_detach(device_t);
+
 static int
 lnc_pci_probe(device_t dev)
 {
@@ -93,11 +96,9 @@ lnc_pci_attach(device_t dev)
        lnc_softc_t *sc = device_get_softc(dev);
        unsigned command;
        int rid = 0;
-       int err = 0;
+       int error = 0;
        bus_size_t lnc_mem_size;
 
-       device_printf(dev, "Attaching %s\n", device_get_desc(dev));
-
        command = pci_read_config(dev, PCIR_COMMAND, 4);
        command |= PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN;
        pci_write_config(dev, PCIR_COMMAND, command, 4);
@@ -106,20 +107,21 @@ lnc_pci_attach(device_t dev)
        sc->portres = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
            RF_ACTIVE);
 
-       if (! sc->portres)
+       if (! sc->portres) {
                device_printf(dev, "Cannot allocate I/O ports\n");
+               error = ENXIO;
+               goto fail;
+       }
 
        rid = 0;
        sc->irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
            RF_ACTIVE | RF_SHAREABLE);
 
-       if (! sc->irqres)
+       if (! sc->irqres) {
                device_printf(dev, "Cannot allocate irq\n");
-
-       err = bus_setup_intr(dev, sc->irqres, INTR_TYPE_NET, lncintr,
-                            sc, &sc->intrhand, NULL);
-       if (err)
-               device_printf(dev, "Cannot setup irq handler\n");
+               error = ENXIO;
+               goto fail;
+       }
 
        sc->lnc_btag = rman_get_bustag(sc->portres);
        sc->lnc_bhandle = rman_get_bushandle(sc->portres);
@@ -145,61 +147,90 @@ lnc_pci_attach(device_t dev)
        lnc_mem_size += (NDESC(sc->nrdre) * RECVBUFSIZE) +
                        (NDESC(sc->ntdre) * TRANSBUFSIZE);
 
-       err = bus_dma_tag_create(NULL,                  /* parent */
-                                1,                     /* alignement */
-                                0,                     /* boundary */
-                                BUS_SPACE_MAXADDR_24BIT,       /* lowaddr */
-                                BUS_SPACE_MAXADDR,     /* highaddr */
-                                NULL, NULL,            /* filter, filterarg */
-                                lnc_mem_size,          /* segsize */
-                                1,                     /* nsegments */
-                                BUS_SPACE_MAXSIZE_32BIT,       /* maxsegsize */
-                                0,                     /* flags */
-                                &sc->dmat);
-
-       if (err) {
+       error = bus_dma_tag_create(NULL,                /* parent */
+                                  1,                   /* alignement */
+                                  0,                   /* boundary */
+                                  BUS_SPACE_MAXADDR_24BIT,     /* lowaddr */
+                                  BUS_SPACE_MAXADDR,   /* highaddr */
+                                  NULL, NULL,          /* filter, filterarg */
+                                  lnc_mem_size,        /* segsize */
+                                  1,                   /* nsegments */
+                                  BUS_SPACE_MAXSIZE_32BIT,     /* maxsegsize */
+                                  BUS_DMA_ALLOCNOW,    /* flags */
+                                  &sc->dmat);
+
+       if (error) {
                device_printf(dev, "Can't create DMA tag\n");
-               /* XXX need to free currently allocated resources here */
-               return (ENOMEM);
+               goto fail;
        }
 
-       err = bus_dmamem_alloc(sc->dmat, (void **)&sc->recv_ring,
-                              BUS_DMA_NOWAIT, &sc->dmamap);
-
-       if (err) {
+       error = bus_dmamem_alloc(sc->dmat, (void **)&sc->recv_ring,
+                              BUS_DMA_WAITOK, &sc->dmamap);
+       if (error) {
                device_printf(dev, "Couldn't allocate memory\n");
-               /* XXX need to free currently allocated resources here */
-               return (ENOMEM);
+               goto fail;
        }
 
-       bus_dmamap_load(sc->dmat, sc->dmamap, sc->recv_ring, lnc_mem_size,
-                       lnc_alloc_callback, sc->recv_ring, BUS_DMA_NOWAIT);
+       error = bus_dmamap_load(sc->dmat, sc->dmamap, sc->recv_ring,
+                               lnc_mem_size, lnc_alloc_callback,
+                               sc->recv_ring, 0);
+       if (error) {
+               device_printf(dev, "Couldn't map receive ring\n");
+               goto fail;
+       }
 
        /* Call generic attach code */
        if (! lnc_attach_common(dev)) {
                device_printf(dev, "Generic attach code failed\n");
+               error = ENXIO;
+               goto fail;
+       }
+
+       error = bus_setup_intr(dev, sc->irqres, INTR_TYPE_NET, lncintr,
+                            sc, &sc->intrhand, NULL);
+       if (error) {
+               device_printf(dev, "Cannot setup irq handler\n");
+               ether_ifdetach(&sc->arpcom.ac_if);
+               goto fail;
        }
+
        return (0);
+
+fail:
+       lnc_pci_detach(dev);
+       return(error);
 }
 
 static int
 lnc_pci_detach(device_t dev)
 {
        lnc_softc_t *sc = device_get_softc(dev);
-       int s = splimp();
 
-       ether_ifdetach(&sc->arpcom.ac_if);
+       crit_enter();
 
-       lnc_stop(sc);
-       bus_teardown_intr(dev, sc->irqres, sc->intrhand);
-       bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irqres);
-       bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS, sc->portres);
+       if (device_is_attached(dev)) {
+               ether_ifdetach(&sc->arpcom.ac_if);
+               lnc_stop(sc);
+       }
+
+       if (sc->intrhand)
+               bus_teardown_intr(dev, sc->irqres, sc->intrhand);
+
+       crit_exit();
 
-       bus_dmamap_unload(sc->dmat, sc->dmamap);
-       bus_dmamem_free(sc->dmat, sc->recv_ring, sc->dmamap);
-       bus_dma_tag_destroy(sc->dmat);
+       if (sc->irqres)
+               bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irqres);
+       if (sc->portres)
+               bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS,
+                                    sc->portres);
+
+       if (sc->dmamap) {
+               bus_dmamap_unload(sc->dmat, sc->dmamap);
+               bus_dmamem_free(sc->dmat, sc->recv_ring, sc->dmamap);
+       }
+       if (sc->dmat)
+               bus_dma_tag_destroy(sc->dmat);
 
-       splx(s);
        return (0);
 }
 
index e7e6a0c..8f9d239 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/lnc/if_lncvar.h,v 1.23 2001/07/04 13:00:20 nyan Exp $
- * $DragonFly: src/sys/dev/netif/lnc/Attic/if_lncvar.h,v 1.1 2003/12/07 19:23:39 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/lnc/Attic/if_lncvar.h,v 1.2 2005/06/13 22:55:15 joerg Exp $
  */
 
 /*
@@ -254,7 +254,6 @@ struct host_ring_entry {
 
 /* Functional declarations */
 extern int lance_probe(struct lnc_softc *);
-extern void lnc_release_resources(device_t);
 extern int lnc_attach_common(device_t);
 extern void lnc_stop(struct lnc_softc *);