diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c index a5754b6b605..6e8b347db05 100644 --- a/sys/compat/ndis/kern_ndis.c +++ b/sys/compat/ndis/kern_ndis.c @@ -1108,8 +1108,6 @@ ndis_reset_nic(arg) return(0); } -#undef NDIS_REAP_TIMERS - int ndis_halt_nic(arg) void *arg; @@ -1117,9 +1115,6 @@ ndis_halt_nic(arg) struct ndis_softc *sc; ndis_handle adapter; ndis_halt_handler haltfunc; -#ifdef NDIS_REAP_TIMERS - ndis_miniport_timer *t, *n; -#endif ndis_miniport_block *block; int empty = 0; uint8_t irql; @@ -1127,24 +1122,6 @@ ndis_halt_nic(arg) sc = arg; block = sc->ndis_block; -#ifdef NDIS_REAP_TIMERS - /* - * Drivers are sometimes very lax about cancelling all - * their timers. Cancel them all ourselves, just to be - * safe. We must do this before invoking MiniportHalt(), - * since if we wait until after, the memory in which - * the timers reside will no longer be valid. - */ - - t = sc->ndis_block->nmb_timerlist; - while (t != NULL) { - KeCancelTimer(&t->nmt_ktimer); - n = t; - t = t->nmt_nexttimer; - n->nmt_nexttimer = NULL; - } - sc->ndis_block->nmb_timerlist = NULL; -#endif if (!cold) KeFlushQueuedDpcs(); diff --git a/sys/compat/ndis/ntoskrnl_var.h b/sys/compat/ndis/ntoskrnl_var.h index 836f56eb051..b01b90eb289 100644 --- a/sys/compat/ndis/ntoskrnl_var.h +++ b/sys/compat/ndis/ntoskrnl_var.h @@ -1362,6 +1362,8 @@ extern void ExFreePool(void *); extern uint32_t IoConnectInterrupt(kinterrupt **, void *, void *, kspin_lock *, uint32_t, uint8_t, uint8_t, uint8_t, uint8_t, uint32_t, uint8_t); +extern void *MmMapIoSpace(uint64_t, uint32_t, uint32_t); +extern void MmUnmapIoSpace(void *, size_t); extern void MmBuildMdlForNonPagedPool(mdl *); extern void IoDisconnectInterrupt(kinterrupt *); extern uint32_t IoAllocateDriverObjectExtension(driver_object *, diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c index 03a277b5d61..eb2ae66722d 100644 --- a/sys/compat/ndis/subr_ndis.c +++ b/sys/compat/ndis/subr_ndis.c @@ -1257,8 +1257,6 @@ NdisMInitializeTimer(timer, handle, func, ctx) ndis_timer_function func; void *ctx; { - uint8_t irql; - /* Save the driver's funcptr and context */ timer->nmt_timerfunc = func; @@ -1276,13 +1274,6 @@ NdisMInitializeTimer(timer, handle, func, ctx) ndis_findwrap((funcptr)ndis_timercall), timer); timer->nmt_ktimer.k_dpc = &timer->nmt_kdpc; - KeAcquireSpinLock(&timer->nmt_block->nmb_lock, &irql); - - timer->nmt_nexttimer = timer->nmt_block->nmb_timerlist; - timer->nmt_block->nmb_timerlist = timer; - - KeReleaseSpinLock(&timer->nmt_block->nmb_lock, irql); - return; } @@ -1750,25 +1741,12 @@ NdisMMapIoSpace(vaddr, adapter, paddr, len) ndis_physaddr paddr; uint32_t len; { - ndis_miniport_block *block; - struct ndis_softc *sc; - if (adapter == NULL) return(NDIS_STATUS_FAILURE); - block = (ndis_miniport_block *)adapter; - sc = device_get_softc(block->nmb_physdeviceobj->do_devext); + *vaddr = MmMapIoSpace(paddr.np_quad, len, 0); - if (sc->ndis_res_mem != NULL && - paddr.np_quad == rman_get_start(sc->ndis_res_mem)) - *vaddr = (void *)rman_get_virtual(sc->ndis_res_mem); - else if (sc->ndis_res_altmem != NULL && - paddr.np_quad == rman_get_start(sc->ndis_res_altmem)) - *vaddr = (void *)rman_get_virtual(sc->ndis_res_altmem); - else if (sc->ndis_res_am != NULL && - paddr.np_quad == rman_get_start(sc->ndis_res_am)) - *vaddr = (void *)rman_get_virtual(sc->ndis_res_am); - else + if (*vaddr == NULL) return(NDIS_STATUS_FAILURE); return(NDIS_STATUS_SUCCESS); @@ -1780,6 +1758,7 @@ NdisMUnmapIoSpace(adapter, vaddr, len) void *vaddr; uint32_t len; { + MmUnmapIoSpace(vaddr, len); return; } diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c index bcd8e45311e..8f5596aa9a1 100644 --- a/sys/compat/ndis/subr_ntoskrnl.c +++ b/sys/compat/ndis/subr_ntoskrnl.c @@ -204,6 +204,7 @@ static void *MmMapLockedPagesSpecifyCache(mdl *, uint8_t, uint32_t, void *, uint32_t, uint32_t); static void MmUnmapLockedPages(void *, mdl *); static uint8_t MmIsAddressValid(void *); +static device_t ntoskrnl_finddev(device_t, uint64_t, struct resource **); static size_t RtlCompareMemory(const void *, const void *, size_t); static ndis_status RtlUnicodeStringToInteger(unicode_string *, uint32_t, uint32_t *); @@ -2541,6 +2542,116 @@ MmIsAddressValid(vaddr) return(FALSE); } +void * +MmMapIoSpace(paddr, len, cachetype) + uint64_t paddr; + uint32_t len; + uint32_t cachetype; +{ + devclass_t nexus_class; + device_t *nexus_devs, devp; + int nexus_count = 0; + device_t matching_dev = NULL; + struct resource *res; + int i; + vm_offset_t v; + + nexus_class = devclass_find("nexus"); + devclass_get_devices(nexus_class, &nexus_devs, &nexus_count); + + for (i = 0; i < nexus_count; i++) { + devp = nexus_devs[i]; + matching_dev = ntoskrnl_finddev(devp, paddr, &res); + if (matching_dev) + break; + } + + free(nexus_devs, M_TEMP); + + if (matching_dev == NULL) + return(NULL); + + v = (vm_offset_t)rman_get_virtual(res); + if (paddr > rman_get_start(res)) + v += paddr - rman_get_start(res); + + return((void *)v); +} + +void +MmUnmapIoSpace(vaddr, len) + void *vaddr; + size_t len; +{ + return; +} + + +static device_t +ntoskrnl_finddev(dev, paddr, res) + device_t dev; + uint64_t paddr; + struct resource **res; +{ + device_t *children; + device_t matching_dev; + int childcnt; + struct resource *r; + struct resource_list *rl; + struct resource_list_entry *rle; + uint32_t flags; + int i; + + /* We only want devices that have been successfully probed. */ + + if (device_is_alive(dev) == FALSE) + return(NULL); + + rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev); + if (rl != NULL) { +#if __FreeBSD_version < 600022 + SLIST_FOREACH(rle, rl, link) { +#else + STAILQ_FOREACH(rle, rl, link) { +#endif + r = rle->res; + + if (r == NULL) + continue; + + flags = rman_get_flags(r); + + if (rle->type == SYS_RES_MEMORY && + paddr >= rman_get_start(r) && + paddr <= rman_get_end(r)) { + if (!(flags & RF_ACTIVE)) + bus_activate_resource(dev, + SYS_RES_MEMORY, 0, r); + *res = r; + return(dev); + } + } + } + + /* + * If this device has children, do another + * level of recursion to inspect them. + */ + + device_get_children(dev, &children, &childcnt); + + for (i = 0; i < childcnt; i++) { + matching_dev = ntoskrnl_finddev(children[i], paddr, res); + if (matching_dev != NULL) { + free(children, M_TEMP); + return(matching_dev); + } + } + + free(children, M_TEMP); + return(NULL); +} + /* * Workitems are unlike DPCs, in that they run in a user-mode thread * context rather than at DISPATCH_LEVEL in kernel context. In our @@ -4053,6 +4164,8 @@ image_patch_table ntoskrnl_functbl[] = { IMPORT_SFUNC(MmUnmapLockedPages, 2), IMPORT_SFUNC(MmBuildMdlForNonPagedPool, 1), IMPORT_SFUNC(MmIsAddressValid, 1), + IMPORT_SFUNC(MmMapIoSpace, 3 + 1), + IMPORT_SFUNC(MmUnmapIoSpace, 2), IMPORT_SFUNC(KeInitializeSpinLock, 1), IMPORT_SFUNC(IoIsWdmVersionAvailable, 2), IMPORT_SFUNC(IoGetDeviceProperty, 5),