Reorganize the timer code a little and implement NdisInitializeTimer()

and NdisCancelTimer(). NdisInitializeTimer() doesn't accept an NDIS
miniport context argument, so we have to derive it from the timer
function context (which is supposed to be the adapter private context).
NdisCancelTimer is now an alias for NdisMCancelTimer().

Also add stubs for NdisMRegisterDevice() and NdisMDeregisterDevice().
These are no-ops for now, but will likely get fleshed in once I start
working on the Am1771/Am1772 wireless driver.
This commit is contained in:
Bill Paul 2004-01-26 21:21:53 +00:00
parent 71f4a30d59
commit 581b0a24bc
3 changed files with 96 additions and 17 deletions

View File

@ -87,6 +87,8 @@ __stdcall static void ndis_getdone_func(ndis_handle, ndis_status);
__stdcall static void ndis_resetdone_func(ndis_handle, ndis_status, uint8_t);
__stdcall static void ndis_sendrsrcavail_func(ndis_handle);
struct nd_head ndis_devhead;
struct ndis_req {
void (*nr_func)(void *);
void *nr_arg;
@ -113,7 +115,6 @@ static STAILQ_HEAD(ndisqhead, ndis_req) ndis_ttodo;
struct ndisqhead ndis_itodo;
struct ndisqhead ndis_free;
static int ndis_jobs = 32;
static int ndis_devs = 0;
static struct ndisproc ndis_tproc;
static struct ndisproc ndis_iproc;
@ -145,11 +146,13 @@ ndis_modevent(module_t mod, int cmd, void *arg)
ndis_create_kthreads();
TAILQ_INIT(&ndis_devhead);
break;
case MOD_SHUTDOWN:
/* stop kthreads */
ndis_destroy_kthreads();
if (ndis_devs == 0) {
if (TAILQ_FIRST(&ndis_devhead) != NULL) {
/* Shut down subsystems */
ndis_libfini();
ntoskrnl_libfini();
@ -1189,7 +1192,6 @@ ndis_shutdown_nic(arg)
ndis_handle adapter;
__stdcall ndis_shutdown_handler shutdownfunc;
sc = arg;
adapter = sc->ndis_block.nmb_miniportadapterctx;
if (adapter == NULL)
@ -1205,7 +1207,7 @@ ndis_shutdown_nic(arg)
shutdownfunc(sc->ndis_chars.nmc_rsvd0);
ndis_shrink_thrqueue(8);
ndis_devs--;
TAILQ_REMOVE(&ndis_devhead, &sc->ndis_block, link);
return(0);
}
@ -1400,7 +1402,7 @@ ndis_unload_driver(arg)
ndis_flush_sysctls(sc);
ndis_shrink_thrqueue(8);
ndis_devs--;
TAILQ_REMOVE(&ndis_devhead, &sc->ndis_block, link);
return(0);
}
@ -1510,7 +1512,7 @@ ndis_load_driver(img, arg)
ndis_enlarge_thrqueue(8);
ndis_devs++;
TAILQ_INSERT_TAIL(&ndis_devhead, block, link);
return(0);
}

View File

