aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/dc/if_dc.c
diff options
context:
space:
mode:
authorSam Leffler <sam@FreeBSD.org>2003-11-14 19:00:32 +0000
committerSam Leffler <sam@FreeBSD.org>2003-11-14 19:00:32 +0000
commit5120abbfb44aea8edaca3311a60e73429dc71942 (patch)
tree0e5901939d8633065a9035209aa5138fe4ea6820 /sys/dev/dc/if_dc.c
parent274461c9441dd719a672a8fef48458e127b3885e (diff)
downloadsrc-5120abbfb44aea8edaca3311a60e73429dc71942.tar.gz
src-5120abbfb44aea8edaca3311a60e73429dc71942.zip
Drop the driver lock around calls to if_input to avoid a LOR when
the packets are immediately returned for sending (e.g. when bridging or packet forwarding). There are more efficient ways to do this but for now use the least intrusive approach. Reviewed by: imp, rwatson
Notes
Notes: svn path=/head/; revision=122689
Diffstat (limited to 'sys/dev/dc/if_dc.c')
-rw-r--r--sys/dev/dc/if_dc.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c
index dc1c1b3ec88b..45ec33fc10de 100644
--- a/sys/dev/dc/if_dc.c
+++ b/sys/dev/dc/if_dc.c
@@ -2723,6 +2723,8 @@ dc_rxeof(struct dc_softc *sc)
int i, total_len = 0;
u_int32_t rxstat;
+ DC_LOCK_ASSERT(sc);
+
ifp = &sc->arpcom.ac_if;
i = sc->dc_cdata.dc_rx_prod;
@@ -2816,7 +2818,9 @@ dc_rxeof(struct dc_softc *sc)
}
ifp->if_ipackets++;
+ DC_UNLOCK(sc);
(*ifp->if_input)(ifp, m);
+ DC_LOCK(sc);
}
sc->dc_cdata.dc_rx_prod = i;
@@ -3069,6 +3073,7 @@ dc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
return;
}
+ DC_LOCK(sc);
sc->rxcycles = count;
dc_rxeof(sc);
dc_txeof(sc);
@@ -3082,8 +3087,10 @@ dc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
status &= (DC_ISR_RX_WATDOGTIMEO | DC_ISR_RX_NOBUF |
DC_ISR_TX_NOBUF | DC_ISR_TX_IDLE | DC_ISR_TX_UNDERRUN |
DC_ISR_BUS_ERR);
- if (!status)
+ if (!status) {
+ DC_UNLOCK(sc);
return;
+ }
/* ack what we have */
CSR_WRITE_4(sc, DC_ISR, status);
@@ -3107,6 +3114,7 @@ dc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
dc_init(sc);
}
}
+ DC_UNLOCK(sc);
}
#endif /* DEVICE_POLLING */