PERFORCE change 145590 for review
Weongyo Jeong
weongyo at FreeBSD.org
Tue Jul 22 05:06:58 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=145590
Change 145590 by weongyo at weongyo_ws on 2008/07/22 05:06:36
fix a case that it's caused by NDIS driver's bug(?) that when NDIS
framework try to query/set a information using ndis_(set|get)_info
functions, some drivers return NDIS_STATUS_PENDING value in spite of
it already called the callback.
Affected files ...
.. //depot/projects/ndisusb/sys/compat/ndis/kern_ndis.c#3 edit
.. //depot/projects/ndisusb/sys/dev/if_ndis/if_ndis.c#4 edit
Differences ...
==== //depot/projects/ndisusb/sys/compat/ndis/kern_ndis.c#3 (text+ko) ====
@@ -884,8 +884,10 @@
if (sc->ndis_block->nmb_pendingreq != NULL) {
KeReleaseSpinLock(&sc->ndis_block->nmb_lock, irql);
panic("ndis_set_info() called while other request pending");
- } else
+ } else {
sc->ndis_block->nmb_pendingreq = (ndis_request *)sc;
+ sc->ndis_block->nmb_setstat = -1;
+ }
setfunc = sc->ndis_chars->nmc_setinfo_func;
adapter = sc->ndis_block->nmb_miniportadapterctx;
@@ -901,6 +903,9 @@
&byteswritten, &bytesneeded);
sc->ndis_block->nmb_pendingreq = NULL;
+ /* please see a description of ndis_get_info() why we check this. */
+ if (rval == NDIS_STATUS_PENDING && sc->ndis_block->nmb_setstat != -1)
+ rval = sc->ndis_block->nmb_setstat;
KeReleaseSpinLock(&sc->ndis_block->nmb_lock, irql);
@@ -1306,8 +1311,11 @@
if (sc->ndis_block->nmb_pendingreq != NULL) {
KeReleaseSpinLock(&sc->ndis_block->nmb_lock, irql);
panic("ndis_get_info() called while other request pending");
- } else
+ } else {
sc->ndis_block->nmb_pendingreq = (ndis_request *)sc;
+ /* NB: `nmb_getstat' type is uint32_t. */
+ sc->ndis_block->nmb_getstat = -1;
+ }
queryfunc = sc->ndis_chars->nmc_queryinfo_func;
adapter = sc->ndis_block->nmb_miniportadapterctx;
@@ -1323,6 +1331,18 @@
&byteswritten, &bytesneeded);
sc->ndis_block->nmb_pendingreq = NULL;
+ /*
+ * NB: some NDIS USB drivers (AFAIK Netgear WG111v2) looks that they
+ * return NDIS_STATUS_PENDING value even if they already called the
+ * callback function in their routine, ndis_getdone_func(). So we
+ * need to check the value whether it's set or not before waiting for
+ * 5 seconds. If we doesn't, we would always be blocked for 5 seconds
+ * because the `nmb_getevent' event wouldn't be happened that the event
+ * is already fired before we try to set it using
+ * KeWaitForSingleObject().
+ */
+ if (rval == NDIS_STATUS_PENDING && sc->ndis_block->nmb_getstat != -1)
+ rval = sc->ndis_block->nmb_getstat;
KeReleaseSpinLock(&sc->ndis_block->nmb_lock, irql);
==== //depot/projects/ndisusb/sys/dev/if_ndis/if_ndis.c#4 (text+ko) ====
More information about the p4-projects
mailing list