when nfe_attach() fails, free all resources including
interrupt map, interrupt handler and dma maps. Also prevent call to bus_dmamap_destroy() when bus_dmamap_create() failed. The nfe_free_* routines assume, the map pointers are NULL but they are actually undefined. Make the assumption true by making them NULL in the error path of bus_dmamap_create(). All together, this fixes crashes when nfe_attach() fails. ok martin@
This commit is contained in:
parent
87b8a8844f
commit
945fa6c58f
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: if_nfe.c,v 1.41 2009/03/01 08:29:25 cegger Exp $ */
|
/* $NetBSD: if_nfe.c,v 1.42 2009/03/01 13:34:10 cegger Exp $ */
|
||||||
/* $OpenBSD: if_nfe.c,v 1.77 2008/02/05 16:52:50 brad Exp $ */
|
/* $OpenBSD: if_nfe.c,v 1.77 2008/02/05 16:52:50 brad Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
/* Driver for NVIDIA nForce MCP Fast Ethernet and Gigabit Ethernet */
|
/* Driver for NVIDIA nForce MCP Fast Ethernet and Gigabit Ethernet */
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: if_nfe.c,v 1.41 2009/03/01 08:29:25 cegger Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: if_nfe.c,v 1.42 2009/03/01 13:34:10 cegger Exp $");
|
||||||
|
|
||||||
#include "opt_inet.h"
|
#include "opt_inet.h"
|
||||||
#include "bpfilter.h"
|
#include "bpfilter.h"
|
||||||
|
@ -245,7 +245,7 @@ nfe_attach(device_t parent, device_t self, void *aux)
|
||||||
|
|
||||||
if (pci_intr_map(pa, &ih) != 0) {
|
if (pci_intr_map(pa, &ih) != 0) {
|
||||||
aprint_error_dev(self, "could not map interrupt\n");
|
aprint_error_dev(self, "could not map interrupt\n");
|
||||||
return;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
intrstr = pci_intr_string(pc, ih);
|
intrstr = pci_intr_string(pc, ih);
|
||||||
|
@ -255,7 +255,7 @@ nfe_attach(device_t parent, device_t self, void *aux)
|
||||||
if (intrstr != NULL)
|
if (intrstr != NULL)
|
||||||
aprint_normal(" at %s", intrstr);
|
aprint_normal(" at %s", intrstr);
|
||||||
aprint_normal("\n");
|
aprint_normal("\n");
|
||||||
return;
|
goto fail;
|
||||||
}
|
}
|
||||||
aprint_normal_dev(self, "interrupting at %s\n", intrstr);
|
aprint_normal_dev(self, "interrupting at %s\n", intrstr);
|
||||||
|
|
||||||
|
@ -345,7 +345,7 @@ nfe_attach(device_t parent, device_t self, void *aux)
|
||||||
*/
|
*/
|
||||||
if (nfe_alloc_tx_ring(sc, &sc->txq) != 0) {
|
if (nfe_alloc_tx_ring(sc, &sc->txq) != 0) {
|
||||||
aprint_error_dev(self, "could not allocate Tx ring\n");
|
aprint_error_dev(self, "could not allocate Tx ring\n");
|
||||||
return;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_init(&sc->rxq.mtx, MUTEX_DEFAULT, IPL_NET);
|
mutex_init(&sc->rxq.mtx, MUTEX_DEFAULT, IPL_NET);
|
||||||
|
@ -353,7 +353,7 @@ nfe_attach(device_t parent, device_t self, void *aux)
|
||||||
if (nfe_alloc_rx_ring(sc, &sc->rxq) != 0) {
|
if (nfe_alloc_rx_ring(sc, &sc->rxq) != 0) {
|
||||||
aprint_error_dev(self, "could not allocate Rx ring\n");
|
aprint_error_dev(self, "could not allocate Rx ring\n");
|
||||||
nfe_free_tx_ring(sc, &sc->txq);
|
nfe_free_tx_ring(sc, &sc->txq);
|
||||||
return;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
ifp = &sc->sc_ethercom.ec_if;
|
ifp = &sc->sc_ethercom.ec_if;
|
||||||
|
@ -416,6 +416,16 @@ nfe_attach(device_t parent, device_t self, void *aux)
|
||||||
aprint_error_dev(self, "couldn't establish power handler\n");
|
aprint_error_dev(self, "couldn't establish power handler\n");
|
||||||
else
|
else
|
||||||
pmf_class_network_register(self, ifp);
|
pmf_class_network_register(self, ifp);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (sc->sc_ih != NULL) {
|
||||||
|
pci_intr_disestablish(pc, sc->sc_ih);
|
||||||
|
sc->sc_ih = NULL;
|
||||||
|
}
|
||||||
|
if (memsize)
|
||||||
|
bus_space_unmap(sc->sc_memt, sc->sc_memh, memsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1362,6 +1372,7 @@ nfe_alloc_rx_ring(struct nfe_softc *sc, struct nfe_rx_ring *ring)
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
aprint_error_dev(sc->sc_dev,
|
aprint_error_dev(sc->sc_dev,
|
||||||
"could not create desc DMA map\n");
|
"could not create desc DMA map\n");
|
||||||
|
ring->map = NULL;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1430,6 +1441,7 @@ nfe_alloc_rx_ring(struct nfe_softc *sc, struct nfe_rx_ring *ring)
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
aprint_error_dev(sc->sc_dev,
|
aprint_error_dev(sc->sc_dev,
|
||||||
"could not create DMA map\n");
|
"could not create DMA map\n");
|
||||||
|
data->map = NULL;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
MCLGET(data->m, M_DONTWAIT);
|
MCLGET(data->m, M_DONTWAIT);
|
||||||
|
@ -1599,6 +1611,7 @@ nfe_jpool_alloc(struct nfe_softc *sc)
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
aprint_error_dev(sc->sc_dev,
|
aprint_error_dev(sc->sc_dev,
|
||||||
"could not create jumbo DMA map\n");
|
"could not create jumbo DMA map\n");
|
||||||
|
ring->jmap = NULL;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1690,6 +1703,7 @@ nfe_alloc_tx_ring(struct nfe_softc *sc, struct nfe_tx_ring *ring)
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
aprint_error_dev(sc->sc_dev,
|
aprint_error_dev(sc->sc_dev,
|
||||||
"could not create desc DMA map\n");
|
"could not create desc DMA map\n");
|
||||||
|
ring->map = NULL;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1726,6 +1740,7 @@ nfe_alloc_tx_ring(struct nfe_softc *sc, struct nfe_tx_ring *ring)
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
aprint_error_dev(sc->sc_dev,
|
aprint_error_dev(sc->sc_dev,
|
||||||
"could not create DMA map\n");
|
"could not create DMA map\n");
|
||||||
|
ring->data[i].map = NULL;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue