diff options
author | wpaul <wpaul@FreeBSD.org> | 2004-02-04 04:44:16 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2004-02-04 04:44:16 +0000 |
commit | 190b4ac58a4f75f205a3570d14a988bde8abbea3 (patch) | |
tree | 463e27bb31432f54f280d04863453cbf23d0089a | |
parent | b8d51aa138d0828da395e4cd549238f660870733 (diff) | |
download | FreeBSD-src-190b4ac58a4f75f205a3570d14a988bde8abbea3.zip FreeBSD-src-190b4ac58a4f75f205a3570d14a988bde8abbea3.tar.gz |
Correct/improve the implementation of NdisMAllocateSharedMemoryAsync().
Since we have a worker thread now, we can actually do the allocation
asynchronously in that thread's context. Also, we need to return a
status value: if we're unable to queue up the async allocation, we
return NDIS_STATUS_FAILURE, otherwise we return NDIS_STATUS_PENDING
to indicate the allocation has been queued and will occur later.
This replaces the kludge where we just invoked the callback routine
right away in the current context.
-rw-r--r-- | sys/compat/ndis/subr_ndis.c | 63 |
1 files changed, 50 insertions, 13 deletions
diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c index b7558ef..6f736a4 100644 --- a/sys/compat/ndis/subr_ndis.c +++ b/sys/compat/ndis/subr_ndis.c @@ -171,7 +171,8 @@ __stdcall static void ndis_free_mapreg(ndis_handle); static void ndis_mapshared_cb(void *, bus_dma_segment_t *, int, int); __stdcall static void ndis_alloc_sharedmem(ndis_handle, uint32_t, uint8_t, void **, ndis_physaddr *); -__stdcall static void ndis_alloc_sharedmem_async(ndis_handle, +static void ndis_asyncmem_complete(void *); +__stdcall static ndis_status ndis_alloc_sharedmem_async(ndis_handle, uint32_t, uint8_t, void *); __stdcall static void ndis_free_sharedmem(ndis_handle, uint32_t, uint8_t, void *, ndis_physaddr); @@ -1319,32 +1320,68 @@ ndis_alloc_sharedmem(adapter, len, cached, vaddr, paddr) return; } -__stdcall static void -ndis_alloc_sharedmem_async(adapter, len, cached, ctx) - ndis_handle adapter; - uint32_t len; - uint8_t cached; - void *ctx; +struct ndis_allocwork { + ndis_handle na_adapter; + uint32_t na_len; + uint8_t na_cached; + void *na_ctx; +}; + +static void +ndis_asyncmem_complete(arg) + void *arg; { ndis_miniport_block *block; struct ndis_softc *sc; + struct ndis_allocwork *w; void *vaddr; ndis_physaddr paddr; __stdcall ndis_allocdone_handler donefunc; - if (adapter == NULL) - return; - - block = (ndis_miniport_block *)adapter; + w = arg; + block = (ndis_miniport_block *)w->na_adapter; sc = (struct ndis_softc *)(block->nmb_ifp); + + vaddr = NULL; + paddr.np_quad = 0; + donefunc = sc->ndis_chars.nmc_allocate_complete_func; + ndis_alloc_sharedmem(w->na_adapter, w->na_len, + w->na_cached, &vaddr, &paddr); + donefunc(w->na_adapter, vaddr, &paddr, w->na_len, w->na_ctx); - ndis_alloc_sharedmem(adapter, len, cached, &vaddr, &paddr); - donefunc(adapter, vaddr, &paddr, len, ctx); + free(arg, M_TEMP); return; } +__stdcall static ndis_status +ndis_alloc_sharedmem_async(adapter, len, cached, ctx) + ndis_handle adapter; + uint32_t len; + uint8_t cached; + void *ctx; +{ + struct ndis_allocwork *w; + + if (adapter == NULL) + return(NDIS_STATUS_FAILURE); + + w = malloc(sizeof(struct ndis_allocwork), M_TEMP, M_NOWAIT); + + if (w == NULL) + return(NDIS_STATUS_FAILURE); + + w->na_adapter = adapter; + w->na_cached = cached; + w->na_len = len; + w->na_ctx = ctx; + + ndis_sched(ndis_asyncmem_complete, w, NDIS_TASKQUEUE); + + return(NDIS_STATUS_PENDING); +} + __stdcall static void ndis_free_sharedmem(adapter, len, cached, vaddr, paddr) ndis_handle adapter; |