@ -1434,8 +1434,11 @@ struct ndis_miniport_block {
ndis_status nmb_setstat;
struct nte_head nmb_timerlist;
vm_offset_t nmb_img;
TAILQ_ENTRY(ndis_miniport_block) link;
};
TAILQ_HEAD(nd_head, ndis_miniport_block);
typedef ndis_status (*ndis_init_handler)(ndis_status *, uint32_t *,
ndis_medium *, uint32_t, ndis_handle, ndis_handle);
typedef ndis_status (*ndis_queryinfo_handler)(ndis_handle, ndis_oid,

View File

@ -104,6 +104,7 @@ __FBSDID("$FreeBSD$");
static struct mtx *ndis_interlock;
static char ndis_filepath[MAXPATHLEN];
struct mtx_pool *ndis_mtxpool;
extern struct nd_head ndis_devhead;
SYSCTL_STRING(_hw, OID_AUTO, ndis_filepath, CTLFLAG_RW, ndis_filepath,
MAXPATHLEN, "Path used by NdisOpenFile() to search for files");
@ -147,6 +148,8 @@ __stdcall static void ndis_vtophys_load(ndis_handle, ndis_buffer *,
__stdcall static void ndis_vtophys_unload(ndis_handle, ndis_buffer *, uint32_t);
__stdcall static void ndis_create_timer(ndis_miniport_timer *, ndis_handle *,
ndis_timer_function, void *);
__stdcall static void ndis_init_timer(ndis_timer *,
ndis_timer_function, void *);
static void ndis_timercall(void *);
__stdcall static void ndis_set_timer(ndis_miniport_timer *, uint32_t);
static void ndis_tick(void *);
@ -266,6 +269,10 @@ __stdcall static void ndis_pkt_to_pkt(ndis_packet *, uint32_t, uint32_t,
ndis_packet *, uint32_t, uint32_t *);
__stdcall static void ndis_pkt_to_pkt_safe(ndis_packet *, uint32_t, uint32_t,
ndis_packet *, uint32_t, uint32_t *, uint32_t);
__stdcall static ndis_status ndis_register_dev(ndis_handle *,
ndis_unicode_string *, ndis_unicode_string *, void *,
void *, ndis_handle **);
__stdcall static ndis_status ndis_deregister_dev(ndis_handle *);
__stdcall static void dummy(void);
/*
@ -891,6 +898,49 @@ ndis_vtophys_unload(adapter, buf, mapreg)
return;
}
/*
* This is an older pre-miniport timer init routine which doesn't
* accept a miniport context handle. The function context (ctx)
* is supposed to be a pointer to the adapter handle, which should
* have been handed to us via NdisSetAttributesEx(). We use this
* function context to track down the corresponding ndis_miniport_block
* structure. It's vital that we track down the miniport block structure,
* so if we can't do it, we panic. Note that we also play some games
* here by treating ndis_timer and ndis_miniport_timer as the same
* thing.
*/
__stdcall static void
ndis_init_timer(timer, func, ctx)
ndis_timer *timer;
ndis_timer_function func;
void *ctx;
{
struct ndis_timer_entry *ne = NULL;
ndis_miniport_block *block = NULL;
TAILQ_FOREACH(block, &ndis_devhead, link) {
if (block->nmb_miniportadapterctx == ctx)
break;
}
if (block->nmb_miniportadapterctx != ctx)
panic("NDIS driver timer context didn't "
"match any adapter contexts");
ne = malloc(sizeof(struct ndis_timer_entry), M_DEVBUF, M_NOWAIT);
callout_init(&ne->nte_ch, CALLOUT_MPSAFE);
TAILQ_INSERT_TAIL(&block->nmb_timerlist, ne, link);
ne->nte_timer = (ndis_miniport_timer *)timer;
timer->nt_timer.nk_header.dh_sigstate = TRUE;
timer->nt_dpc.nk_sysarg1 = &ne->nte_ch;
timer->nt_dpc.nk_deferedfunc = (ndis_kdpc_func)func;
timer->nt_dpc.nk_deferredctx = ctx;
return;
}
__stdcall static void
ndis_create_timer(timer, handle, func, ctx)
ndis_miniport_timer *timer;
@ -908,9 +958,9 @@ ndis_create_timer(timer, handle, func, ctx)
ne->nte_timer = timer;
timer->nmt_ktimer.nk_header.dh_sigstate = TRUE;
timer->nmt_dpc.nk_deferredctx = &ne->nte_ch;
timer->nmt_timerfunc = func;
timer->nmt_timerctx = ctx;
timer->nmt_dpc.nk_sysarg1 = &ne->nte_ch;
timer->nmt_dpc.nk_deferedfunc = (ndis_kdpc_func)func;
timer->nmt_dpc.nk_deferredctx = ctx;
return;
}
@ -930,8 +980,8 @@ ndis_timercall(arg)
timer = arg;
timer->nmt_ktimer.nk_header.dh_sigstate = FALSE;
timerfunc = timer->nmt_timerfunc;
timerfunc(NULL, timer->nmt_timerctx, NULL, NULL);
timerfunc = (ndis_timer_function)timer->nmt_dpc.nk_deferedfunc;
timerfunc(NULL, timer->nmt_dpc.nk_deferredctx, NULL, NULL);
return;
}
@ -953,7 +1003,7 @@ ndis_set_timer(timer, msecs)
tv.tv_sec = 0;
tv.tv_usec = msecs * 1000;
ch = timer->nmt_dpc.nk_deferredctx;
ch = timer->nmt_dpc.nk_sysarg1;
timer->nmt_dpc.nk_sysarg2 = ndis_timercall;
timer->nmt_ktimer.nk_header.dh_sigstate = TRUE;
callout_reset(ch, tvtohz(&tv), timer->nmt_dpc.nk_sysarg2, timer);
@ -973,14 +1023,14 @@ ndis_tick(arg)
timer = arg;
timer->nmt_ktimer.nk_header.dh_sigstate = FALSE;
timerfunc = timer->nmt_timerfunc;
timerfunc(NULL, timer->nmt_timerctx, NULL, NULL);
timerfunc = (ndis_timer_function)timer->nmt_dpc.nk_deferedfunc;
timerfunc(NULL, timer->nmt_dpc.nk_deferredctx, NULL, NULL);
/* Automatically reload timer. */
tv.tv_sec = 0;
tv.tv_usec = timer->nmt_ktimer.nk_period * 1000;
ch = timer->nmt_dpc.nk_deferredctx;
ch = timer->nmt_dpc.nk_sysarg1;
timer->nmt_ktimer.nk_header.dh_sigstate = TRUE;
timer->nmt_dpc.nk_sysarg2 = ndis_tick;
callout_reset(ch, tvtohz(&tv), timer->nmt_dpc.nk_sysarg2, timer);
@ -1000,7 +1050,7 @@ ndis_set_periodic_timer(timer, msecs)
tv.tv_usec = msecs * 1000;
timer->nmt_ktimer.nk_period = msecs;
ch = timer->nmt_dpc.nk_deferredctx;
ch = timer->nmt_dpc.nk_sysarg1;
timer->nmt_dpc.nk_sysarg2 = ndis_tick;
timer->nmt_ktimer.nk_header.dh_sigstate = TRUE;
callout_reset(ch, tvtohz(&tv), timer->nmt_dpc.nk_sysarg2, timer);
@ -1017,7 +1067,7 @@ ndis_cancel_timer(timer, cancelled)
if (timer == NULL)
return;
ch = timer->nmt_dpc.nk_deferredctx;
ch = timer->nmt_dpc.nk_sysarg1;
if (ch == NULL)
return;
callout_stop(ch);
@ -2608,6 +2658,26 @@ ndis_pkt_to_pkt_safe(dpkt, doff, reqlen, spkt, soff, cpylen, prio)
return;
}
__stdcall static ndis_status
ndis_register_dev(handle, devname, symname, majorfuncs, devobj, devhandle)
ndis_handle *handle;
ndis_unicode_string *devname;
ndis_unicode_string *symname;
void *majorfuncs;
void *devobj;
ndis_handle **devhandle;
{
return(NDIS_STATUS_SUCCESS);
}
__stdcall static ndis_status
ndis_deregister_dev(devhandle)
ndis_handle *devhandle;
{
return(NDIS_STATUS_SUCCESS);
}
__stdcall static void
dummy()
{
@ -2667,8 +2737,10 @@ image_patch_table ndis_functbl[] = {
{ "NdisMStartBufferPhysicalMapping", (FUNC)ndis_vtophys_load },
{ "NdisMCompleteBufferPhysicalMapping", (FUNC)ndis_vtophys_unload },
{ "NdisMInitializeTimer", (FUNC)ndis_create_timer },
{ "NdisInitializeTimer", (FUNC)ndis_init_timer },
{ "NdisSetTimer", (FUNC)ndis_set_timer },
{ "NdisMCancelTimer", (FUNC)ndis_cancel_timer },
{ "NdisCancelTimer", (FUNC)ndis_cancel_timer },
{ "NdisMSetPeriodicTimer", (FUNC)ndis_set_periodic_timer },
{ "NdisMQueryAdapterResources", (FUNC)ndis_query_resources },
{ "NdisMRegisterIoPortRange", (FUNC)ndis_register_ioport },
@ -2722,6 +2794,8 @@ image_patch_table ndis_functbl[] = {
{ "NdisMapFile", (FUNC)ndis_map_file },
{ "NdisUnmapFile", (FUNC)ndis_unmap_file },
{ "NdisCloseFile", (FUNC)ndis_close_file },
{ "NdisMRegisterDevice", (FUNC)ndis_register_dev },
{ "NdisMDeregisterDevice", (FUNC)ndis_deregister_dev },
/*
* This last entry is a catch-all for any function we haven't