summaryrefslogtreecommitdiffstats
path: root/sys
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 /sys
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.
Diffstat (limited to 'sys')
-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