summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2004-04-22 07:08:39 +0000
committerwpaul <wpaul@FreeBSD.org>2004-04-22 07:08:39 +0000
commit6bc1da1c05748794ddfba4b35ad43a0752b9d9ce (patch)
treed7c8788b2df34a961795a4183df16cf79dd6cf16 /sys/compat
parentea882c9688f650396d1f4b076c564a13bb55b025 (diff)
downloadFreeBSD-src-6bc1da1c05748794ddfba4b35ad43a0752b9d9ce.zip
FreeBSD-src-6bc1da1c05748794ddfba4b35ad43a0752b9d9ce.tar.gz
Ok, _really_ fix the Intel 2100B Centrino deadlock problems this time.
(I hope.) My original instinct to make ndis_return_packet() asynchronous was correct. Making ndis_rxeof() submit packets to the stack asynchronously fixes one recursive spinlock acquisition, but it's also possible for it to happen via the ndis_txeof() path too. So: - In if_ndis.c, revert ndis_rxeof() to its old behavior (and don't bother putting ndis_rxeof_serial() back since we don't need it anymore). - In kern_ndis.c, make ndis_return_packet() submit the call to the MiniportReturnPacket() function to the "ndis swi" thread so that it always happens in another context no matter who calls it.
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/ndis/kern_ndis.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c
index 6e5d35a..51b2d17 100644
--- a/sys/compat/ndis/kern_ndis.c
+++ b/sys/compat/ndis/kern_ndis.c
@@ -99,6 +99,7 @@ struct ndisproc {
int np_state;
};
+static void ndis_return(void *);
static int ndis_create_kthreads(void);
static void ndis_destroy_kthreads(void);
static void ndis_stop_thread(int);
@@ -724,17 +725,38 @@ ndis_flush_sysctls(arg)
return(0);
}
-void
-ndis_return_packet(buf, arg)
- void *buf; /* not used */
+static void
+ndis_return(arg)
void *arg;
{
struct ndis_softc *sc;
+ __stdcall ndis_return_handler returnfunc;
ndis_handle adapter;
ndis_packet *p;
- __stdcall ndis_return_handler returnfunc;
uint8_t irql;
+ p = arg;
+ sc = p->np_softc;
+ adapter = sc->ndis_block.nmb_miniportadapterctx;
+
+ if (adapter == NULL)
+ return;
+
+ returnfunc = sc->ndis_chars.nmc_return_packet_func;
+ irql = FASTCALL1(hal_raise_irql, DISPATCH_LEVEL);
+ returnfunc(adapter, p);
+ FASTCALL1(hal_lower_irql, irql);
+
+ return;
+}
+
+void
+ndis_return_packet(buf, arg)
+ void *buf; /* not used */
+ void *arg;
+{
+ ndis_packet *p;
+
if (arg == NULL)
return;
@@ -747,14 +769,7 @@ ndis_return_packet(buf, arg)
if (p->np_refcnt)
return;
- sc = p->np_softc;
- returnfunc = sc->ndis_chars.nmc_return_packet_func;
- adapter = sc->ndis_block.nmb_miniportadapterctx;
- if (adapter != NULL) {
- irql = FASTCALL1(hal_raise_irql, DISPATCH_LEVEL);
- returnfunc(adapter, p);
- FASTCALL1(hal_lower_irql, irql);
- }
+ ndis_sched(ndis_return, p, NDIS_SWI);
return;
}
OpenPOWER on IntegriCloud