summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2004-02-04 04:44:16 +0000
committerwpaul <wpaul@FreeBSD.org>2004-02-04 04:44:16 +0000
commit190b4ac58a4f75f205a3570d14a988bde8abbea3 (patch)
tree463e27bb31432f54f280d04863453cbf23d0089a
parentb8d51aa138d0828da395e4cd549238f660870733 (diff)
downloadFreeBSD-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.c63
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;
OpenPOWER on IntegriCloud