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