diff options
Diffstat (limited to 'sys/compat/ndis/kern_ndis.c')
-rw-r--r-- | sys/compat/ndis/kern_ndis.c | 268 |
1 files changed, 115 insertions, 153 deletions
diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c index f6db9c7..f93bf4e 100644 --- a/sys/compat/ndis/kern_ndis.c +++ b/sys/compat/ndis/kern_ndis.c @@ -125,6 +125,7 @@ static struct ndisproc ndis_iproc; * collision with if_ndis.ko, which internally calls itself * 'ndis.' */ + static int ndis_modevent(module_t mod, int cmd, void *arg) { @@ -133,6 +134,7 @@ ndis_modevent(module_t mod, int cmd, void *arg) switch (cmd) { case MOD_LOAD: /* Initialize subsystems */ + windrv_libinit(); ndis_libinit(); ntoskrnl_libinit(); @@ -169,6 +171,7 @@ ndis_modevent(module_t mod, int cmd, void *arg) /* Shut down subsystems */ ndis_libfini(); ntoskrnl_libfini(); + windrv_libfini(); /* Remove zones */ uma_zdestroy(ndis_packet_zone); @@ -542,10 +545,14 @@ ndis_status_func(adapter, status, sbuf, slen) uint32_t slen; { ndis_miniport_block *block; - block = adapter; + struct ndis_softc *sc; + struct ifnet *ifp; - if (block->nmb_ifp->if_flags & IFF_DEBUG) - device_printf (block->nmb_dev, "status: %x\n", status); + block = adapter; + sc = device_get_softc(block->nmb_physdeviceobj->do_devext); + ifp = &sc->arpcom.ac_if; + if (ifp->if_flags & IFF_DEBUG) + device_printf (sc->ndis_dev, "status: %x\n", status); return; } @@ -554,10 +561,14 @@ ndis_statusdone_func(adapter) ndis_handle adapter; { ndis_miniport_block *block; + struct ndis_softc *sc; + struct ifnet *ifp; + block = adapter; - - if (block->nmb_ifp->if_flags & IFF_DEBUG) - device_printf (block->nmb_dev, "status complete\n"); + sc = device_get_softc(block->nmb_physdeviceobj->do_devext); + ifp = &sc->arpcom.ac_if; + if (ifp->if_flags & IFF_DEBUG) + device_printf (sc->ndis_dev, "status complete\n"); return; } @@ -594,11 +605,16 @@ ndis_resetdone_func(adapter, status, addressingreset) uint8_t addressingreset; { ndis_miniport_block *block; + struct ndis_softc *sc; + struct ifnet *ifp; + block = adapter; + sc = device_get_softc(block->nmb_physdeviceobj->do_devext); + ifp = &sc->arpcom.ac_if; - if (block->nmb_ifp->if_flags & IFF_DEBUG) - device_printf (block->nmb_dev, "reset done...\n"); - wakeup(block->nmb_ifp); + if (ifp->if_flags & IFF_DEBUG) + device_printf (sc->ndis_dev, "reset done...\n"); + wakeup(ifp); return; } @@ -780,12 +796,12 @@ ndis_return(arg) p = arg; sc = p->np_softc; - adapter = sc->ndis_block.nmb_miniportadapterctx; + adapter = sc->ndis_block->nmb_miniportadapterctx; if (adapter == NULL) return; - returnfunc = sc->ndis_chars.nmc_return_packet_func; + returnfunc = sc->ndis_chars->nmc_return_packet_func; irql = KeRaiseIrql(DISPATCH_LEVEL); returnfunc(adapter, p); KeLowerIrql(irql); @@ -863,7 +879,7 @@ ndis_convert_res(arg) int error = 0; sc = arg; - block = &sc->ndis_block; + block = sc->ndis_block; dev = sc->ndis_dev; SLIST_INIT(&brl_rev); @@ -1129,25 +1145,25 @@ ndis_set_info(arg, oid, buf, buflen) sc = arg; NDIS_LOCK(sc); - setfunc = sc->ndis_chars.nmc_setinfo_func; - adapter = sc->ndis_block.nmb_miniportadapterctx; + setfunc = sc->ndis_chars->nmc_setinfo_func; + adapter = sc->ndis_block->nmb_miniportadapterctx; NDIS_UNLOCK(sc); if (adapter == NULL || setfunc == NULL) return(ENXIO); - KeAcquireSpinLock(&sc->ndis_block.nmb_lock, &irql); + KeAcquireSpinLock(&sc->ndis_block->nmb_lock, &irql); rval = setfunc(adapter, oid, buf, *buflen, &byteswritten, &bytesneeded); - KeReleaseSpinLock(&sc->ndis_block.nmb_lock, irql); + KeReleaseSpinLock(&sc->ndis_block->nmb_lock, irql); if (rval == NDIS_STATUS_PENDING) { mtx_lock(&ndis_req_mtx); - error = msleep(&sc->ndis_block.nmb_setstat, + error = msleep(&sc->ndis_block->nmb_setstat, &ndis_req_mtx, curthread->td_priority|PDROP, "ndisset", 5 * hz); - rval = sc->ndis_block.nmb_setstat; + rval = sc->ndis_block->nmb_setstat; } if (byteswritten) @@ -1188,11 +1204,11 @@ ndis_send_packets(arg, packets, cnt) uint8_t irql; sc = arg; - adapter = sc->ndis_block.nmb_miniportadapterctx; + adapter = sc->ndis_block->nmb_miniportadapterctx; if (adapter == NULL) return(ENXIO); - sendfunc = sc->ndis_chars.nmc_sendmulti_func; - senddonefunc = sc->ndis_block.nmb_senddone_func; + sendfunc = sc->ndis_chars->nmc_sendmulti_func; + senddonefunc = sc->ndis_block->nmb_senddone_func; irql = KeRaiseIrql(DISPATCH_LEVEL); sendfunc(adapter, packets, cnt); KeLowerIrql(irql); @@ -1207,7 +1223,7 @@ ndis_send_packets(arg, packets, cnt) */ if (p == NULL || p->np_oob.npo_status == NDIS_STATUS_PENDING) continue; - senddonefunc(&sc->ndis_block, p, p->np_oob.npo_status); + senddonefunc(sc->ndis_block, p, p->np_oob.npo_status); } return(0); @@ -1226,11 +1242,11 @@ ndis_send_packet(arg, packet) uint8_t irql; sc = arg; - adapter = sc->ndis_block.nmb_miniportadapterctx; + adapter = sc->ndis_block->nmb_miniportadapterctx; if (adapter == NULL) return(ENXIO); - sendfunc = sc->ndis_chars.nmc_sendsingle_func; - senddonefunc = sc->ndis_block.nmb_senddone_func; + sendfunc = sc->ndis_chars->nmc_sendsingle_func; + senddonefunc = sc->ndis_block->nmb_senddone_func; irql = KeRaiseIrql(DISPATCH_LEVEL); status = sendfunc(adapter, packet, packet->np_private.npp_flags); @@ -1239,7 +1255,7 @@ ndis_send_packet(arg, packet) if (status == NDIS_STATUS_PENDING) return(0); - senddonefunc(&sc->ndis_block, packet, status); + senddonefunc(sc->ndis_block, packet, status); return(0); } @@ -1315,8 +1331,8 @@ ndis_reset_nic(arg) sc = arg; ifp = &sc->arpcom.ac_if; NDIS_LOCK(sc); - adapter = sc->ndis_block.nmb_miniportadapterctx; - resetfunc = sc->ndis_chars.nmc_reset_func; + adapter = sc->ndis_block->nmb_miniportadapterctx; + resetfunc = sc->ndis_chars->nmc_reset_func; NDIS_UNLOCK(sc); if (adapter == NULL || resetfunc == NULL) return(EIO); @@ -1347,7 +1363,7 @@ ndis_halt_nic(arg) ifp = &sc->arpcom.ac_if; NDIS_LOCK(sc); - adapter = sc->ndis_block.nmb_miniportadapterctx; + adapter = sc->ndis_block->nmb_miniportadapterctx; if (adapter == NULL) { NDIS_UNLOCK(sc); return(EIO); @@ -1359,13 +1375,13 @@ ndis_halt_nic(arg) * halt handler has been called. */ - haltfunc = sc->ndis_chars.nmc_halt_func; + haltfunc = sc->ndis_chars->nmc_halt_func; NDIS_UNLOCK(sc); haltfunc(adapter); NDIS_LOCK(sc); - sc->ndis_block.nmb_miniportadapterctx = NULL; + sc->ndis_block->nmb_miniportadapterctx = NULL; NDIS_UNLOCK(sc); return(0); @@ -1381,19 +1397,19 @@ ndis_shutdown_nic(arg) sc = arg; NDIS_LOCK(sc); - adapter = sc->ndis_block.nmb_miniportadapterctx; - shutdownfunc = sc->ndis_chars.nmc_shutdown_handler; + adapter = sc->ndis_block->nmb_miniportadapterctx; + shutdownfunc = sc->ndis_chars->nmc_shutdown_handler; NDIS_UNLOCK(sc); if (adapter == NULL || shutdownfunc == NULL) return(EIO); - if (sc->ndis_chars.nmc_rsvd0 == NULL) + if (sc->ndis_chars->nmc_rsvd0 == NULL) shutdownfunc(adapter); else - shutdownfunc(sc->ndis_chars.nmc_rsvd0); + shutdownfunc(sc->ndis_chars->nmc_rsvd0); ndis_shrink_thrqueue(8); - TAILQ_REMOVE(&ndis_devhead, &sc->ndis_block, link); + TAILQ_REMOVE(&ndis_devhead, sc->ndis_block, link); return(0); } @@ -1414,8 +1430,8 @@ ndis_init_nic(arg) sc = arg; NDIS_LOCK(sc); - block = &sc->ndis_block; - initfunc = sc->ndis_chars.nmc_init_func; + block = sc->ndis_block; + initfunc = sc->ndis_chars->nmc_init_func; NDIS_UNLOCK(sc); TAILQ_INIT(&block->nmb_timerlist); @@ -1433,7 +1449,7 @@ ndis_init_nic(arg) */ if (status != NDIS_STATUS_SUCCESS) { NDIS_LOCK(sc); - sc->ndis_block.nmb_miniportadapterctx = NULL; + sc->ndis_block->nmb_miniportadapterctx = NULL; NDIS_UNLOCK(sc); return(ENXIO); } @@ -1450,8 +1466,8 @@ ndis_enable_intr(arg) __stdcall ndis_enable_interrupts_handler intrenbfunc; sc = arg; - adapter = sc->ndis_block.nmb_miniportadapterctx; - intrenbfunc = sc->ndis_chars.nmc_enable_interrupts_func; + adapter = sc->ndis_block->nmb_miniportadapterctx; + intrenbfunc = sc->ndis_chars->nmc_enable_interrupts_func; if (adapter == NULL || intrenbfunc == NULL) return; intrenbfunc(adapter); @@ -1468,10 +1484,8 @@ ndis_disable_intr(arg) __stdcall ndis_disable_interrupts_handler intrdisfunc; sc = arg; - NDIS_LOCK(sc); - adapter = sc->ndis_block.nmb_miniportadapterctx; - intrdisfunc = sc->ndis_chars.nmc_disable_interrupts_func; - NDIS_UNLOCK(sc); + adapter = sc->ndis_block->nmb_miniportadapterctx; + intrdisfunc = sc->ndis_chars->nmc_disable_interrupts_func; if (adapter == NULL || intrdisfunc == NULL) return; intrdisfunc(adapter); @@ -1494,8 +1508,8 @@ ndis_isr(arg, ourintr, callhandler) return(EINVAL); sc = arg; - adapter = sc->ndis_block.nmb_miniportadapterctx; - isrfunc = sc->ndis_chars.nmc_isr_func; + adapter = sc->ndis_block->nmb_miniportadapterctx; + isrfunc = sc->ndis_chars->nmc_isr_func; if (adapter == NULL || isrfunc == NULL) return(ENXIO); @@ -1519,8 +1533,8 @@ ndis_intrhand(arg) sc = arg; NDIS_LOCK(sc); - adapter = sc->ndis_block.nmb_miniportadapterctx; - intrfunc = sc->ndis_chars.nmc_interrupt_func; + adapter = sc->ndis_block->nmb_miniportadapterctx; + intrfunc = sc->ndis_chars->nmc_interrupt_func; NDIS_UNLOCK(sc); if (adapter == NULL || intrfunc == NULL) return(EINVAL); @@ -1547,27 +1561,27 @@ ndis_get_info(arg, oid, buf, buflen) sc = arg; NDIS_LOCK(sc); - queryfunc = sc->ndis_chars.nmc_queryinfo_func; - adapter = sc->ndis_block.nmb_miniportadapterctx; + queryfunc = sc->ndis_chars->nmc_queryinfo_func; + adapter = sc->ndis_block->nmb_miniportadapterctx; NDIS_UNLOCK(sc); if (adapter == NULL || queryfunc == NULL) return(ENXIO); - KeAcquireSpinLock(&sc->ndis_block.nmb_lock, &irql); + KeAcquireSpinLock(&sc->ndis_block->nmb_lock, &irql); rval = queryfunc(adapter, oid, buf, *buflen, &byteswritten, &bytesneeded); - KeReleaseSpinLock(&sc->ndis_block.nmb_lock, irql); + KeReleaseSpinLock(&sc->ndis_block->nmb_lock, irql); /* Wait for requests that block. */ if (rval == NDIS_STATUS_PENDING) { mtx_lock(&ndis_req_mtx); - error = msleep(&sc->ndis_block.nmb_getstat, + error = msleep(&sc->ndis_block->nmb_getstat, &ndis_req_mtx, curthread->td_priority|PDROP, "ndisget", 5 * hz); - rval = sc->ndis_block.nmb_getstat; + rval = sc->ndis_block->nmb_getstat; } if (byteswritten) @@ -1592,96 +1606,39 @@ ndis_get_info(arg, oid, buf, buflen) return(0); } -int -ndis_unload_driver(arg) - void *arg; +__stdcall uint32_t +NdisAddDevice(drv, pdo) + driver_object *drv; + device_object *pdo; { + device_object *fdo; + ndis_miniport_block *block; struct ndis_softc *sc; + uint32_t status; - sc = arg; - - free(sc->ndis_block.nmb_rlist, M_DEVBUF); - - ndis_flush_sysctls(sc); - - ndis_shrink_thrqueue(8); - TAILQ_REMOVE(&ndis_devhead, &sc->ndis_block, link); - - return(0); -} - -#define NDIS_LOADED htonl(0x42534F44) - -int -ndis_load_driver(img, arg) - vm_offset_t img; - void *arg; -{ - driver_entry entry; - image_optional_header opt_hdr; - image_import_descriptor imp_desc; - ndis_unicode_string dummystr; - ndis_miniport_block *block; - ndis_status status; - int idx; - uint32_t *ptr; - struct ndis_softc *sc; - - sc = arg; + status = IoCreateDevice(drv, sizeof(ndis_miniport_block), NULL, + FILE_DEVICE_UNKNOWN, 0, FALSE, &fdo); - /* - * Only perform the relocation/linking phase once - * since the binary image may be shared among multiple - * device instances. - */ - - ptr = (uint32_t *)(img + 8); - if (*ptr != NDIS_LOADED) { - /* Perform text relocation */ - if (pe_relocate(img)) - return(ENOEXEC); - - /* Dynamically link the NDIS.SYS routines -- required. */ - if (pe_patch_imports(img, "NDIS", ndis_functbl)) - return(ENOEXEC); - - /* Dynamically link the HAL.dll routines -- also required. */ - if (pe_patch_imports(img, "HAL", hal_functbl)) - return(ENOEXEC); - - /* Dynamically link ntoskrnl.exe -- optional. */ - if (pe_get_import_descriptor(img, - &imp_desc, "ntoskrnl") == 0) { - if (pe_patch_imports(img, - "ntoskrnl", ntoskrnl_functbl)) - return(ENOEXEC); - } - *ptr = NDIS_LOADED; - } + if (status != STATUS_SUCCESS) + return(status); - /* Locate the driver entry point */ - pe_get_optional_header(img, &opt_hdr); - entry = (driver_entry)pe_translate_addr(img, opt_hdr.ioh_entryaddr); - - dummystr.nus_len = strlen(NDIS_DUMMY_PATH) * 2; - dummystr.nus_maxlen = strlen(NDIS_DUMMY_PATH) * 2; - dummystr.nus_buf = NULL; - ndis_ascii_to_unicode(NDIS_DUMMY_PATH, &dummystr.nus_buf); + block = fdo->do_devext; + block->nmb_deviceobj = fdo; + block->nmb_physdeviceobj = pdo; + block->nmb_nextdeviceobj = IoAttachDeviceToDeviceStack(fdo, pdo); + KeInitializeSpinLock(&block->nmb_lock); /* - * Now that we have the miniport driver characteristics, - * create an NDIS block and call the init handler. - * This will cause the driver to try to probe for - * a device. - */ - - block = &sc->ndis_block; + * Stash pointers to the miniport block and miniport + * characteristics info in the if_ndis softc so the + * UNIX wrapper driver can get to them later. + */ - ptr = (uint32_t *)block; - for (idx = 0; idx < sizeof(ndis_miniport_block) / 4; idx++) { - *ptr = idx | 0xdead0000; - ptr++; - } + sc = device_get_softc(pdo->do_devext); + sc->ndis_block = block; + sc->ndis_chars = IoGetDriverObjectExtension(drv, (void *)1); + + /* Finish up BSD-specific setup. */ block->nmb_signature = (void *)0xcafebabe; block->nmb_setdone_func = ndis_setdone_func; @@ -1691,27 +1648,32 @@ ndis_load_driver(img, arg) block->nmb_resetdone_func = ndis_resetdone_func; block->nmb_sendrsrc_func = ndis_sendrsrcavail_func; - block->nmb_ifp = &sc->arpcom.ac_if; - block->nmb_dev = sc->ndis_dev; - block->nmb_img = img; - block->nmb_devobj.do_rsvd = block; + ndis_enlarge_thrqueue(8); - /* - * Now call the DriverEntry() routine. This will cause - * a callout to the NdisInitializeWrapper() and - * NdisMRegisterMiniport() routines. - */ - status = entry(&block->nmb_devobj, &dummystr); + TAILQ_INSERT_TAIL(&ndis_devhead, block, link); - free (dummystr.nus_buf, M_DEVBUF); + return (STATUS_SUCCESS); +} - if (status != NDIS_STATUS_SUCCESS) - return(ENODEV); +int +ndis_unload_driver(arg) + void *arg; +{ + struct ndis_softc *sc; + device_object *fdo; - ndis_enlarge_thrqueue(8); + sc = arg; - TAILQ_INSERT_TAIL(&ndis_devhead, block, link); - KeInitializeSpinLock(&block->nmb_lock); + free(sc->ndis_block->nmb_rlist, M_DEVBUF); + + ndis_flush_sysctls(sc); + + ndis_shrink_thrqueue(8); + TAILQ_REMOVE(&ndis_devhead, sc->ndis_block, link); + + fdo = sc->ndis_block->nmb_deviceobj; + IoDetachDevice(sc->ndis_block->nmb_nextdeviceobj); + IoDeleteDevice(fdo); return(0); } |