summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/compat/ndis/kern_ndis.c268
-rw-r--r--sys/compat/ndis/kern_windrv.c416
-rw-r--r--sys/compat/ndis/ndis_var.h15
-rw-r--r--sys/compat/ndis/ntoskrnl_var.h171
-rw-r--r--sys/compat/ndis/subr_hal.c25
-rw-r--r--sys/compat/ndis/subr_ndis.c204
-rw-r--r--sys/compat/ndis/subr_ntoskrnl.c588
-rw-r--r--sys/conf/files.i3861
-rw-r--r--sys/dev/if_ndis/if_ndis.c112
-rw-r--r--sys/dev/if_ndis/if_ndis_pccard.c17
-rw-r--r--sys/dev/if_ndis/if_ndis_pci.c22
-rw-r--r--sys/dev/if_ndis/if_ndisvar.h7
-rw-r--r--sys/modules/ndis/Makefile1
-rw-r--r--usr.sbin/ndiscvt/ndiscvt.c1
14 files changed, 1489 insertions, 359 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);
}
diff --git a/sys/compat/ndis/kern_windrv.c b/sys/compat/ndis/kern_windrv.c
new file mode 100644
index 0000000..f298b99
--- /dev/null
+++ b/sys/compat/ndis/kern_windrv.c
@@ -0,0 +1,416 @@
+/*-
+ * Copyright (c) 2005
+ * Bill Paul <wpaul@windriver.com>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/unistd.h>
+#include <sys/types.h>
+
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/module.h>
+#include <sys/conf.h>
+#include <sys/mbuf.h>
+#include <sys/bus.h>
+
+#include <sys/queue.h>
+
+#include <compat/ndis/pe_var.h>
+#include <compat/ndis/cfg_var.h>
+#include <compat/ndis/resource_var.h>
+#include <compat/ndis/ntoskrnl_var.h>
+#include <compat/ndis/ndis_var.h>
+#include <compat/ndis/hal_var.h>
+
+struct windrv_type {
+ uint16_t windrv_vid; /* for PCI or USB */
+ uint16_t windrv_did; /* for PCI or USB */
+ uint32_t windrv_subsys; /* for PCI */
+ char *windrv_vname; /* for pccard */
+ char *windrv_dname; /* for pccard */
+ char *windrv_name; /* for pccard, PCI or USB */
+};
+
+struct drvdb_ent {
+ driver_object *windrv_object;
+ struct windrv_type *windrv_devlist;
+ ndis_cfg *windrv_regvals;
+ STAILQ_ENTRY(drvdb_ent) link;
+};
+
+struct mtx drvdb_mtx;
+static STAILQ_HEAD(drvdb, drvdb_ent) drvdb_head;
+
+static driver_object fake_pci_driver; /* serves both PCI and cardbus */
+static driver_object fake_pccard_driver;
+
+
+#define DUMMY_REGISTRY_PATH "\\\\some\\bogus\\path"
+
+int
+windrv_libinit(void)
+{
+ STAILQ_INIT(&drvdb_head);
+ mtx_init(&drvdb_mtx, "Windows driver DB lock",
+ "Windows internal lock", MTX_DEF);
+
+ /*
+ * PCI and pccard devices don't need to use IRPs to
+ * interact with their bus drivers (usually), so our
+ * emulated PCI and pccard drivers are just stubs.
+ * USB devices, on the other hand, do all their I/O
+ * by exchanging IRPs with the USB bus driver, so
+ * for that we need to provide emulator dispatcher
+ * routines, which are in a separate module.
+ */
+
+ windrv_bus_attach(&fake_pci_driver, "PCI Bus");
+ windrv_bus_attach(&fake_pccard_driver, "PCCARD Bus");
+
+ return(0);
+}
+
+int
+windrv_libfini(void)
+{
+ struct drvdb_ent *d;
+
+ mtx_lock(&drvdb_mtx);
+ while(STAILQ_FIRST(&drvdb_head) != NULL) {
+ d = STAILQ_FIRST(&drvdb_head);
+ STAILQ_REMOVE_HEAD(&drvdb_head, link);
+ free(d, M_DEVBUF);
+ }
+ mtx_unlock(&drvdb_mtx);
+
+ free(fake_pci_driver.dro_drivername.us_buf, M_DEVBUF);
+ free(fake_pccard_driver.dro_drivername.us_buf, M_DEVBUF);
+
+ mtx_destroy(&drvdb_mtx);
+ return(0);
+}
+
+/*
+ * Given the address of a driver image, find its corresponding
+ * driver_object.
+ */
+
+driver_object *
+windrv_lookup(img)
+ vm_offset_t img;
+{
+ struct drvdb_ent *d;
+
+ mtx_lock(&drvdb_mtx);
+ STAILQ_FOREACH(d, &drvdb_head, link) {
+ if (d->windrv_object->dro_driverstart == (void *)img) {
+ mtx_unlock(&drvdb_mtx);
+ return(d->windrv_object);
+ }
+ }
+ mtx_unlock(&drvdb_mtx);
+
+ return(NULL);
+}
+
+/*
+ * Remove a driver_object from our datatabase and destroy it. Throw
+ * away any custom driver extension info that may have been added.
+ */
+
+int
+windrv_unload(mod, img, len)
+ module_t mod;
+ vm_offset_t img;
+ int len;
+{
+ struct drvdb_ent *d, *r = NULL;
+ driver_object *drv;
+ list_entry *e, *c;
+
+ mtx_lock(&drvdb_mtx);
+ STAILQ_FOREACH(d, &drvdb_head, link) {
+ if (d->windrv_object->dro_driverstart == (void *)img) {
+ r = d;
+ STAILQ_REMOVE(&drvdb_head, d, drvdb_ent, link);
+ break;
+ }
+ }
+ mtx_unlock(&drvdb_mtx);
+
+ if (r == NULL)
+ return (ENOENT);
+
+ /*
+ * Destroy any custom extensions that may have been added.
+ */
+ drv = r->windrv_object;
+ e = drv->dro_driverext->dre_usrext.nle_flink;
+ while (e != &drv->dro_driverext->dre_usrext) {
+ c = e->nle_flink;
+ REMOVE_LIST_HEAD((&drv->dro_driverext->dre_usrext));
+ ExFreePool(c);
+ e = e->nle_flink;
+ }
+
+ /* Free the driver extension */
+ free(drv->dro_driverext, M_DEVBUF);
+
+ /* Free the driver name */
+ free(drv->dro_drivername.us_buf, M_DEVBUF);
+
+ /* Free driver object */
+ free(drv, M_DEVBUF);
+
+ /* Free our DB handle */
+ free(r, M_DEVBUF);
+
+ return(0);
+}
+
+/*
+ * Loader routine for actual Windows driver modules, ultimately
+ * calls the driver's DriverEntry() routine.
+ */
+
+int
+windrv_load(mod, img, len)
+ module_t mod;
+ vm_offset_t img;
+ int len;
+{
+ image_import_descriptor imp_desc;
+ image_optional_header opt_hdr;
+ driver_entry entry;
+ struct drvdb_ent *new;
+ struct driver_object *dobj;
+ int status;
+
+ /*
+ * First step: try to relocate and dynalink the executable
+ * driver image.
+ */
+
+ /* 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);
+ }
+
+ /* Dynamically link USBD.SYS -- optional */
+#ifdef notyet
+ if (pe_get_import_descriptor(img, &imp_desc, "USBD") == 0) {
+ if (pe_patch_imports(img, "USBD", ntoskrnl_functbl))
+ return(ENOEXEC);
+ }
+#endif
+
+ /* Next step: find the driver entry point. */
+
+ pe_get_optional_header(img, &opt_hdr);
+ entry = (driver_entry)pe_translate_addr(img, opt_hdr.ioh_entryaddr);
+
+ /* Next step: allocate and store a driver object. */
+
+ new = malloc(sizeof(struct drvdb_ent), M_DEVBUF, M_NOWAIT);
+ if (new == NULL)
+ return (ENOMEM);
+
+ dobj = malloc(sizeof(device_object), M_DEVBUF, M_NOWAIT|M_ZERO);
+ if (dobj == NULL) {
+ free (new, M_DEVBUF);
+ return (ENOMEM);
+ }
+
+ /* Allocate a driver extension structure too. */
+
+ dobj->dro_driverext = malloc(sizeof(driver_extension),
+ M_DEVBUF, M_NOWAIT|M_ZERO);
+
+ if (dobj->dro_driverext == NULL) {
+ free(new, M_DEVBUF);
+ free(dobj, M_DEVBUF);
+ return(ENOMEM);
+ }
+
+ INIT_LIST_HEAD((&dobj->dro_driverext->dre_usrext));
+
+ dobj->dro_driverstart = (void *)img;
+ dobj->dro_driversize = len;
+
+ dobj->dro_drivername.us_len = strlen(DUMMY_REGISTRY_PATH) * 2;
+ dobj->dro_drivername.us_maxlen = strlen(DUMMY_REGISTRY_PATH) * 2;
+ dobj->dro_drivername.us_buf = NULL;
+ ndis_ascii_to_unicode(DUMMY_REGISTRY_PATH,
+ &dobj->dro_drivername.us_buf);
+
+ new->windrv_object = dobj;
+
+ /* Now call the DriverEntry() function. */
+
+ status = entry(dobj, &dobj->dro_drivername);
+
+ if (status != STATUS_SUCCESS) {
+ free(dobj->dro_drivername.us_buf, M_DEVBUF);
+ free(dobj, M_DEVBUF);
+ free(new, M_DEVBUF);
+ return(ENODEV);
+ }
+
+ mtx_lock(&drvdb_mtx);
+ STAILQ_INSERT_HEAD(&drvdb_head, new, link);
+ mtx_unlock(&drvdb_mtx);
+
+ return (0);
+}
+
+/*
+ * Make a new Physical Device Object for a device that was
+ * detected/plugged in. For us, the PDO is just a way to
+ * get at the device_t.
+ */
+
+int
+windrv_create_pdo(drv, bsddev)
+ driver_object *drv;
+ device_t bsddev;
+{
+ device_object *dev;
+
+ /*
+ * This is a new physical device object, which technically
+ * is the "top of the stack." Consequently, we don't do
+ * an IoAttachDeviceToDeviceStack() here.
+ */
+
+ mtx_lock(&drvdb_mtx);
+ IoCreateDevice(drv, 0, NULL, FILE_DEVICE_UNKNOWN, 0, FALSE, &dev);
+ mtx_unlock(&drvdb_mtx);
+
+ /* Stash pointer to our BSD device handle. */
+
+ dev->do_devext = bsddev;
+
+ return(STATUS_SUCCESS);
+}
+
+void
+windrv_destroy_pdo(drv, bsddev)
+ driver_object *drv;
+ device_t bsddev;
+{
+ device_object *pdo;
+
+ pdo = windrv_find_pdo(drv, bsddev);
+
+ /* Remove reference to device_t */
+
+ pdo->do_devext = NULL;
+
+ mtx_lock(&drvdb_mtx);
+ IoDeleteDevice(pdo);
+ mtx_unlock(&drvdb_mtx);
+
+ return;
+}
+
+/*
+ * Given a device_t, find the corresponding PDO in a driver's
+ * device list.
+ */
+
+device_object *
+windrv_find_pdo(drv, bsddev)
+ driver_object *drv;
+ device_t bsddev;
+{
+ device_object *pdo;
+
+ mtx_lock(&drvdb_mtx);
+ pdo = drv->dro_devobj;
+ if (pdo->do_devext != bsddev) {
+ mtx_unlock(&drvdb_mtx);
+ panic("PDO wasn't first device in list");
+ }
+ mtx_unlock(&drvdb_mtx);
+
+ return(pdo);
+}
+
+/*
+ * Add an internally emulated driver to the database. We need this
+ * to set up an emulated bus driver so that it can receive IRPs.
+ */
+
+int
+windrv_bus_attach(drv, name)
+ driver_object *drv;
+ char *name;
+{
+ struct drvdb_ent *new;
+
+ new = malloc(sizeof(struct drvdb_ent), M_DEVBUF, M_NOWAIT);
+ if (new == NULL)
+ return (ENOMEM);
+
+ drv->dro_drivername.us_len = strlen(name) * 2;
+ drv->dro_drivername.us_maxlen = strlen(name) * 2;
+ drv->dro_drivername.us_buf = NULL;
+ ndis_ascii_to_unicode(name, &drv->dro_drivername.us_buf);
+
+ new->windrv_object = drv;
+ new->windrv_devlist = NULL;
+ new->windrv_regvals = NULL;
+
+ mtx_lock(&drvdb_mtx);
+ STAILQ_INSERT_HEAD(&drvdb_head, new, link);
+ mtx_unlock(&drvdb_mtx);
+
+ return(0);
+}
diff --git a/sys/compat/ndis/ndis_var.h b/sys/compat/ndis/ndis_var.h
index 8761abb..b4eaf5a 100644
--- a/sys/compat/ndis/ndis_var.h
+++ b/sys/compat/ndis/ndis_var.h
@@ -751,6 +751,7 @@ struct ndis_ansi_string {
typedef struct ndis_ansi_string ndis_ansi_string;
+#ifdef notdef
/*
* nus_buf is really a wchar_t *, but it's inconvenient to include
* all the necessary header goop needed to define it, and it's a
@@ -761,9 +762,10 @@ struct ndis_unicode_string {
uint16_t nus_maxlen;
uint16_t *nus_buf;
};
-
typedef struct ndis_unicode_string ndis_unicode_string;
+#endif
+typedef unicode_string ndis_unicode_string;
enum ndis_parm_type {
ndis_parm_int,
@@ -1398,11 +1400,11 @@ struct ndis_miniport_block {
void *nmb_resetdone_func;
ndis_medium nmb_medium;
uint32_t nmb_busnum;
- uint32_t nmb_bustye;
+ uint32_t nmb_bustype;
uint32_t nmb_adaptertype;
- void *nmb_deviceobj;
- void *nmb_physdeviceobj;
- void *nmb_nextdeviceobj;
+ device_object *nmb_deviceobj; /* Functional device */
+ device_object *nmb_physdeviceobj; /* Physical device */
+ device_object *nmb_nextdeviceobj; /* Next dev in stack */
void *nmb_mapreg;
void *nmb_callmgraflist;
void *nmb_miniportthread;
@@ -1480,7 +1482,7 @@ typedef void (*ndis_allocdone_handler)(ndis_handle, void *,
ndis_physaddr *, uint32_t, void *);
typedef uint8_t (*ndis_checkforhang_handler)(ndis_handle);
-typedef __stdcall ndis_status (*driver_entry)(void *, ndis_unicode_string *);
+typedef __stdcall ndis_status (*driver_entry)(void *, unicode_string *);
extern image_patch_table ndis_functbl[];
@@ -1529,6 +1531,7 @@ extern int ndis_thsuspend(struct proc *, int);
extern void ndis_thresume(struct proc *);
extern int ndis_strcasecmp(const char *, const char *);
extern int ndis_strncasecmp(const char *, const char *, size_t);
+__stdcall extern uint32_t NdisAddDevice(driver_object *, device_object *);
__END_DECLS
#endif /* _NDIS_VAR_H_ */
diff --git a/sys/compat/ndis/ntoskrnl_var.h b/sys/compat/ndis/ntoskrnl_var.h
index bc1f5f3..f1c0766 100644
--- a/sys/compat/ndis/ntoskrnl_var.h
+++ b/sys/compat/ndis/ntoskrnl_var.h
@@ -194,7 +194,7 @@ struct list_entry {
typedef struct list_entry list_entry;
#define INIT_LIST_HEAD(l) \
- l->nle_flink = l->nle_blink = l
+ (l)->nle_flink = (l)->nle_blink = (l)
#define REMOVE_LIST_ENTRY(e) \
do { \
@@ -236,8 +236,8 @@ typedef struct list_entry list_entry;
b = l->nle_blink; \
e->nle_flink = l; \
e->nle_blink = b; \
- b->nle_flink = e; \
- l->nle_blink = e; \
+ b->nle_flink = (e); \
+ l->nle_blink = (e); \
} while (0)
#define INSERT_LIST_HEAD(l, e) \
@@ -498,10 +498,25 @@ struct driver_extension {
void *dre_adddevicefunc;
uint32_t dre_reinitcnt;
unicode_string dre_srvname;
+
+ /*
+ * Drivers are allowed to add one or more custom extensions
+ * to the driver object, but there's no special pointer
+ * for them. Hang them off here for now.
+ */
+
+ list_entry dre_usrext;
};
typedef struct driver_extension driver_extension;
+struct custom_extension {
+ list_entry ce_list;
+ void *ce_clid;
+};
+
+typedef struct custom_extension custom_extension;
+
/*
* In Windows, there are Physical Device Objects (PDOs) and
* Functional Device Objects (FDOs). Physical Device Objects are
@@ -522,7 +537,7 @@ struct device_object {
uint16_t do_type;
uint16_t do_size;
uint32_t do_refcnt;
- struct device_object *do_drvobj;
+ struct driver_object *do_drvobj;
struct device_object *do_nextdev;
struct device_object *do_attacheddev;
struct irp *do_currirp;
@@ -531,6 +546,7 @@ struct device_object {
uint32_t do_characteristics;
void *do_vpb;
void *do_devext;
+ uint32_t do_devtype;
uint8_t do_stacksize;
union {
list_entry do_listent;
@@ -714,6 +730,8 @@ struct io_status_block {
} u;
register_t isb_info;
};
+#define isb_status u.isb_status
+#define isb_ptr u.isb_ptr
typedef struct io_status_block io_status_block;
@@ -736,6 +754,9 @@ struct kapc {
typedef struct kapc kapc;
+typedef __stdcall uint32_t (*completion_func)(device_object *,
+ struct irp *, void *);
+
struct io_stack_location {
uint8_t isl_major;
uint8_t isl_minor;
@@ -763,7 +784,7 @@ struct io_stack_location {
void *isl_devobj;
void *isl_fileobj;
- void *isl_completionfunc;
+ completion_func isl_completionfunc;
void *isl_completionctx;
};
@@ -797,7 +818,7 @@ struct irp {
uint8_t irp_apcenv;
uint8_t irp_allocflags;
io_status_block *irp_usriostat;
- nt_kevent irp_userevent;
+ nt_kevent *irp_usrevent;
union {
struct {
void *irp_apcfunc;
@@ -839,12 +860,22 @@ struct irp {
typedef struct irp irp;
+#define IoSizeOfIrp(ssize) \
+ ((uint16_t) (sizeof(irp) + ((ssize) * (sizeof(io_stack_location)))))
+
+
#define IoGetCurrentIrpStackLocation(irp) \
(irp)->irp_tail.irp_overlay.irp_csl
#define IoGetNextIrpStackLocation(irp) \
((irp)->irp_tail.irp_overlay.irp_csl - 1)
+#define IoSetNextIrpStackLocation(irp) \
+ do { \
+ irp->irp_currentstackloc--; \
+ irp->irp_tail.irp_overlay.irp_csl--; \
+ } while(0)
+
#define IoSetCompletionRoutine(irp, func, ctx, ok, err, cancel) \
do { \
io_stack_location *s; \
@@ -852,17 +883,14 @@ typedef struct irp irp;
s->isl_completionfunc = (func); \
s->isl_completionctx = (ctx); \
s->isl_ctl = 0; \
- if (ok) irp->ctl = SL_INVOKE_ON_SUCCESS; \
- if (err) irp->ctl |= SL_INVOKE_ON_ERROR; \
- if (cancel) irp->ctl |= SL_INVOKE_ON_CANCEL; \
+ if (ok) s->isl_ctl = SL_INVOKE_ON_SUCCESS; \
+ if (err) s->isl_ctl |= SL_INVOKE_ON_ERROR; \
+ if (cancel) s->isl_ctl |= SL_INVOKE_ON_CANCEL; \
} while(0)
#define IoMarkIrpPending(irp) \
IoGetCurrentIrpStackLocation(irp)->isl_ctl |= SL_PENDING_RETURNED
-#define IoSizeOfIrp(s) \
- ((uint16_t) (sizeof(itp) + ((s) * (sizeof(io_stack_location)))))
-
#define IoCopyCurrentIrpStackLocationToNext(irp) \
do { \
io_stack_location *src, *dst; \
@@ -878,7 +906,7 @@ typedef struct irp irp;
(irp)->irp_tail.irp_overlay.irp_csl++; \
} while(0)
-typedef uint32_t (*driver_dispatch)(device_object *, irp *);
+typedef __stdcall uint32_t (*driver_dispatch)(device_object *, irp *);
/*
* The driver_object is allocated once for each driver that's loaded
@@ -898,14 +926,14 @@ struct driver_object {
void *dro_driverstart;
uint32_t dro_driversize;
void *dro_driversection;
- driver_extension dro_driverext;
+ driver_extension *dro_driverext;
unicode_string dro_drivername;
unicode_string *dro_hwdb;
void *dro_pfastiodispatch;
void *dro_driverinitfunc;
void *dro_driverstartiofunc;
void *dro_driverunloadfunc;
- void *dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1];
+ driver_dispatch dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1];
};
typedef struct driver_object driver_object;
@@ -931,6 +959,81 @@ typedef struct driver_object driver_object;
#define DEVPROP_INSTALL_STATE 0x00000012
#define DEVPROP_REMOVAL_POLICY 0x00000013
+/* Various supported device types (used with IoCreateDevice()) */
+
+#define FILE_DEVICE_BEEP 0x00000001
+#define FILE_DEVICE_CD_ROM 0x00000002
+#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
+#define FILE_DEVICE_CONTROLLER 0x00000004
+#define FILE_DEVICE_DATALINK 0x00000005
+#define FILE_DEVICE_DFS 0x00000006
+#define FILE_DEVICE_DISK 0x00000007
+#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
+#define FILE_DEVICE_FILE_SYSTEM 0x00000009
+#define FILE_DEVICE_INPORT_PORT 0x0000000A
+#define FILE_DEVICE_KEYBOARD 0x0000000B
+#define FILE_DEVICE_MAILSLOT 0x0000000C
+#define FILE_DEVICE_MIDI_IN 0x0000000D
+#define FILE_DEVICE_MIDI_OUT 0x0000000E
+#define FILE_DEVICE_MOUSE 0x0000000F
+#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010
+#define FILE_DEVICE_NAMED_PIPE 0x00000011
+#define FILE_DEVICE_NETWORK 0x00000012
+#define FILE_DEVICE_NETWORK_BROWSER 0x00000013
+#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
+#define FILE_DEVICE_NULL 0x00000015
+#define FILE_DEVICE_PARALLEL_PORT 0x00000016
+#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017
+#define FILE_DEVICE_PRINTER 0x00000018
+#define FILE_DEVICE_SCANNER 0x00000019
+#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001A
+#define FILE_DEVICE_SERIAL_PORT 0x0000001B
+#define FILE_DEVICE_SCREEN 0x0000001C
+#define FILE_DEVICE_SOUND 0x0000001D
+#define FILE_DEVICE_STREAMS 0x0000001E
+#define FILE_DEVICE_TAPE 0x0000001F
+#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
+#define FILE_DEVICE_TRANSPORT 0x00000021
+#define FILE_DEVICE_UNKNOWN 0x00000022
+#define FILE_DEVICE_VIDEO 0x00000023
+#define FILE_DEVICE_VIRTUAL_DISK 0x00000024
+#define FILE_DEVICE_WAVE_IN 0x00000025
+#define FILE_DEVICE_WAVE_OUT 0x00000026
+#define FILE_DEVICE_8042_PORT 0x00000027
+#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
+#define FILE_DEVICE_BATTERY 0x00000029
+#define FILE_DEVICE_BUS_EXTENDER 0x0000002A
+#define FILE_DEVICE_MODEM 0x0000002B
+#define FILE_DEVICE_VDM 0x0000002C
+#define FILE_DEVICE_MASS_STORAGE 0x0000002D
+#define FILE_DEVICE_SMB 0x0000002E
+#define FILE_DEVICE_KS 0x0000002F
+#define FILE_DEVICE_CHANGER 0x00000030
+#define FILE_DEVICE_SMARTCARD 0x00000031
+#define FILE_DEVICE_ACPI 0x00000032
+#define FILE_DEVICE_DVD 0x00000033
+#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034
+#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035
+#define FILE_DEVICE_DFS_VOLUME 0x00000036
+#define FILE_DEVICE_SERENUM 0x00000037
+#define FILE_DEVICE_TERMSRV 0x00000038
+#define FILE_DEVICE_KSEC 0x00000039
+#define FILE_DEVICE_FIPS 0x0000003A
+
+/* Device characteristics */
+
+#define FILE_REMOVABLE_MEDIA 0x00000001
+#define FILE_READ_ONLY_DEVICE 0x00000002
+#define FILE_FLOPPY_DISKETTE 0x00000004
+#define FILE_WRITE_ONCE_MEDIA 0x00000008
+#define FILE_REMOTE_DEVICE 0x00000010
+#define FILE_DEVICE_IS_MOUNTED 0x00000020
+#define FILE_VIRTUAL_VOLUME 0x00000040
+#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080
+#define FILE_DEVICE_SECURE_OPEN 0x00000100
+
+/* Status codes */
+
#define STATUS_SUCCESS 0x00000000
#define STATUS_USER_APC 0x000000C0
#define STATUS_KERNEL_APC 0x00000100
@@ -938,12 +1041,25 @@ typedef struct driver_object driver_object;
#define STATUS_TIMEOUT 0x00000102
#define STATUS_INVALID_PARAMETER 0xC000000D
#define STATUS_INVALID_DEVICE_REQUEST 0xC0000010
+#define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016
#define STATUS_BUFFER_TOO_SMALL 0xC0000023
#define STATUS_MUTANT_NOT_OWNED 0xC0000046
#define STATUS_INVALID_PARAMETER_2 0xC00000F0
+#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A
#define STATUS_WAIT_0 0x00000000
+/* Memory pool types, for ExAllocatePoolWithTag() */
+
+#define NonPagedPool 0x00000000
+#define PagedPool 0x00000001
+#define NonPagedPoolMustSucceed 0x00000002
+#define DontUseThisType 0x00000003
+#define NonPagedPoolCacheAligned 0x00000004
+#define PagedPoolCacheAligned 0x00000005
+#define NonPagedPoolCacheAlignedMustS 0x00000006
+#define MaxPoolType 0x00000007
+
/*
* FreeBSD's kernel stack is 2 pages in size by default. The
* Windows stack is larger, so we need to give our threads more
@@ -954,6 +1070,16 @@ typedef struct driver_object driver_object;
extern image_patch_table ntoskrnl_functbl[];
__BEGIN_DECLS
+extern int windrv_libinit(void);
+extern int windrv_libfini(void);
+extern driver_object *windrv_lookup(vm_offset_t);
+extern int windrv_load(module_t, vm_offset_t, int);
+extern int windrv_unload(module_t, vm_offset_t, int);
+extern int windrv_create_pdo(driver_object *, device_t);
+extern void windrv_destroy_pdo(driver_object *, device_t);
+extern device_object *windrv_find_pdo(driver_object *, device_t);
+extern int windrv_bus_attach(driver_object *, char *);
+
extern int ntoskrnl_libinit(void);
extern int ntoskrnl_libfini(void);
__stdcall extern void KeInitializeDpc(kdpc *, void *, void *);
@@ -962,8 +1088,7 @@ __stdcall extern uint8_t KeRemoveQueueDpc(kdpc *);
__stdcall extern void KeInitializeTimer(ktimer *);
__stdcall extern void KeInitializeTimerEx(ktimer *, uint32_t);
__stdcall extern uint8_t KeSetTimer(ktimer *, int64_t, kdpc *);
-__stdcall extern uint8_t KeSetTimerEx(ktimer *, int64_t,
- uint32_t, kdpc *);
+__stdcall extern uint8_t KeSetTimerEx(ktimer *, int64_t, uint32_t, kdpc *);
__stdcall extern uint8_t KeCancelTimer(ktimer *);
__stdcall extern uint8_t KeReadStateTimer(ktimer *);
__stdcall extern uint32_t KeWaitForSingleObject(nt_dispatch_header *, uint32_t,
@@ -976,8 +1101,20 @@ __stdcall extern uint32_t KeResetEvent(nt_kevent *);
__fastcall extern void KefAcquireSpinLockAtDpcLevel(REGARGS1(kspin_lock *));
__fastcall extern void KefReleaseSpinLockFromDpcLevel(REGARGS1(kspin_lock *));
__stdcall extern void KeInitializeSpinLock(kspin_lock *);
+__stdcall extern void *ExAllocatePoolWithTag(uint32_t, size_t, uint32_t);
+__stdcall extern void ExFreePool(void *);
+__stdcall extern uint32_t IoAllocateDriverObjectExtension(driver_object *,
+ void *, uint32_t, void **);
+__stdcall extern void *IoGetDriverObjectExtension(driver_object *, void *);
+__stdcall extern uint32_t IoCreateDevice(driver_object *, uint32_t,
+ unicode_string *, uint32_t, uint32_t, uint8_t, device_object **);
+__stdcall extern void IoDeleteDevice(device_object *);
+__stdcall extern device_object *IoGetAttachedDevice(device_object *);
__fastcall extern uint32_t IofCallDriver(REGARGS2(device_object *, irp *));
__fastcall extern void IofCompleteRequest(REGARGS2(irp *, uint8_t));
+__stdcall extern void IoDetachDevice(device_object *);
+__stdcall extern device_object *IoAttachDeviceToDeviceStack(device_object *,
+ device_object *);
#define IoCallDriver(a, b) FASTCALL2(IofCallDriver, a, b)
#define IoCompleteRequest(a, b) FASTCALL2(IofCompleteRequest, a, b)
diff --git a/sys/compat/ndis/subr_hal.c b/sys/compat/ndis/subr_hal.c
index 81dcade..b72613c 100644
--- a/sys/compat/ndis/subr_hal.c
+++ b/sys/compat/ndis/subr_hal.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/sched.h>
+#include <sys/module.h>
#include <sys/systm.h>
#include <machine/clock.h>
@@ -223,13 +224,19 @@ READ_PORT_BUFFER_UCHAR(port, val, cnt)
* until the current thread lowers the IRQL to something less than
* DISPATCH_LEVEL.
*
- * In FreeBSD, ISRs run in interrupt threads, so to duplicate the
- * Windows notion of IRQLs, we use the following rules:
+ * There's another commonly used IRQL in Windows, which is APC_LEVEL.
+ * An APC is an Asynchronous Procedure Call, which differs from a DPC
+ * (Defered Procedure Call) in that a DPC is queued up to run in
+ * another thread, while an APC runs in the thread that scheduled
+ * it (similar to a signal handler in a UNIX process). We don't
+ * actually support the notion of APCs in FreeBSD, so for now, the
+ * only IRQLs we're interested in are DISPATCH_LEVEL and PASSIVE_LEVEL.
*
- * PASSIVE_LEVEL == normal kernel thread priority
- * DISPATCH_LEVEL == lowest interrupt thread priotity (PI_SOFT)
- * DEVICE_LEVEL == highest interrupt thread priority (PI_REALTIME)
- * HIGH_LEVEL == interrupts disabled (critical_enter())
+ * To simulate DISPATCH_LEVEL, we raise the current thread's priority
+ * to PI_REALTIME, which is the highest we can give it. This should,
+ * if I understand things correctly, prevent anything except for an
+ * interrupt thread from preempting us. PASSIVE_LEVEL is basically
+ * everything else.
*
* Be aware that, at least on the x86 arch, the Windows spinlock
* functions are divided up in peculiar ways. The actual spinlock
@@ -306,6 +313,9 @@ KfRaiseIrql(REGARGS1(uint8_t irql))
mtx_lock_spin(&sched_lock);
oldirql = curthread->td_base_pri;
sched_prio(curthread, PI_REALTIME);
+#if __FreeBSD_version < 600000
+ curthread->td_base_pri = PI_REALTIME;
+#endif
mtx_unlock_spin(&sched_lock);
return(oldirql);
@@ -321,6 +331,9 @@ KfLowerIrql(REGARGS1(uint8_t oldirql))
panic("IRQL_NOT_GREATER_THAN");
mtx_lock_spin(&sched_lock);
+#if __FreeBSD_version < 600000
+ curthread->td_base_pri = oldirql;
+#endif
sched_prio(curthread, oldirql);
mtx_unlock_spin(&sched_lock);
diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c
index b7267d5..f5b5972 100644
--- a/sys/compat/ndis/subr_ndis.c
+++ b/sys/compat/ndis/subr_ndis.c
@@ -113,7 +113,7 @@ SYSCTL_STRING(_hw, OID_AUTO, ndis_filepath, CTLFLAG_RW, ndis_filepath,
MAXPATHLEN, "Path used by NdisOpenFile() to search for files");
__stdcall static void NdisInitializeWrapper(ndis_handle *,
- device_object *, void *, void *);
+ driver_object *, void *, void *);
__stdcall static ndis_status NdisMRegisterMiniport(ndis_handle,
ndis_miniport_characteristics *, int);
__stdcall static ndis_status NdisAllocateMemoryWithTag(void **,
@@ -367,17 +367,39 @@ ndis_unicode_to_ascii(unicode, ulen, ascii)
return(0);
}
+/*
+ * This routine does the messy Windows Driver Model device attachment
+ * stuff on behalf of NDIS drivers. We register our own AddDevice
+ * routine here
+ */
__stdcall static void
-NdisInitializeWrapper(wrapper, drv_obj, path, unused)
+NdisInitializeWrapper(wrapper, drv, path, unused)
ndis_handle *wrapper;
- device_object *drv_obj;
+ driver_object *drv;
void *path;
void *unused;
{
- ndis_miniport_block *block;
+ /*
+ * As of yet, I haven't come up with a compelling
+ * reason to define a private NDIS wrapper structure,
+ * so we use a pointer to the driver object as the
+ * wrapper handle. The driver object has the miniport
+ * characteristics struct for this driver hung off it
+ * via IoAllocateDriverObjectExtension(), and that's
+ * really all the private data we need.
+ */
- block = drv_obj->do_rsvd;
- *wrapper = block;
+ *wrapper = drv;
+
+ /*
+ * If this was really Windows, we'd be registering dispatch
+ * routines for the NDIS miniport module here, but we're
+ * not Windows so all we really need to do is set up an
+ * AddDevice function that'll be invoked when a new device
+ * instance appears.
+ */
+
+ drv->dro_driverext->dre_adddevicefunc = NdisAddDevice;
return;
}
@@ -387,6 +409,7 @@ NdisTerminateWrapper(handle, syspec)
ndis_handle handle;
void *syspec;
{
+ /* Nothing to see here, move along. */
return;
}
@@ -396,18 +419,34 @@ NdisMRegisterMiniport(handle, characteristics, len)
ndis_miniport_characteristics *characteristics;
int len;
{
- ndis_miniport_block *block;
- struct ndis_softc *sc;
+ ndis_miniport_characteristics *ch = NULL;
+ driver_object *drv;
- block = (ndis_miniport_block *)handle;
- sc = (struct ndis_softc *)block->nmb_ifp;
- bcopy((char *)characteristics, (char *)&sc->ndis_chars,
- sizeof(ndis_miniport_characteristics));
- if (sc->ndis_chars.nmc_version_major < 5 ||
- sc->ndis_chars.nmc_version_minor < 1) {
- sc->ndis_chars.nmc_shutdown_handler = NULL;
- sc->ndis_chars.nmc_canceltxpkts_handler = NULL;
- sc->ndis_chars.nmc_pnpevent_handler = NULL;
+ drv = (driver_object *)handle;
+
+ /*
+ * We need to save the NDIS miniport characteristics
+ * somewhere. This data is per-driver, not per-device
+ * (all devices handled by the same driver have the
+ * same characteristics) so we hook it onto the driver
+ * object using IoAllocateDriverObjectExtension().
+ * The extra extension info is automagically deleted when
+ * the driver is unloaded (see windrv_unload()).
+ */
+
+ if (IoAllocateDriverObjectExtension(drv, (void *)1,
+ sizeof(ndis_miniport_characteristics), (void **)&ch) !=
+ STATUS_SUCCESS)
+ return(NDIS_STATUS_RESOURCES);
+
+ bzero((char *)ch, sizeof(ndis_miniport_characteristics));
+
+ bcopy((char *)characteristics, (char *)ch, len);
+
+ if (ch->nmc_version_major < 5 || ch->nmc_version_minor < 1) {
+ ch->nmc_shutdown_handler = NULL;
+ ch->nmc_canceltxpkts_handler = NULL;
+ ch->nmc_pnpevent_handler = NULL;
}
return(NDIS_STATUS_SUCCESS);
@@ -421,7 +460,7 @@ NdisAllocateMemoryWithTag(vaddr, len, tag)
{
void *mem;
- mem = malloc(len, M_DEVBUF, M_NOWAIT);
+ mem = ExAllocatePoolWithTag(NonPagedPool, len, tag);
if (mem == NULL)
return(NDIS_STATUS_RESOURCES);
*vaddr = mem;
@@ -438,7 +477,7 @@ NdisAllocateMemory(vaddr, len, flags, highaddr)
{
void *mem;
- mem = malloc(len, M_DEVBUF, M_NOWAIT);
+ mem = ExAllocatePoolWithTag(NonPagedPool, len, 0);
if (mem == NULL)
return(NDIS_STATUS_RESOURCES);
*vaddr = mem;
@@ -454,7 +493,8 @@ NdisFreeMemory(vaddr, len, flags)
{
if (len == 0)
return;
- free(vaddr, M_DEVBUF);
+
+ ExFreePool(vaddr);
return;
}
@@ -490,6 +530,7 @@ NdisOpenConfiguration(status, cfg, wrapctx)
{
*cfg = wrapctx;
*status = NDIS_STATUS_SUCCESS;
+
return;
}
@@ -535,8 +576,8 @@ ndis_encode_parm(block, oid, type, parm)
ndis_ascii_to_unicode((char *)oid->oid_arg1, &unicode);
(*parm)->ncp_type = ndis_parm_string;
ustr = &(*parm)->ncp_parmdata.ncp_stringdata;
- ustr->nus_len = strlen((char *)oid->oid_arg1) * 2;
- ustr->nus_buf = unicode;
+ ustr->us_len = strlen((char *)oid->oid_arg1) * 2;
+ ustr->us_buf = unicode;
break;
case ndis_parm_int:
if (strncmp((char *)oid->oid_arg1, "0x", 2) == 0)
@@ -627,14 +668,14 @@ NdisReadConfiguration(status, parm, cfg, key, type)
struct sysctl_ctx_entry *e;
block = (ndis_miniport_block *)cfg;
- sc = (struct ndis_softc *)block->nmb_ifp;
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
- if (key->nus_len == 0 || key->nus_buf == NULL) {
+ if (key->us_len == 0 || key->us_buf == NULL) {
*status = NDIS_STATUS_FAILURE;
return;
}
- ndis_unicode_to_ascii(key->nus_buf, key->nus_len, &keystr);
+ ndis_unicode_to_ascii(key->us_buf, key->us_len, &keystr);
*parm = &block->nmb_replyparm;
bzero((char *)&block->nmb_replyparm, sizeof(ndis_config_parm));
@@ -698,7 +739,7 @@ ndis_decode_parm(block, parm, val)
switch(parm->ncp_type) {
case ndis_parm_string:
ustr = &parm->ncp_parmdata.ncp_stringdata;
- ndis_unicode_to_ascii(ustr->nus_buf, ustr->nus_len, &astr);
+ ndis_unicode_to_ascii(ustr->us_buf, ustr->us_len, &astr);
bcopy(astr, val, 254);
free(astr, M_DEVBUF);
break;
@@ -730,9 +771,9 @@ NdisWriteConfiguration(status, cfg, key, parm)
char val[256];
block = (ndis_miniport_block *)cfg;
- sc = (struct ndis_softc *)block->nmb_ifp;
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
- ndis_unicode_to_ascii(key->nus_buf, key->nus_len, &keystr);
+ ndis_unicode_to_ascii(key->us_buf, key->us_len, &keystr);
/* Decode the parameter into a string. */
bzero(val, sizeof(val));
@@ -863,14 +904,16 @@ NdisReadPciSlotInformation(adapter, slot, offset, buf, len)
ndis_miniport_block *block;
int i;
char *dest;
+ device_t dev;
block = (ndis_miniport_block *)adapter;
dest = buf;
- if (block == NULL || block->nmb_dev == NULL)
+ if (block == NULL)
return(0);
+ dev = block->nmb_physdeviceobj->do_devext;
for (i = 0; i < len; i++)
- dest[i] = pci_read_config(block->nmb_dev, i + offset, 1);
+ dest[i] = pci_read_config(dev, i + offset, 1);
return(len);
}
@@ -886,15 +929,17 @@ NdisWritePciSlotInformation(adapter, slot, offset, buf, len)
ndis_miniport_block *block;
int i;
char *dest;
+ device_t dev;
block = (ndis_miniport_block *)adapter;
dest = buf;
- if (block == NULL || block->nmb_dev == NULL)
+ if (block == NULL)
return(0);
+ dev = block->nmb_physdeviceobj->do_devext;
for (i = 0; i < len; i++)
- pci_write_config(block->nmb_dev, i + offset, dest[i], 1);
+ pci_write_config(dev, i + offset, dest[i], 1);
return(len);
}
@@ -914,9 +959,10 @@ NdisWriteErrorLogEntry(ndis_handle adapter, ndis_error_code code,
char *str = NULL, *ustr = NULL;
uint16_t flags;
char msgbuf[ERRMSGLEN];
-
+ device_t dev;
block = (ndis_miniport_block *)adapter;
+ dev = block->nmb_physdeviceobj->do_devext;
error = pe_get_message(block->nmb_img, code, &str, &i, &flags);
if (error == 0 && flags & MESSAGE_RESOURCE_UNICODE) {
@@ -925,13 +971,13 @@ NdisWriteErrorLogEntry(ndis_handle adapter, ndis_error_code code,
((i / 2)) > (ERRMSGLEN - 1) ? ERRMSGLEN : i, &ustr);
str = ustr;
}
- device_printf (block->nmb_dev, "NDIS ERROR: %x (%s)\n", code,
+ device_printf (dev, "NDIS ERROR: %x (%s)\n", code,
str == NULL ? "unknown error" : str);
- device_printf (block->nmb_dev, "NDIS NUMERRORS: %x\n", numerrors);
+ device_printf (dev, "NDIS NUMERRORS: %x\n", numerrors);
va_start(ap, numerrors);
for (i = 0; i < numerrors; i++)
- device_printf (block->nmb_dev, "argptr: %p\n",
+ device_printf (dev, "argptr: %p\n",
va_arg(ap, void *));
va_end(ap);
@@ -982,7 +1028,7 @@ NdisMStartBufferPhysicalMapping(adapter, buf, mapreg, writedev, addrarray, array
return;
block = (ndis_miniport_block *)adapter;
- sc = (struct ndis_softc *)(block->nmb_ifp);
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
if (mapreg > sc->ndis_mmapcnt)
return;
@@ -1019,7 +1065,7 @@ NdisMCompleteBufferPhysicalMapping(adapter, buf, mapreg)
return;
block = (ndis_miniport_block *)adapter;
- sc = (struct ndis_softc *)(block->nmb_ifp);
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
if (mapreg > sc->ndis_mmapcnt)
return;
@@ -1136,7 +1182,7 @@ NdisMQueryAdapterResources(status, adapter, list, buflen)
int rsclen;
block = (ndis_miniport_block *)adapter;
- sc = (struct ndis_softc *)block->nmb_ifp;
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
rsclen = sizeof(ndis_resource_list) +
(sizeof(cm_partial_resource_desc) * (sc->ndis_rescnt - 1));
@@ -1165,7 +1211,7 @@ NdisMRegisterIoPortRange(offset, adapter, port, numports)
return(NDIS_STATUS_FAILURE);
block = (ndis_miniport_block *)adapter;
- sc = (struct ndis_softc *)(block->nmb_ifp);
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
if (sc->ndis_res_io == NULL)
return(NDIS_STATUS_FAILURE);
@@ -1201,7 +1247,7 @@ NdisReadNetworkAddress(status, addr, addrlen, adapter)
uint8_t empty[] = { 0, 0, 0, 0, 0, 0 };
block = (ndis_miniport_block *)adapter;
- sc = (struct ndis_softc *)block->nmb_ifp;
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
if (bcmp(sc->arpcom.ac_enaddr, empty, ETHER_ADDR_LEN) == 0)
*status = NDIS_STATUS_FAILURE;
@@ -1236,7 +1282,7 @@ NdisMAllocateMapRegisters(adapter, dmachannel, dmasize, physmapneeded, maxmap)
int error, i, nseg = NDIS_MAXSEG;
block = (ndis_miniport_block *)adapter;
- sc = (struct ndis_softc *)block->nmb_ifp;
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
sc->ndis_mmaps = malloc(sizeof(bus_dmamap_t) * physmapneeded,
M_DEVBUF, M_NOWAIT|M_ZERO);
@@ -1271,7 +1317,7 @@ NdisMFreeMapRegisters(adapter)
int i;
block = (ndis_miniport_block *)adapter;
- sc = (struct ndis_softc *)block->nmb_ifp;
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
for (i = 0; i < sc->ndis_mmapcnt; i++)
bus_dmamap_destroy(sc->ndis_mtag, sc->ndis_mmaps[i]);
@@ -1322,7 +1368,7 @@ NdisMAllocateSharedMemory(adapter, len, cached, vaddr, paddr)
return;
block = (ndis_miniport_block *)adapter;
- sc = (struct ndis_softc *)(block->nmb_ifp);
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
sh = malloc(sizeof(struct ndis_shmem), M_DEVBUF, M_NOWAIT|M_ZERO);
if (sh == NULL)
@@ -1398,12 +1444,12 @@ ndis_asyncmem_complete(arg)
w = arg;
block = (ndis_miniport_block *)w->na_adapter;
- sc = (struct ndis_softc *)(block->nmb_ifp);
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
vaddr = NULL;
paddr.np_quad = 0;
- donefunc = sc->ndis_chars.nmc_allocate_complete_func;
+ donefunc = sc->ndis_chars->nmc_allocate_complete_func;
NdisMAllocateSharedMemory(w->na_adapter, w->na_len,
w->na_cached, &vaddr, &paddr);
donefunc(w->na_adapter, vaddr, &paddr, w->na_len, w->na_ctx);
@@ -1463,7 +1509,7 @@ NdisMFreeSharedMemory(adapter, len, cached, vaddr, paddr)
return;
block = (ndis_miniport_block *)adapter;
- sc = (struct ndis_softc *)(block->nmb_ifp);
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
sh = prev = sc->ndis_shlist;
while (sh) {
@@ -1501,7 +1547,7 @@ NdisMMapIoSpace(vaddr, adapter, paddr, len)
return(NDIS_STATUS_FAILURE);
block = (ndis_miniport_block *)adapter;
- sc = (struct ndis_softc *)(block->nmb_ifp);
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
if (sc->ndis_res_mem != NULL &&
paddr.np_quad == rman_get_start(sc->ndis_res_mem))
@@ -1564,7 +1610,7 @@ NdisMInitializeScatterGatherDma(adapter, is64, maxphysmap)
if (adapter == NULL)
return(NDIS_STATUS_FAILURE);
block = (ndis_miniport_block *)adapter;
- sc = (struct ndis_softc *)block->nmb_ifp;
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
/* Don't do this twice. */
if (sc->ndis_sc == 1)
@@ -2083,8 +2129,8 @@ NdisUnicodeStringToAnsiString(dstr, sstr)
{
if (dstr == NULL || sstr == NULL)
return(NDIS_STATUS_FAILURE);
- if (ndis_unicode_to_ascii(sstr->nus_buf,
- sstr->nus_len, &dstr->nas_buf))
+ if (ndis_unicode_to_ascii(sstr->us_buf,
+ sstr->us_len, &dstr->nas_buf))
return(NDIS_STATUS_FAILURE);
dstr->nas_len = dstr->nas_maxlen = strlen(dstr->nas_buf);
return (NDIS_STATUS_SUCCESS);
@@ -2103,11 +2149,11 @@ NdisAnsiStringToUnicodeString(dstr, sstr)
return(NDIS_STATUS_FAILURE);
strncpy(str, sstr->nas_buf, sstr->nas_len);
*(str + sstr->nas_len) = '\0';
- if (ndis_ascii_to_unicode(str, &dstr->nus_buf)) {
+ if (ndis_ascii_to_unicode(str, &dstr->us_buf)) {
free(str, M_DEVBUF);
return(NDIS_STATUS_FAILURE);
}
- dstr->nus_len = dstr->nus_maxlen = sstr->nas_len * 2;
+ dstr->us_len = dstr->us_maxlen = sstr->nas_len * 2;
free(str, M_DEVBUF);
return (NDIS_STATUS_SUCCESS);
}
@@ -2147,6 +2193,7 @@ NdisMRegisterInterrupt(intr, adapter, ivec, ilevel, reqisr, shared, imode)
intr->ni_isrreq = reqisr;
intr->ni_shared = shared;
block->nmb_interrupt = intr;
+
return(NDIS_STATUS_SUCCESS);
}
@@ -2171,8 +2218,8 @@ NdisMRegisterAdapterShutdownHandler(adapter, shutdownctx, shutdownfunc)
return;
block = (ndis_miniport_block *)adapter;
- sc = (struct ndis_softc *)block->nmb_ifp;
- chars = &sc->ndis_chars;
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
+ chars = sc->ndis_chars;
chars->nmc_shutdown_handler = shutdownfunc;
chars->nmc_rsvd0 = shutdownctx;
@@ -2192,8 +2239,8 @@ NdisMDeregisterAdapterShutdownHandler(adapter)
return;
block = (ndis_miniport_block *)adapter;
- sc = (struct ndis_softc *)block->nmb_ifp;
- chars = &sc->ndis_chars;
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
+ chars = sc->ndis_chars;
chars->nmc_shutdown_handler = NULL;
chars->nmc_rsvd0 = NULL;
@@ -2272,7 +2319,7 @@ NdisReadPcmciaAttributeMemory(handle, offset, buf, len)
return(0);
block = (ndis_miniport_block *)handle;
- sc = (struct ndis_softc *)block->nmb_ifp;
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
dest = buf;
bh = rman_get_bushandle(sc->ndis_res_am);
@@ -2302,7 +2349,7 @@ NdisWritePcmciaAttributeMemory(handle, offset, buf, len)
return(0);
block = (ndis_miniport_block *)handle;
- sc = (struct ndis_softc *)block->nmb_ifp;
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
src = buf;
bh = rman_get_bushandle(sc->ndis_res_am);
@@ -2383,7 +2430,7 @@ NdisMSynchronizeWithInterrupt(intr, syncfunc, syncctx)
if (syncfunc == NULL || syncctx == NULL)
return(0);
- sc = (struct ndis_softc *)intr->ni_block->nmb_ifp;
+ sc = device_get_softc(intr->ni_block->nmb_physdeviceobj->do_devext);
sync = syncfunc;
mtx_lock(&sc->ndis_intrmtx);
rval = sync(syncctx);
@@ -2432,10 +2479,10 @@ NdisInitializeString(dst, src)
ndis_unicode_string *u;
u = dst;
- u->nus_buf = NULL;
- if (ndis_ascii_to_unicode(src, &u->nus_buf))
+ u->us_buf = NULL;
+ if (ndis_ascii_to_unicode(src, &u->us_buf))
return;
- u->nus_len = u->nus_maxlen = strlen(src) * 2;
+ u->us_len = u->us_maxlen = strlen(src) * 2;
return;
}
@@ -2445,8 +2492,8 @@ NdisFreeString(str)
{
if (str == NULL)
return;
- if (str->nus_buf != NULL)
- free(str->nus_buf, M_DEVBUF);
+ if (str->us_buf != NULL)
+ free(str->us_buf, M_DEVBUF);
free(str, M_DEVBUF);
return;
}
@@ -2491,14 +2538,14 @@ NdisInitUnicodeString(dst, src)
if (u == NULL)
return;
if (src == NULL) {
- u->nus_len = u->nus_maxlen = 0;
- u->nus_buf = NULL;
+ u->us_len = u->us_maxlen = 0;
+ u->us_buf = NULL;
} else {
i = 0;
while(src[i] != 0)
i++;
- u->nus_buf = src;
- u->nus_len = u->nus_maxlen = i * 2;
+ u->us_buf = src;
+ u->us_len = u->us_maxlen = i * 2;
}
return;
@@ -2518,9 +2565,11 @@ __stdcall static void NdisMGetDeviceProperty(adapter, phydevobj,
block = (ndis_miniport_block *)adapter;
if (phydevobj != NULL)
- *phydevobj = &block->nmb_devobj;
+ *phydevobj = block->nmb_physdeviceobj;
if (funcdevobj != NULL)
- *funcdevobj = &block->nmb_devobj;
+ *funcdevobj = block->nmb_deviceobj;
+ if (nextdevobj != NULL)
+ *nextdevobj = block->nmb_nextdeviceobj;
return;
}
@@ -2617,8 +2666,8 @@ NdisOpenFile(status, filehandle, filelength, filename, highestaddr)
linker_file_t head, lf;
caddr_t kldstart, kldend;
- ndis_unicode_to_ascii(filename->nus_buf,
- filename->nus_len, &afilename);
+ ndis_unicode_to_ascii(filename->us_buf,
+ filename->us_len, &afilename);
fh = malloc(sizeof(ndis_fh), M_TEMP, M_NOWAIT);
if (fh == NULL) {
@@ -3010,7 +3059,7 @@ NdisMRegisterDevice(handle, devname, symname, majorfuncs, devobj, devhandle)
ndis_miniport_block *block;
block = (ndis_miniport_block *)handle;
- *devobj = &block->nmb_devobj;
+ *devobj = block->nmb_deviceobj;
*devhandle = handle;
return(NDIS_STATUS_SUCCESS);
@@ -3029,11 +3078,14 @@ NdisMQueryAdapterInstanceName(name, handle)
ndis_handle handle;
{
ndis_miniport_block *block;
+ device_t dev;
block = (ndis_miniport_block *)handle;
+ dev = block->nmb_physdeviceobj->do_devext;
+
ndis_ascii_to_unicode(__DECONST(char *,
- device_get_nameunit(block->nmb_dev)), &name->nus_buf);
- name->nus_len = strlen(device_get_nameunit(block->nmb_dev)) * 2;
+ device_get_nameunit(dev)), &name->us_buf);
+ name->us_len = strlen(device_get_nameunit(dev)) * 2;
return(NDIS_STATUS_SUCCESS);
}
diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c
index b3df9c4..f793f2a 100644
--- a/sys/compat/ndis/subr_ntoskrnl.c
+++ b/sys/compat/ndis/subr_ntoskrnl.c
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/kthread.h>
+#include <sys/module.h>
#include <machine/atomic.h>
#include <machine/clock.h>
@@ -81,8 +82,18 @@ __stdcall static ndis_status RtlUnicodeStringToAnsiString(ndis_ansi_string *,
ndis_unicode_string *, uint8_t);
__stdcall static ndis_status RtlAnsiStringToUnicodeString(ndis_unicode_string *,
ndis_ansi_string *, uint8_t);
-__stdcall static void *IoBuildSynchronousFsdRequest(uint32_t, void *,
- void *, uint32_t, uint32_t *, void *, void *);
+__stdcall static irp *IoBuildSynchronousFsdRequest(uint32_t, device_object *,
+ void *, uint32_t, uint64_t *, nt_kevent *, io_status_block *);
+__stdcall static irp *IoBuildAsynchronousFsdRequest(uint32_t,
+ device_object *, void *, uint32_t, uint64_t *, io_status_block *);
+__stdcall static irp *IoBuildDeviceIoControlRequest(uint32_t,
+ device_object *, void *, uint32_t, void *, uint32_t,
+ uint8_t, nt_kevent *, io_status_block *);
+__stdcall static irp *IoAllocateIrp(uint8_t, uint8_t);
+__stdcall static void IoReuseIrp(irp *, uint32_t);
+__stdcall static void IoFreeIrp(irp *);
+__stdcall static void IoInitializeIrp(irp *, uint16_t, uint8_t);
+__stdcall static irp *IoMakeAssociatedIrp(irp *, uint8_t);
__stdcall static uint32_t KeWaitForMultipleObjects(uint32_t,
nt_dispatch_header **, uint32_t, uint32_t, uint32_t, uint8_t,
int64_t *, wait_block *);
@@ -105,8 +116,6 @@ __stdcall static uint64_t _aulldiv(uint64_t, uint64_t);
__stdcall static uint64_t _aullrem(uint64_t, uint64_t);
__regparm static uint64_t _aullshr(uint64_t, uint8_t);
__regparm static uint64_t _aullshl(uint64_t, uint8_t);
-__stdcall static void *ntoskrnl_allocfunc(uint32_t, size_t, uint32_t);
-__stdcall static void ntoskrnl_freefunc(void *);
static slist_entry *ntoskrnl_pushsl(slist_header *, slist_entry *);
static slist_entry *ntoskrnl_popsl(slist_header *);
__stdcall static void ExInitializePagedLookasideList(paged_lookaside_list *,
@@ -203,16 +212,16 @@ RtlEqualUnicodeString(str1, str2, caseinsensitive)
{
int i;
- if (str1->nus_len != str2->nus_len)
+ if (str1->us_len != str2->us_len)
return(FALSE);
- for (i = 0; i < str1->nus_len; i++) {
+ for (i = 0; i < str1->us_len; i++) {
if (caseinsensitive == TRUE) {
- if (toupper((char)(str1->nus_buf[i] & 0xFF)) !=
- toupper((char)(str2->nus_buf[i] & 0xFF)))
+ if (toupper((char)(str1->us_buf[i] & 0xFF)) !=
+ toupper((char)(str2->us_buf[i] & 0xFF)))
return(FALSE);
} else {
- if (str1->nus_buf[i] != str2->nus_buf[i])
+ if (str1->us_buf[i] != str2->us_buf[i])
return(FALSE);
}
}
@@ -226,11 +235,11 @@ RtlCopyUnicodeString(dest, src)
ndis_unicode_string *src;
{
- if (dest->nus_maxlen >= src->nus_len)
- dest->nus_len = src->nus_len;
+ if (dest->us_maxlen >= src->us_len)
+ dest->us_len = src->us_len;
else
- dest->nus_len = dest->nus_maxlen;
- memcpy(dest->nus_buf, src->nus_buf, dest->nus_len);
+ dest->us_len = dest->us_maxlen;
+ memcpy(dest->us_buf, src->us_buf, dest->us_len);
return;
}
@@ -246,15 +255,15 @@ RtlUnicodeStringToAnsiString(dest, src, allocate)
return(NDIS_STATUS_FAILURE);
if (allocate == TRUE) {
- if (ndis_unicode_to_ascii(src->nus_buf, src->nus_len, &astr))
+ if (ndis_unicode_to_ascii(src->us_buf, src->us_len, &astr))
return(NDIS_STATUS_FAILURE);
dest->nas_buf = astr;
dest->nas_len = dest->nas_maxlen = strlen(astr);
} else {
- dest->nas_len = src->nus_len / 2; /* XXX */
+ dest->nas_len = src->us_len / 2; /* XXX */
if (dest->nas_maxlen < dest->nas_len)
dest->nas_len = dest->nas_maxlen;
- ndis_unicode_to_ascii(src->nus_buf, dest->nas_len * 2,
+ ndis_unicode_to_ascii(src->us_buf, dest->nas_len * 2,
&dest->nas_buf);
}
return (NDIS_STATUS_SUCCESS);
@@ -274,39 +283,478 @@ RtlAnsiStringToUnicodeString(dest, src, allocate)
if (allocate == TRUE) {
if (ndis_ascii_to_unicode(src->nas_buf, &ustr))
return(NDIS_STATUS_FAILURE);
- dest->nus_buf = ustr;
- dest->nus_len = dest->nus_maxlen = strlen(src->nas_buf) * 2;
+ dest->us_buf = ustr;
+ dest->us_len = dest->us_maxlen = strlen(src->nas_buf) * 2;
} else {
- dest->nus_len = src->nas_len * 2; /* XXX */
- if (dest->nus_maxlen < dest->nus_len)
- dest->nus_len = dest->nus_maxlen;
- ndis_ascii_to_unicode(src->nas_buf, &dest->nus_buf);
+ dest->us_len = src->nas_len * 2; /* XXX */
+ if (dest->us_maxlen < dest->us_len)
+ dest->us_len = dest->us_maxlen;
+ ndis_ascii_to_unicode(src->nas_buf, &dest->us_buf);
}
return (NDIS_STATUS_SUCCESS);
}
-__stdcall static void *
+__stdcall void *
+ExAllocatePoolWithTag(pooltype, len, tag)
+ uint32_t pooltype;
+ size_t len;
+ uint32_t tag;
+{
+ void *buf;
+
+ buf = malloc(len, M_DEVBUF, M_NOWAIT);
+ if (buf == NULL)
+ return(NULL);
+ return(buf);
+}
+
+__stdcall void
+ExFreePool(buf)
+ void *buf;
+{
+ free(buf, M_DEVBUF);
+ return;
+}
+
+__stdcall uint32_t
+IoAllocateDriverObjectExtension(drv, clid, extlen, ext)
+ driver_object *drv;
+ void *clid;
+ uint32_t extlen;
+ void **ext;
+{
+ custom_extension *ce;
+
+ ce = ExAllocatePoolWithTag(NonPagedPool, sizeof(custom_extension)
+ + extlen, 0);
+
+ if (ce == NULL)
+ return(STATUS_INSUFFICIENT_RESOURCES);
+
+ ce->ce_clid = clid;
+ INSERT_LIST_TAIL((&drv->dro_driverext->dre_usrext), (&ce->ce_list));
+
+ *ext = (void *)(ce + 1);
+
+ return(STATUS_SUCCESS);
+}
+
+__stdcall void *
+IoGetDriverObjectExtension(drv, clid)
+ driver_object *drv;
+ void *clid;
+{
+ list_entry *e;
+ custom_extension *ce;
+
+ e = drv->dro_driverext->dre_usrext.nle_flink;
+ while (e != &drv->dro_driverext->dre_usrext) {
+ ce = (custom_extension *)e;
+ if (ce->ce_clid == clid)
+ return((void *)(ce + 1));
+ e = e->nle_flink;
+ }
+
+ return(NULL);
+}
+
+
+__stdcall uint32_t
+IoCreateDevice(drv, devextlen, devname, devtype, devchars, exclusive, newdev)
+ driver_object *drv;
+ uint32_t devextlen;
+ unicode_string *devname;
+ uint32_t devtype;
+ uint32_t devchars;
+ uint8_t exclusive;
+ device_object **newdev;
+{
+ device_object *dev;
+
+ dev = ExAllocatePoolWithTag(NonPagedPool, sizeof(device_object), 0);
+ if (dev == NULL)
+ return(STATUS_INSUFFICIENT_RESOURCES);
+
+ dev->do_type = devtype;
+ dev->do_drvobj = drv;
+ dev->do_currirp = NULL;
+ dev->do_flags = 0;
+
+ if (devextlen) {
+ dev->do_devext = ExAllocatePoolWithTag(NonPagedPool,
+ devextlen, 0);
+
+ if (dev->do_devext == NULL) {
+ ExFreePool(dev);
+ return(STATUS_INSUFFICIENT_RESOURCES);
+ }
+ } else
+ dev->do_devext = NULL;
+
+ dev->do_size = sizeof(device_object) + devextlen;
+ dev->do_refcnt = 1;
+ dev->do_attacheddev = NULL;
+ dev->do_nextdev = NULL;
+ dev->do_devtype = devtype;
+ dev->do_stacksize = 1;
+ dev->do_alignreq = 1;
+ dev->do_characteristics = devchars;
+ dev->do_iotimer = NULL;
+ KeInitializeEvent(&dev->do_devlock, EVENT_TYPE_SYNC, TRUE);
+
+ /*
+ * Vpd is used for disk/tape devices,
+ * but we don't support those. (Yet.)
+ */
+ dev->do_vpb = NULL;
+
+ dev->do_devobj_ext = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(devobj_extension), 0);
+
+ if (dev->do_devobj_ext == NULL) {
+ if (dev->do_devext != NULL)
+ ExFreePool(dev->do_devext);
+ ExFreePool(dev);
+ return(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ dev->do_devobj_ext->dve_type = 0;
+ dev->do_devobj_ext->dve_size = sizeof(devobj_extension);
+ dev->do_devobj_ext->dve_devobj = dev;
+
+ /*
+ * Attach this device to the driver object's list
+ * of devices. Note: this is not the same as attaching
+ * the device to the device stack. The driver's AddDevice
+ * routine must explicitly call IoAddDeviceToDeviceStack()
+ * to do that.
+ */
+
+ if (drv->dro_devobj == NULL) {
+ drv->dro_devobj = dev;
+ dev->do_nextdev = NULL;
+ } else {
+ dev->do_nextdev = drv->dro_devobj;
+ drv->dro_devobj = dev;
+ }
+
+ *newdev = dev;
+
+ return(STATUS_SUCCESS);
+}
+
+__stdcall void
+IoDeleteDevice(dev)
+ device_object *dev;
+{
+ device_object *prev;
+
+ if (dev == NULL)
+ return;
+
+ if (dev->do_devobj_ext != NULL)
+ ExFreePool(dev->do_devobj_ext);
+
+ if (dev->do_devext != NULL)
+ ExFreePool(dev->do_devext);
+
+ /* Unlink the device from the driver's device list. */
+
+ prev = dev->do_drvobj->dro_devobj;
+ if (prev == dev)
+ dev->do_drvobj->dro_devobj = dev->do_nextdev;
+ else {
+ while (prev->do_nextdev != dev)
+ prev = prev->do_nextdev;
+ prev->do_nextdev = dev->do_nextdev;
+ }
+
+ ExFreePool(dev);
+
+ return;
+}
+
+__stdcall device_object *
+IoGetAttachedDevice(dev)
+ device_object *dev;
+{
+ device_object *d;
+
+ if (dev == NULL)
+ return (NULL);
+
+ d = dev;
+
+ while (d->do_attacheddev != NULL)
+ d = d->do_attacheddev;
+
+ return (d);
+}
+
+__stdcall static irp *
IoBuildSynchronousFsdRequest(func, dobj, buf, len, off, event, status)
uint32_t func;
- void *dobj;
+ device_object *dobj;
+ void *buf;
+ uint32_t len;
+ uint64_t *off;
+ nt_kevent *event;
+ io_status_block *status;
+{
+ return(NULL);
+}
+
+__stdcall static irp *
+IoBuildAsynchronousFsdRequest(func, dobj, buf, len, off, status)
+ uint32_t func;
+ device_object *dobj;
void *buf;
uint32_t len;
- uint32_t *off;
- void *event;
- void *status;
+ uint64_t *off;
+ io_status_block *status;
{
return(NULL);
}
-
+
+__stdcall static irp *
+IoBuildDeviceIoControlRequest(iocode, dobj, ibuf, ilen, obuf, olen,
+ isinternal, event, status)
+ uint32_t iocode;
+ device_object *dobj;
+ void *ibuf;
+ uint32_t ilen;
+ void *obuf;
+ uint32_t olen;
+ uint8_t isinternal;
+ nt_kevent *event;
+ io_status_block *status;
+{
+ return (NULL);
+}
+
+__stdcall static irp *
+IoAllocateIrp(stsize, chargequota)
+ uint8_t stsize;
+ uint8_t chargequota;
+{
+ irp *i;
+
+ i = ExAllocatePoolWithTag(NonPagedPool, IoSizeOfIrp(stsize), 0);
+ if (i == NULL)
+ return (NULL);
+
+ IoInitializeIrp(i, IoSizeOfIrp(stsize), stsize);
+
+ return (NULL);
+}
+
+__stdcall static irp *
+IoMakeAssociatedIrp(ip, stsize)
+ irp *ip;
+ uint8_t stsize;
+{
+ irp *associrp;
+
+ associrp = IoAllocateIrp(stsize, FALSE);
+ if (associrp == NULL)
+ return(NULL);
+
+ mtx_lock(&ntoskrnl_dispatchlock);
+ associrp->irp_flags |= IRP_ASSOCIATED_IRP;
+ associrp->irp_tail.irp_overlay.irp_thread =
+ ip->irp_tail.irp_overlay.irp_thread;
+ associrp->irp_assoc.irp_master = ip;
+ mtx_unlock(&ntoskrnl_dispatchlock);
+
+ return(associrp);
+}
+
+__stdcall static void
+IoFreeIrp(ip)
+ irp *ip;
+{
+ ExFreePool(ip);
+ return;
+}
+
+__stdcall static void
+IoInitializeIrp(io, psize, ssize)
+ irp *io;
+ uint16_t psize;
+ uint8_t ssize;
+{
+ bzero((char *)io, sizeof(irp));
+ io->irp_size = psize;
+ io->irp_stackcnt = ssize;
+ io->irp_currentstackloc = ssize;
+ INIT_LIST_HEAD(&io->irp_thlist);
+ io->irp_tail.irp_overlay.irp_csl =
+ (io_stack_location *)(io + 1) + ssize;
+
+ return;
+}
+
+__stdcall static void
+IoReuseIrp(ip, status)
+ irp *ip;
+ uint32_t status;
+{
+ uint8_t allocflags;
+
+ allocflags = ip->irp_allocflags;
+ IoInitializeIrp(ip, ip->irp_size, ip->irp_stackcnt);
+ ip->irp_iostat.isb_status = status;
+ ip->irp_allocflags = allocflags;
+
+ return;
+}
+
__fastcall uint32_t
IofCallDriver(REGARGS2(device_object *dobj, irp *ip))
{
- return(0);
+ driver_object *drvobj;
+ io_stack_location *sl;
+ uint32_t status;
+ driver_dispatch disp;
+
+ drvobj = dobj->do_drvobj;
+
+ if (ip->irp_currentstackloc <= 0)
+ panic("IoCallDriver(): out of stack locations");
+
+ IoSetNextIrpStackLocation(ip);
+ sl = IoGetCurrentIrpStackLocation(ip);
+
+ sl->isl_devobj = dobj;
+
+ disp = drvobj->dro_dispatch[sl->isl_major];
+ status = disp(dobj, ip);
+
+ return(status);
}
__fastcall void
IofCompleteRequest(REGARGS2(irp *ip, uint8_t prioboost))
{
+ uint32_t i;
+ uint32_t status;
+ device_object *dobj;
+ io_stack_location *sl;
+ completion_func cf;
+
+ ip->irp_pendingreturned =
+ IoGetCurrentIrpStackLocation(ip)->isl_ctl & SL_PENDING_RETURNED;
+ sl = (io_stack_location *)(ip + 1);
+
+ for (i = ip->irp_currentstackloc; i < (uint32_t)ip->irp_stackcnt; i++) {
+ if (ip->irp_currentstackloc < ip->irp_stackcnt - 1) {
+ IoSkipCurrentIrpStackLocation(ip);
+ dobj = IoGetCurrentIrpStackLocation(ip)->isl_devobj;
+ } else
+ dobj = NULL;
+
+ if (sl[i].isl_completionfunc != NULL &&
+ ((ip->irp_iostat.isb_status == STATUS_SUCCESS &&
+ sl->isl_ctl & SL_INVOKE_ON_SUCCESS) ||
+ (ip->irp_iostat.isb_status != STATUS_SUCCESS &&
+ sl->isl_ctl & SL_INVOKE_ON_ERROR) ||
+ (ip->irp_cancel == TRUE &&
+ sl->isl_ctl & SL_INVOKE_ON_CANCEL))) {
+ cf = sl->isl_completionfunc;
+ status = cf(dobj, ip, sl->isl_completionctx);
+ if (status == STATUS_MORE_PROCESSING_REQUIRED)
+ return;
+ }
+
+ if (IoGetCurrentIrpStackLocation(ip)->isl_ctl &
+ SL_PENDING_RETURNED)
+ ip->irp_pendingreturned = TRUE;
+ }
+
+ /* Handle any associated IRPs. */
+
+ if (ip->irp_flags & IRP_ASSOCIATED_IRP) {
+ uint32_t masterirpcnt;
+ irp *masterirp;
+ mdl *m;
+
+ masterirp = ip->irp_assoc.irp_master;
+ masterirpcnt = FASTCALL1(InterlockedDecrement,
+ masterirp->irp_assoc.irp_irpcnt);
+
+ while ((m = ip->irp_mdl) != NULL) {
+ ip->irp_mdl = m->mdl_next;
+ IoFreeMdl(m);
+ }
+ IoFreeIrp(ip);
+ if (masterirpcnt == 0)
+ IoCompleteRequest(masterirp, IO_NO_INCREMENT);
+ return;
+ }
+
+ /* With any luck, these conditions will never arise. */
+
+ if (ip->irp_flags & (IRP_PAGING_IO|IRP_CLOSE_OPERATION)) {
+ if (ip->irp_usriostat != NULL)
+ *ip->irp_usriostat = ip->irp_iostat;
+ if (ip->irp_usrevent != NULL)
+ KeSetEvent(ip->irp_usrevent, prioboost, FALSE);
+ if (ip->irp_flags & IRP_PAGING_IO) {
+ if (ip->irp_mdl != NULL)
+ IoFreeMdl(ip->irp_mdl);
+ IoFreeIrp(ip);
+ }
+ }
+
+ return;
+}
+
+__stdcall device_object *
+IoAttachDeviceToDeviceStack(src, dst)
+ device_object *src;
+ device_object *dst;
+{
+ device_object *attached;
+
+ mtx_lock(&ntoskrnl_dispatchlock);
+
+ attached = IoGetAttachedDevice(dst);
+ attached->do_attacheddev = src;
+ src->do_attacheddev = NULL;
+ src->do_stacksize = attached->do_stacksize + 1;
+
+ mtx_unlock(&ntoskrnl_dispatchlock);
+
+ return(attached);
+}
+
+__stdcall void
+IoDetachDevice(topdev)
+ device_object *topdev;
+{
+ device_object *tail;
+
+ mtx_lock(&ntoskrnl_dispatchlock);
+
+ /* First, break the chain. */
+ tail = topdev->do_attacheddev;
+ if (tail == NULL) {
+ mtx_unlock(&ntoskrnl_dispatchlock);
+ return;
+ }
+ topdev->do_attacheddev = tail->do_attacheddev;
+ topdev->do_refcnt--;
+
+ /* Now reduce the stacksize count for the tail objects. */
+
+ tail = topdev->do_attacheddev;
+ while (tail != NULL) {
+ tail->do_stacksize--;
+ tail = tail->do_attacheddev;
+ }
+
+ mtx_unlock(&ntoskrnl_dispatchlock);
+
return;
}
@@ -830,23 +1278,6 @@ ntoskrnl_popsl(head)
return(first);
}
-__stdcall static void *
-ntoskrnl_allocfunc(pooltype, size, tag)
- uint32_t pooltype;
- size_t size;
- uint32_t tag;
-{
- return(malloc(size, M_DEVBUF, M_NOWAIT));
-}
-
-__stdcall static void
-ntoskrnl_freefunc(buf)
- void *buf;
-{
- free(buf, M_DEVBUF);
- return;
-}
-
__stdcall static void
ExInitializePagedLookasideList(lookaside, allocfunc, freefunc,
flags, size, tag, depth)
@@ -866,12 +1297,12 @@ ExInitializePagedLookasideList(lookaside, allocfunc, freefunc,
lookaside->nll_l.gl_size = size;
lookaside->nll_l.gl_tag = tag;
if (allocfunc == NULL)
- lookaside->nll_l.gl_allocfunc = ntoskrnl_allocfunc;
+ lookaside->nll_l.gl_allocfunc = ExAllocatePoolWithTag;
else
lookaside->nll_l.gl_allocfunc = allocfunc;
if (freefunc == NULL)
- lookaside->nll_l.gl_freefunc = ntoskrnl_freefunc;
+ lookaside->nll_l.gl_freefunc = ExFreePool;
else
lookaside->nll_l.gl_freefunc = freefunc;
@@ -916,12 +1347,12 @@ ExInitializeNPagedLookasideList(lookaside, allocfunc, freefunc,
lookaside->nll_l.gl_size = size;
lookaside->nll_l.gl_tag = tag;
if (allocfunc == NULL)
- lookaside->nll_l.gl_allocfunc = ntoskrnl_allocfunc;
+ lookaside->nll_l.gl_allocfunc = ExAllocatePoolWithTag;
else
lookaside->nll_l.gl_allocfunc = allocfunc;
if (freefunc == NULL)
- lookaside->nll_l.gl_freefunc = ntoskrnl_freefunc;
+ lookaside->nll_l.gl_freefunc = ExFreePool;
else
lookaside->nll_l.gl_freefunc = freefunc;
@@ -1057,7 +1488,8 @@ IoAllocateMdl(vaddr, len, secondarybuf, chargequota, iopkt)
{
mdl *m;
- m = malloc(MmSizeOfMdl(vaddr, len), M_DEVBUF, M_NOWAIT|M_ZERO);
+ m = ExAllocatePoolWithTag(NonPagedPool,
+ MmSizeOfMdl(vaddr, len), 0);
if (m == NULL)
return (NULL);
@@ -1235,14 +1667,14 @@ RtlInitUnicodeString(dst, src)
if (u == NULL)
return;
if (src == NULL) {
- u->nus_len = u->nus_maxlen = 0;
- u->nus_buf = NULL;
+ u->us_len = u->us_maxlen = 0;
+ u->us_buf = NULL;
} else {
i = 0;
while(src[i] != 0)
i++;
- u->nus_buf = src;
- u->nus_len = u->nus_maxlen = i * 2;
+ u->us_buf = src;
+ u->us_len = u->us_maxlen = i * 2;
}
return;
@@ -1259,8 +1691,8 @@ RtlUnicodeStringToInteger(ustr, base, val)
char abuf[64];
char *astr;
- uchr = ustr->nus_buf;
- len = ustr->nus_len;
+ uchr = ustr->us_buf;
+ len = ustr->us_len;
bzero(abuf, sizeof(abuf));
if ((char)((*uchr) & 0xFF) == '-') {
@@ -1306,10 +1738,10 @@ __stdcall static void
RtlFreeUnicodeString(ustr)
ndis_unicode_string *ustr;
{
- if (ustr->nus_buf == NULL)
+ if (ustr->us_buf == NULL)
return;
- free(ustr->nus_buf, M_DEVBUF);
- ustr->nus_buf = NULL;
+ free(ustr->us_buf, M_DEVBUF);
+ ustr->us_buf = NULL;
return;
}
@@ -1374,15 +1806,16 @@ IoGetDeviceProperty(devobj, regprop, buflen, prop, reslen)
void *prop;
uint32_t *reslen;
{
- ndis_miniport_block *block;
+ driver_object *drv;
+ uint16_t **name;
- block = devobj->do_rsvd;
+ drv = devobj->do_drvobj;
switch (regprop) {
case DEVPROP_DRIVER_KEYNAME:
- ndis_ascii_to_unicode(__DECONST(char *,
- device_get_nameunit(block->nmb_dev)), (uint16_t **)&prop);
- *reslen = strlen(device_get_nameunit(block->nmb_dev)) * 2;
+ name = prop;
+ *name = drv->dro_drivername.us_buf;
+ *reslen = drv->dro_drivername.us_len;
break;
default:
return(STATUS_INVALID_PARAMETER_2);
@@ -1746,11 +2179,17 @@ KeInitializeDpc(dpc, dpcfunc, dpcctx)
void *dpcfunc;
void *dpcctx;
{
+ uint8_t irql;
+
if (dpc == NULL)
return;
+ KeInitializeSpinLock(&dpc->k_lock);
+
+ KeAcquireSpinLock(&dpc->k_lock, &irql);
dpc->k_deferedfunc = dpcfunc;
dpc->k_deferredctx = dpcctx;
+ KeReleaseSpinLock(&dpc->k_lock, irql);
return;
}
@@ -1761,8 +2200,13 @@ KeInsertQueueDpc(dpc, sysarg1, sysarg2)
void *sysarg1;
void *sysarg2;
{
+ uint8_t irql;
+
+ KeAcquireSpinLock(&dpc->k_lock, &irql);
dpc->k_sysarg1 = sysarg1;
dpc->k_sysarg2 = sysarg2;
+ KeReleaseSpinLock(&dpc->k_lock, irql);
+
if (ndis_sched(ntoskrnl_run_dpc, dpc, NDIS_SWI))
return(FALSE);
@@ -1896,9 +2340,23 @@ image_patch_table ntoskrnl_functbl[] = {
IMPORT_FUNC(memcpy),
IMPORT_FUNC_MAP(memmove, memset),
IMPORT_FUNC(memset),
+ IMPORT_FUNC(IoAllocateDriverObjectExtension),
+ IMPORT_FUNC(IoGetDriverObjectExtension),
IMPORT_FUNC(IofCallDriver),
IMPORT_FUNC(IofCompleteRequest),
+ IMPORT_FUNC(IoCreateDevice),
+ IMPORT_FUNC(IoDeleteDevice),
+ IMPORT_FUNC(IoGetAttachedDevice),
+ IMPORT_FUNC(IoAttachDeviceToDeviceStack),
+ IMPORT_FUNC(IoDetachDevice),
IMPORT_FUNC(IoBuildSynchronousFsdRequest),
+ IMPORT_FUNC(IoBuildAsynchronousFsdRequest),
+ IMPORT_FUNC(IoBuildDeviceIoControlRequest),
+ IMPORT_FUNC(IoAllocateIrp),
+ IMPORT_FUNC(IoReuseIrp),
+ IMPORT_FUNC(IoMakeAssociatedIrp),
+ IMPORT_FUNC(IoFreeIrp),
+ IMPORT_FUNC(IoInitializeIrp),
IMPORT_FUNC(KeWaitForSingleObject),
IMPORT_FUNC(KeWaitForMultipleObjects),
IMPORT_FUNC(_allmul),
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index 25f8f22..03ac732 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -80,6 +80,7 @@ compat/linux/linux_sysctl.c optional compat_linux
compat/linux/linux_uid16.c optional compat_linux
compat/linux/linux_util.c optional compat_linux
compat/ndis/kern_ndis.c optional ndisapi pci
+compat/ndis/kern_windrv.c optional ndisapi pci
compat/ndis/subr_hal.c optional ndisapi pci
compat/ndis/subr_ndis.c optional ndisapi pci
compat/ndis/subr_ntoskrnl.c optional ndisapi pci
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index c6223db..aed5e4b 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/queue.h>
+#include <sys/module.h>
#if __FreeBSD_version < 502113
#include <sys/sysctl.h>
#endif
@@ -90,6 +91,8 @@ int ndis_suspend (device_t);
int ndis_resume (device_t);
void ndis_shutdown (device_t);
+int ndisdrv_modevent (module_t, int, void *);
+
static __stdcall void ndis_txeof (ndis_handle,
ndis_packet *, ndis_status);
static __stdcall void ndis_rxeof (ndis_handle,
@@ -123,7 +126,45 @@ static void ndis_setmulti (struct ndis_softc *);
static void ndis_map_sclist (void *, bus_dma_segment_t *,
int, bus_size_t, int);
-extern struct mtx_pool *ndis_mtxpool;
+static int ndisdrv_loaded = 0;
+
+/*
+ * This routine should call windrv_load() once for each driver
+ * image. This will do the relocation and dynalinking for the
+ * image, and create a Windows driver object which will be
+ * saved in our driver database.
+ */
+
+int
+ndisdrv_modevent(mod, cmd, arg)
+ module_t mod;
+ int cmd;
+ void *arg;
+{
+ int error = 0;
+
+ switch (cmd) {
+ case MOD_LOAD:
+ ndisdrv_loaded++;
+ if (ndisdrv_loaded > 1)
+ break;
+ windrv_load(mod, (vm_offset_t)drv_data, 0);
+ break;
+ case MOD_UNLOAD:
+ ndisdrv_loaded--;
+ if (ndisdrv_loaded > 0)
+ break;
+ windrv_unload(mod, (vm_offset_t)drv_data, 0);
+ break;
+ case MOD_SHUTDOWN:
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+
+ return (error);
+}
/*
* Program the 64-bit multicast hash filter.
@@ -364,6 +405,8 @@ ndis_attach(dev)
{
u_char eaddr[ETHER_ADDR_LEN];
struct ndis_softc *sc;
+ driver_object *drv;
+ device_object *pdo;
struct ifnet *ifp = NULL;
void *img;
int error = 0, len;
@@ -407,21 +450,32 @@ ndis_attach(dev)
/* Create sysctl registry nodes */
ndis_create_sysctls(sc);
- /* Set up driver image in memory. */
+ /*
+ * Create a new functional device object for this
+ * device. This is what creates the miniport block
+ * for this device instance.
+ */
+
img = drv_data;
- ndis_load_driver((vm_offset_t)img, sc);
+ drv = windrv_lookup((vm_offset_t)img);
+ pdo = windrv_find_pdo(drv, dev);
+ if (NdisAddDevice(drv, pdo) != STATUS_SUCCESS) {
+ device_printf(dev, "failed to create FDO!\n");
+ error = ENXIO;
+ goto fail;
+ }
/* Tell the user what version of the API the driver is using. */
device_printf(dev, "NDIS API version: %d.%d\n",
- sc->ndis_chars.nmc_version_major,
- sc->ndis_chars.nmc_version_minor);
+ sc->ndis_chars->nmc_version_major,
+ sc->ndis_chars->nmc_version_minor);
/* Do resource conversion. */
ndis_convert_res(sc);
/* Install our RX and TX interrupt handlers. */
- sc->ndis_block.nmb_senddone_func = ndis_txeof;
- sc->ndis_block.nmb_pktind_func = ndis_rxeof;
+ sc->ndis_block->nmb_senddone_func = ndis_txeof;
+ sc->ndis_block->nmb_pktind_func = ndis_rxeof;
/* Call driver's init routine. */
if (ndis_init_nic(sc)) {
@@ -443,8 +497,8 @@ ndis_attach(dev)
* with this driver, and if so, how many.
*/
- if (sc->ndis_chars.nmc_sendsingle_func &&
- sc->ndis_chars.nmc_sendmulti_func == NULL) {
+ if (sc->ndis_chars->nmc_sendsingle_func &&
+ sc->ndis_chars->nmc_sendmulti_func == NULL) {
sc->ndis_maxpkts = 1;
} else {
len = sizeof(sc->ndis_maxpkts);
@@ -692,8 +746,8 @@ nonettypes:
}
/* Override the status handler so we can detect link changes. */
- sc->ndis_block.nmb_status_func = ndis_linksts;
- sc->ndis_block.nmb_statusdone_func = ndis_linksts_done;
+ sc->ndis_block->nmb_status_func = ndis_linksts;
+ sc->ndis_block->nmb_statusdone_func = ndis_linksts_done;
fail:
if (error)
ndis_detach(dev);
@@ -717,6 +771,7 @@ ndis_detach(dev)
{
struct ndis_softc *sc;
struct ifnet *ifp;
+ driver_object *drv;
sc = device_get_softc(dev);
KASSERT(mtx_initialized(&sc->ndis_mtx),
@@ -767,6 +822,13 @@ ndis_detach(dev)
ndis_unload_driver(sc);
+ /* Destroy the PDO for this device. */
+
+ drv = windrv_lookup((vm_offset_t)drv_data);
+ if (drv == NULL)
+ panic("couldn't find driver object");
+ windrv_destroy_pdo(drv, dev);
+
if (sc->ndis_iftype == PCIBus)
bus_dma_tag_destroy(sc->ndis_parent_tag);
@@ -849,8 +911,8 @@ ndis_rxeof(adapter, packets, pktcnt)
int i;
block = (ndis_miniport_block *)adapter;
- sc = (struct ndis_softc *)(block->nmb_ifp->if_softc);
- ifp = block->nmb_ifp;
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
+ ifp = &sc->arpcom.ac_if;
for (i = 0; i < pktcnt; i++) {
p = packets[i];
@@ -927,8 +989,8 @@ ndis_txeof(adapter, packet, status)
struct mbuf *m;
block = (ndis_miniport_block *)adapter;
- sc = (struct ndis_softc *)block->nmb_ifp->if_softc;
- ifp = block->nmb_ifp;
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
+ ifp = &sc->arpcom.ac_if;
m = packet->np_m0;
idx = packet->np_txidx;
@@ -979,8 +1041,8 @@ ndis_linksts_done(adapter)
struct ifnet *ifp;
block = adapter;
- ifp = block->nmb_ifp;
- sc = ifp->if_softc;
+ sc = device_get_softc(block->nmb_physdeviceobj->do_devext);
+ ifp = &sc->arpcom.ac_if;
NDIS_LOCK(sc);
if (!NDIS_INITIALIZED(sc)) {
@@ -1038,11 +1100,11 @@ ndis_intr(arg)
sc = arg;
ifp = &sc->arpcom.ac_if;
- if (sc->ndis_block.nmb_miniportadapterctx == NULL)
+ if (sc->ndis_block->nmb_miniportadapterctx == NULL)
return;
mtx_lock(&sc->ndis_intrmtx);
- if (sc->ndis_block.nmb_interrupt->ni_isrreq == TRUE)
+ if (sc->ndis_block->nmb_interrupt->ni_isrreq == TRUE)
ndis_isr(sc, &is_our_intr, &call_isr);
else {
ndis_disable_intr(sc);
@@ -1068,7 +1130,7 @@ ndis_tick(xsc)
ndis_sched(ndis_ticktask, sc, NDIS_TASKQUEUE);
sc->ndis_stat_ch = timeout(ndis_tick, sc, hz *
- sc->ndis_block.nmb_checkforhangsecs);
+ sc->ndis_block->nmb_checkforhangsecs);
mtx_lock(&Giant);
@@ -1087,10 +1149,10 @@ ndis_ticktask(xsc)
sc = xsc;
- hangfunc = sc->ndis_chars.nmc_checkhang_func;
+ hangfunc = sc->ndis_chars->nmc_checkhang_func;
if (hangfunc != NULL) {
- rval = hangfunc(sc->ndis_block.nmb_miniportadapterctx);
+ rval = hangfunc(sc->ndis_block->nmb_miniportadapterctx);
if (rval == TRUE) {
ndis_reset_nic(sc);
return;
@@ -1391,11 +1453,11 @@ ndis_init(xsc)
* drivers, exactly 2 seconds is too fast.
*/
- if (sc->ndis_block.nmb_checkforhangsecs == 0)
- sc->ndis_block.nmb_checkforhangsecs = 3;
+ if (sc->ndis_block->nmb_checkforhangsecs == 0)
+ sc->ndis_block->nmb_checkforhangsecs = 3;
sc->ndis_stat_ch = timeout(ndis_tick, sc,
- hz * sc->ndis_block.nmb_checkforhangsecs);
+ hz * sc->ndis_block->nmb_checkforhangsecs);
return;
}
diff --git a/sys/dev/if_ndis/if_ndis_pccard.c b/sys/dev/if_ndis/if_ndis_pccard.c
index 0786b01..c3c42eb 100644
--- a/sys/dev/if_ndis/if_ndis_pccard.c
+++ b/sys/dev/if_ndis/if_ndis_pccard.c
@@ -87,13 +87,14 @@ static int ndis_probe_pccard (device_t);
static int ndis_attach_pccard (device_t);
static struct resource_list *ndis_get_resource_list
(device_t, device_t);
+extern int ndisdrv_modevent (module_t, int, void *);
extern int ndis_attach (device_t);
extern int ndis_shutdown (device_t);
extern int ndis_detach (device_t);
extern int ndis_suspend (device_t);
extern int ndis_resume (device_t);
-extern struct mtx_pool *ndis_mtxpool;
+extern unsigned char drv_data[];
static device_method_t ndis_methods[] = {
/* Device interface */
@@ -130,10 +131,11 @@ static devclass_t ndis_devclass;
#ifdef NDIS_MODNAME
#define NDIS_MODNAME_OVERRIDE_PCMCIA(x) \
- DRIVER_MODULE(x, pccard, ndis_driver, ndis_devclass, 0, 0)
+ DRIVER_MODULE(x, pccard, ndis_driver, ndis_devclass, \
+ ndisdrv_modevent, 0)
NDIS_MODNAME_OVERRIDE_PCMCIA(NDIS_MODNAME);
#else
-DRIVER_MODULE(ndis, pccard, ndis_driver, ndis_devclass, 0, 0);
+DRIVER_MODULE(ndis, pccard, ndis_driver, ndis_devclass, ndisdrv_modevent, 0);
#endif
/*
@@ -147,6 +149,13 @@ ndis_probe_pccard(dev)
struct ndis_pccard_type *t;
const char *prodstr, *vendstr;
int error;
+ driver_object *drv;
+ vm_offset_t img;
+
+ img = (vm_offset_t)drv_data;
+ drv = windrv_lookup(img);
+ if (drv == NULL)
+ return(ENXIO);
t = ndis_devs;
@@ -161,6 +170,8 @@ ndis_probe_pccard(dev)
if (ndis_strcasecmp(vendstr, t->ndis_vid) == 0 &&
ndis_strcasecmp(prodstr, t->ndis_did) == 0) {
device_set_desc(dev, t->ndis_name);
+ /* Create PDO for this device instance */
+ windrv_create_pdo(drv, dev);
return(0);
}
t++;
diff --git a/sys/dev/if_ndis/if_ndis_pci.c b/sys/dev/if_ndis/if_ndis_pci.c
index 8af48f4..f24ec70 100644
--- a/sys/dev/if_ndis/if_ndis_pci.c
+++ b/sys/dev/if_ndis/if_ndis_pci.c
@@ -86,13 +86,14 @@ static int ndis_probe_pci (device_t);
static int ndis_attach_pci (device_t);
static struct resource_list *ndis_get_resource_list
(device_t, device_t);
+extern int ndisdrv_modevent (module_t, int, void *);
extern int ndis_attach (device_t);
extern int ndis_shutdown (device_t);
extern int ndis_detach (device_t);
extern int ndis_suspend (device_t);
extern int ndis_resume (device_t);
-extern struct mtx_pool *ndis_mtxpool;
+extern unsigned char drv_data[];
static device_method_t ndis_methods[] = {
/* Device interface */
@@ -123,14 +124,15 @@ static devclass_t ndis_devclass;
#ifdef NDIS_MODNAME
#define NDIS_MODNAME_OVERRIDE_PCI(x) \
- DRIVER_MODULE(x, pci, ndis_driver, ndis_devclass, 0, 0)
+ DRIVER_MODULE(x, pci, ndis_driver, ndis_devclass, ndisdrv_modevent, 0)
#define NDIS_MODNAME_OVERRIDE_CARDBUS(x) \
- DRIVER_MODULE(x, cardbus, ndis_driver, ndis_devclass, 0, 0)
+ DRIVER_MODULE(x, cardbus, ndis_driver, ndis_devclass, \
+ ndisdrv_modevent, 0)
NDIS_MODNAME_OVERRIDE_PCI(NDIS_MODNAME);
NDIS_MODNAME_OVERRIDE_CARDBUS(NDIS_MODNAME);
#else
-DRIVER_MODULE(ndis, pci, ndis_driver, ndis_devclass, 0, 0);
-DRIVER_MODULE(ndis, cardbus, ndis_driver, ndis_devclass, 0, 0);
+DRIVER_MODULE(ndis, pci, ndis_driver, ndis_devclass, ndisdrv_modevent, 0);
+DRIVER_MODULE(ndis, cardbus, ndis_driver, ndis_devclass, ndisdrv_modevent, 0);
#endif
/*
@@ -142,8 +144,15 @@ ndis_probe_pci(dev)
device_t dev;
{
struct ndis_pci_type *t;
+ driver_object *drv;
+ vm_offset_t img;
t = ndis_devs;
+ img = (vm_offset_t)drv_data;
+ drv = windrv_lookup(img);
+
+ if (drv == NULL)
+ return(ENXIO);
while(t->ndis_name != NULL) {
if ((pci_get_vendor(dev) == t->ndis_vid) &&
@@ -151,6 +160,9 @@ ndis_probe_pci(dev)
((pci_read_config(dev, PCIR_SUBVEND_0, 4) ==
t->ndis_subsys) || t->ndis_subsys == 0)) {
device_set_desc(dev, t->ndis_name);
+
+ /* Create PDO for this device instance */
+ windrv_create_pdo(drv, dev);
return(0);
}
t++;
diff --git a/sys/dev/if_ndis/if_ndisvar.h b/sys/dev/if_ndis/if_ndisvar.h
index 8da9b39..6736024 100644
--- a/sys/dev/if_ndis/if_ndisvar.h
+++ b/sys/dev/if_ndis/if_ndisvar.h
@@ -62,7 +62,7 @@ struct ndis_cfglist {
TAILQ_HEAD(nch, ndis_cfglist);
-#define NDIS_INITIALIZED(sc) (sc->ndis_block.nmb_miniportadapterctx != NULL)
+#define NDIS_INITIALIZED(sc) (sc->ndis_block->nmb_miniportadapterctx != NULL)
#define NDIS_INC(x) \
(x)->ndis_txidx = ((x)->ndis_txidx + 1) % (x)->ndis_maxpkts
@@ -97,8 +97,8 @@ struct ndis_softc {
struct mtx ndis_intrmtx;
device_t ndis_dev;
int ndis_unit;
- ndis_miniport_block ndis_block;
- ndis_miniport_characteristics ndis_chars;
+ ndis_miniport_block *ndis_block;
+ ndis_miniport_characteristics *ndis_chars;
interface_type ndis_type;
struct callout_handle ndis_stat_ch;
int ndis_maxpkts;
@@ -130,6 +130,7 @@ struct ndis_softc {
bus_dmamap_t *ndis_mmaps;
bus_dmamap_t *ndis_tmaps;
int ndis_mmapcnt;
+ device_object *ndis_pdo;
};
#define NDIS_LOCK(_sc) mtx_lock(&(_sc)->ndis_mtx)
diff --git a/sys/modules/ndis/Makefile b/sys/modules/ndis/Makefile
index 9d5380b..0090a45 100644
--- a/sys/modules/ndis/Makefile
+++ b/sys/modules/ndis/Makefile
@@ -4,6 +4,7 @@
KMOD= ndis
SRCS= subr_pe.c subr_ndis.c subr_hal.c subr_ntoskrnl.c kern_ndis.c
+SRCS+= kern_windrv.c
SRCS+= opt_bdg.h device_if.h bus_if.h pci_if.h vnode_if.h
.include <bsd.kmod.mk>
diff --git a/usr.sbin/ndiscvt/ndiscvt.c b/usr.sbin/ndiscvt/ndiscvt.c
index a24711e..b7a3d5c 100644
--- a/usr.sbin/ndiscvt/ndiscvt.c
+++ b/usr.sbin/ndiscvt/ndiscvt.c
@@ -386,6 +386,7 @@ main(int argc, char *argv[])
fprintf(outfp, "\nextern unsigned char drv_data[];\n\n");
fprintf(outfp, "__asm__(\".data\");\n");
+ fprintf(outfp, "__asm__(\".globl drv_data\");\n");
fprintf(outfp, "__asm__(\".type drv_data, @object\");\n");
fprintf(outfp, "__asm__(\".size drv_data, %d\");\n", fsize);
fprintf(outfp, "__asm__(\"drv_data:\");\n");
OpenPOWER on IntegriCloud