Here is an updated patch for dc.  Can you try it?
* Remove bogus locking
* Move intr setup, ether_ifattach to end
* add proper resource freeing to a case that missed it (!mac)
* update resource freeing for error cases after intr move

-Nate
Index: if_dc.c
===================================================================
RCS file: /home/ncvs/src/sys/pci/if_dc.c,v
retrieving revision 1.85
diff -u -r1.85 if_dc.c
--- if_dc.c     27 Nov 2002 07:04:10 -0000      1.85
+++ if_dc.c     8 Jan 2003 18:49:22 -0000
@@ -1927,13 +1927,13 @@
        if (!(command & PCIM_CMD_PORTEN)) {
                printf("dc%d: failed to enable I/O ports!\n", unit);
                error = ENXIO;
-               goto fail_nolock;
+               goto fail;
        }
 #else
        if (!(command & PCIM_CMD_MEMEN)) {
                printf("dc%d: failed to enable memory mapping!\n", unit);
                error = ENXIO;
-               goto fail_nolock;
+               goto fail;
        }
 #endif
 
@@ -1944,36 +1944,12 @@
        if (sc->dc_res == NULL) {
                printf("dc%d: couldn't map ports/memory\n", unit);
                error = ENXIO;
-               goto fail_nolock;
+               goto fail;
        }
 
        sc->dc_btag = rman_get_bustag(sc->dc_res);
        sc->dc_bhandle = rman_get_bushandle(sc->dc_res);
 
-       /* Allocate interrupt */
-       rid = 0;
-       sc->dc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
-           RF_SHAREABLE | RF_ACTIVE);
-
-       if (sc->dc_irq == NULL) {
-               printf("dc%d: couldn't map interrupt\n", unit);
-               bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
-               error = ENXIO;
-               goto fail_nolock;
-       }
-
-       error = bus_setup_intr(dev, sc->dc_irq, INTR_TYPE_NET | 
-           (IS_MPSAFE ? INTR_MPSAFE : 0),
-           dc_intr, sc, &sc->dc_intrhand);
-
-       if (error) {
-               bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
-               bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
-               printf("dc%d: couldn't set up irq\n", unit);
-               goto fail_nolock;
-       }
-       DC_LOCK(sc);
-
        /* Need this info to decide on a chip type. */
        sc->dc_info = dc_devtype(dev);
        revision = pci_read_config(dev, DC_PCI_CFRV, 4) & 0x000000FF;
@@ -2162,6 +2138,8 @@
                mac = pci_get_ether(dev);
                if (!mac) {
                        device_printf(dev, "No station address in CIS!\n");
+                       bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
+                       error = ENXIO;
                        goto fail;
                }
                bcopy(mac, eaddr, ETHER_ADDR_LEN);
@@ -2184,8 +2162,6 @@
 
        if (sc->dc_ldata == NULL) {
                printf("dc%d: no memory for list buffers!\n", unit);
-               bus_teardown_intr(dev, sc->dc_irq, sc->dc_intrhand);
-               bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
                bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
                error = ENXIO;
                goto fail;
@@ -2245,8 +2221,6 @@
 
        if (error) {
                printf("dc%d: MII without any PHY!\n", sc->dc_unit);
-               bus_teardown_intr(dev, sc->dc_irq, sc->dc_intrhand);
-               bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
                bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
                error = ENXIO;
                goto fail;
@@ -2266,11 +2240,6 @@
        }
 
        /*
-        * Call MI attach routine.
-        */
-       ether_ifattach(ifp, eaddr);
-
-       /*
         * Tell the upper layer(s) we support long frames.
         */
        ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
@@ -2304,14 +2273,37 @@
        }
 #endif
 
-       DC_UNLOCK(sc);
-       return(0);
+       /*
+        * Call MI attach routine.
+        */
+       ether_ifattach(ifp, eaddr);
+
+       /* Allocate interrupt */
+       rid = 0;
+       sc->dc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+           RF_SHAREABLE | RF_ACTIVE);
+
+       if (sc->dc_irq == NULL) {
+               printf("dc%d: couldn't map interrupt\n", unit);
+               bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
+               error = ENXIO;
+               goto fail;
+       }
+
+       error = bus_setup_intr(dev, sc->dc_irq, INTR_TYPE_NET | 
+           (IS_MPSAFE ? INTR_MPSAFE : 0),
+           dc_intr, sc, &sc->dc_intrhand);
+
+       if (error) {
+               bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
+               bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
+               printf("dc%d: couldn't set up irq\n", unit);
+       }
 
 fail:
-       DC_UNLOCK(sc);
-fail_nolock:
-       mtx_destroy(&sc->dc_mtx);
-       return(error);
+       if (error != 0)
+               mtx_destroy(&sc->dc_mtx);
+       return (error);
 }
 
 static int

Reply via email to