From 581b0a24bc5b9ac9e14d57046f98d68217bb7fcf Mon Sep 17 00:00:00 2001 From: Bill Paul Date: Mon, 26 Jan 2004 21:21:53 +0000 Subject: [PATCH] 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. --- sys/compat/ndis/kern_ndis.c | 14 +++--- sys/compat/ndis/ndis_var.h | 3 ++ sys/compat/ndis/subr_ndis.c | 96 ++++++++++++++++++++++++++++++++----- 3 files changed, 96 insertions(+), 17 deletions(-) diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c index e640e8e78b9a..623cfca49af1 100644 --- a/sys/compat/ndis/kern_ndis.c +++ b/sys/compat/ndis/kern_ndis.c @@ -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); } diff --git a/sys/compat/ndis/ndis_var.h b/sys/compat/ndis/ndis_var.h index d8a200d4dc4e..cd03ca78bee4 100644 --- a/sys/compat/ndis/ndis_var.h +++ b/sys/compat/ndis/ndis_var.h @@ -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, diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c index da5cf89016f8..5dd2b845eb29 100644 --- a/sys/compat/ndis/subr_ndis.c +++ b/sys/compat/ndis/subr_ndis.c @@ -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