Attached is a diff that fixes a "could sleep" problem where
ether_ifattach() does a malloc and dc(4) is holding a lock in its softc.  
It uses a cleaner exit strategy with only one call to DC_UNLOCK and no
multiple return statements as well as fixing one place where "error"
wasn't set.  If people are ok with it, I'll sweep other drivers that have
a similar problem.

-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     7 Jan 2003 00:36:30 -0000
@@ -2162,6 +2162,7 @@
                mac = pci_get_ether(dev);
                if (!mac) {
                        device_printf(dev, "No station address in CIS!\n");
+                       error = ENXIO;
                        goto fail;
                }
                bcopy(mac, eaddr, ETHER_ADDR_LEN);
@@ -2266,11 +2267,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 +2300,16 @@
        }
 #endif
 
-       DC_UNLOCK(sc);
-       return(0);
-
 fail:
        DC_UNLOCK(sc);
 fail_nolock:
-       mtx_destroy(&sc->dc_mtx);
-       return(error);
+       /* If no errors, call the MI attach routine. */
+       if (error == 0)
+               ether_ifattach(ifp, eaddr);
+       else
+               mtx_destroy(&sc->dc_mtx);
+
+       return (error);
 }
 
 static int

Reply via email to