diff options
author | wpaul <wpaul@FreeBSD.org> | 2005-05-16 15:29:21 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2005-05-16 15:29:21 +0000 |
commit | 0228d4cac81797f6a834721ec46e7c2f60e3f0e9 (patch) | |
tree | 7fc8454e08df495c6dfb64f8c3179a07ce231746 /sys/compat | |
parent | e7b25f55b8be91eecf779abf73f2344569f00dcb (diff) | |
download | FreeBSD-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.
Diffstat (limited to 'sys/compat')
-rw-r--r-- | sys/compat/ndis/ndis_var.h | 20 | ||||
-rw-r--r-- | sys/compat/ndis/subr_ndis.c | 19 |
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); } |