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