summaryrefslogtreecommitdiffstats
path: root/sys/pci/if_ti.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/pci/if_ti.c')
-rw-r--r--sys/pci/if_ti.c82
1 files changed, 32 insertions, 50 deletions
diff --git a/sys/pci/if_ti.c b/sys/pci/if_ti.c
index be81f61..4513a18 100644
--- a/sys/pci/if_ti.c
+++ b/sys/pci/if_ti.c
@@ -2115,7 +2115,6 @@ ti_attach(dev)
sc = device_get_softc(dev);
unit = device_get_unit(dev);
- bzero(sc, sizeof(struct ti_softc));
mtx_init(&sc->ti_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
@@ -2161,25 +2160,10 @@ ti_attach(dev)
goto fail;
}
- error = bus_setup_intr(dev, sc->ti_irq, INTR_TYPE_NET,
- ti_intr, sc, &sc->ti_intrhand);
-
- if (error) {
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
- printf("ti%d: couldn't set up irq\n", unit);
- goto fail;
- }
-
sc->ti_unit = unit;
if (ti_chipinit(sc)) {
printf("ti%d: chip initialization failed\n", sc->ti_unit);
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
error = ENXIO;
goto fail;
}
@@ -2190,10 +2174,6 @@ ti_attach(dev)
/* Init again -- zeroing memory may have clobbered some registers. */
if (ti_chipinit(sc)) {
printf("ti%d: chip initialization failed\n", sc->ti_unit);
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
error = ENXIO;
goto fail;
}
@@ -2208,10 +2188,6 @@ ti_attach(dev)
if (ti_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr,
TI_EE_MAC_OFFSET + 2, ETHER_ADDR_LEN)) {
printf("ti%d: failed to read station address\n", unit);
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
error = ENXIO;
goto fail;
}
@@ -2227,12 +2203,8 @@ ti_attach(dev)
M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
if (sc->ti_rdata == NULL) {
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
- error = ENXIO;
printf("ti%d: no memory for list buffers!\n", sc->ti_unit);
+ error = ENXIO;
goto fail;
}
@@ -2242,23 +2214,12 @@ ti_attach(dev)
#ifdef TI_PRIVATE_JUMBOS
if (ti_alloc_jumbo_mem(sc)) {
printf("ti%d: jumbo buffer allocation failed\n", sc->ti_unit);
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
- contigfree(sc->ti_rdata, sizeof(struct ti_ring_data),
- M_DEVBUF);
error = ENXIO;
goto fail;
}
#else
if (!jumbo_vm_init()) {
printf("ti%d: VM initialization failed!\n", sc->ti_unit);
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
- free(sc->ti_rdata, M_DEVBUF);
error = ENOMEM;
goto fail;
}
@@ -2359,10 +2320,19 @@ ti_attach(dev)
* Call MI attach routine.
*/
ether_ifattach(ifp, sc->arpcom.ac_enaddr);
- return(0);
+
+ error = bus_setup_intr(dev, sc->ti_irq, INTR_TYPE_NET,
+ ti_intr, sc, &sc->ti_intrhand);
+
+ if (error) {
+ printf("ti%d: couldn't set up irq\n", unit);
+ goto fail;
+ }
fail:
- mtx_destroy(&sc->ti_mtx);
+ if (sc && error)
+ ti_detach(dev);
+
return(error);
}
@@ -2405,21 +2375,33 @@ ti_detach(dev)
return EBUSY;
sc = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc->ti_mtx), "ti mutex not initialized");
TI_LOCK(sc);
ifp = &sc->arpcom.ac_if;
- ether_ifdetach(ifp);
- ti_stop(sc);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev))
+ ti_stop(sc);
+ ether_ifdetach(ifp);
+ bus_generic_detach(dev);
+ ifmedia_removeall(&sc->ifmedia);
+ }
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY, TI_PCI_LOMEM, sc->ti_res);
+ if (sc->ti_intrhand)
+ bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
+ if (sc->ti_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
+ if (sc->ti_res) {
+ bus_release_resource(dev, SYS_RES_MEMORY, TI_PCI_LOMEM,
+ sc->ti_res);
+ }
#ifdef TI_PRIVATE_JUMBOS
- contigfree(sc->ti_cdata.ti_jumbo_buf, TI_JMEM, M_DEVBUF);
+ if (sc->ti_cdata.ti_jumbo_buf)
+ contigfree(sc->ti_cdata.ti_jumbo_buf, TI_JMEM, M_DEVBUF);
#endif
- contigfree(sc->ti_rdata, sizeof(struct ti_ring_data), M_DEVBUF);
- ifmedia_removeall(&sc->ifmedia);
+ if (sc->ti_rdata)
+ contigfree(sc->ti_rdata, sizeof(struct ti_ring_data), M_DEVBUF);
TI_UNLOCK(sc);
mtx_destroy(&sc->ti_mtx);
OpenPOWER on IntegriCloud