summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2005-05-16 15:29:21 +0000
committerwpaul <wpaul@FreeBSD.org>2005-05-16 15:29:21 +0000
commit0228d4cac81797f6a834721ec46e7c2f60e3f0e9 (patch)
tree7fc8454e08df495c6dfb64f8c3179a07ce231746
parente7b25f55b8be91eecf779abf73f2344569f00dcb (diff)
downloadFreeBSD-src-0228d4cac81797f6a834721ec46e7c2f60e3f0e9.zip
FreeBSD-src-0228d4cac81797f6a834721ec46e7c2f60e3f0e9.tar.gz
Correct some problems with workitem usage. NdisScheduleWorkItem() does
not use exactly the same workitem sturcture as ExQueueWorkItem() like I originally thought it did.
-rw-r--r--sys/compat/ndis/ndis_var.h20
-rw-r--r--sys/compat/ndis/subr_ndis.c19
2 files changed, 35 insertions, 4 deletions
diff --git a/sys/compat/ndis/ndis_var.h b/sys/compat/ndis/ndis_var.h
index fc577a1..742fae2 100644
--- a/sys/compat/ndis/ndis_var.h
+++ b/sys/compat/ndis/ndis_var.h
@@ -977,9 +977,23 @@ typedef enum ndis_interrupt_mode ndis_interrupt_mode;
#define NUMBER_OF_SINGLE_WORK_ITEMS 6
-typedef work_queue_item ndis_work_item;
-typedef work_item_func ndis_proc;
-#define NdisInitializeWorkItem(w, f, c) ExInitializeWorkItem(w, f, c)
+struct ndis_work_item;
+
+typedef void (*ndis_proc)(struct ndis_work_item *, void *);
+
+struct ndis_work_item {
+ void *nwi_ctx;
+ ndis_proc nwi_func;
+ uint8_t nwi_wraprsvd[sizeof(void *) * 8];
+};
+
+typedef struct ndis_work_item ndis_work_item;
+
+#define NdisInitializeWorkItem(w, f, c) \
+ do { \
+ (w)->nwi_ctx = c; \
+ (w)->nwi_func = f; \
+ } while (0)
#ifdef notdef
struct ndis_buffer {
diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c
index f34f58f..49b3da9 100644
--- a/sys/compat/ndis/subr_ndis.c
+++ b/sys/compat/ndis/subr_ndis.c
@@ -1658,6 +1658,7 @@ NdisMAllocateSharedMemoryAsync(adapter, len, cached, ctx)
w->na_cached = cached;
w->na_len = len;
w->na_ctx = ctx;
+ w->na_iw = iw;
ifw = (io_workitem_func)ndis_findwrap((funcptr)ndis_asyncmem_complete);
IoQueueWorkItem(iw, ifw, WORKQUEUE_DELAYED, w);
@@ -3100,13 +3101,29 @@ NdisMIndicateStatus(adapter, status, sbuf, slen)
* depends on the API semantics of ExQueueWorkItem(). In our world,
* ExQueueWorkItem() is implemented on top of IoAllocateQueueItem()
* anyway.
+ *
+ * There are actually three distinct APIs here. NdisScheduleWorkItem()
+ * takes a pointer to an NDIS_WORK_ITEM. ExQueueWorkItem() takes a pointer
+ * to a WORK_QUEUE_ITEM. And finally, IoQueueWorkItem() takes a pointer
+ * to an opaque work item thingie which you get from IoAllocateWorkItem().
+ * An NDIS_WORK_ITEM is not the same as a WORK_QUEUE_ITEM. However,
+ * the NDIS_WORK_ITEM has some opaque storage at the end of it, and we
+ * (ab)use this storage as a WORK_QUEUE_ITEM, which is what we submit
+ * to ExQueueWorkItem().
+ *
+ * Got all that? (Sheesh.)
*/
ndis_status
NdisScheduleWorkItem(work)
ndis_work_item *work;
{
- ExQueueWorkItem(work, WORKQUEUE_DELAYED);
+ work_queue_item *wqi;
+
+ wqi = (work_queue_item *)work->nwi_wraprsvd;
+ ExInitializeWorkItem(wqi,
+ (work_item_func)work->nwi_func, work->nwi_ctx);
+ ExQueueWorkItem(wqi, WORKQUEUE_DELAYED);
return(NDIS_STATUS_SUCCESS);
}
OpenPOWER on IntegriCloud