summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/compat/ndis/kern_ndis.c2
-rw-r--r--sys/compat/ndis/kern_windrv.c108
-rw-r--r--sys/compat/ndis/ntoskrnl_var.h13
-rw-r--r--sys/compat/ndis/subr_hal.c2
-rw-r--r--sys/compat/ndis/subr_ndis.c19
-rw-r--r--sys/compat/ndis/subr_ntoskrnl.c5
-rw-r--r--sys/conf/files.amd641
-rw-r--r--sys/conf/files.i3861
-rw-r--r--sys/dev/if_ndis/if_ndis.c30
-rw-r--r--sys/dev/if_ndis/if_ndis_pccard.c91
-rw-r--r--sys/dev/if_ndis/if_ndis_pci.c90
-rw-r--r--sys/dev/if_ndis/if_ndis_usb.c29
-rw-r--r--sys/dev/if_ndis/if_ndisvar.h1
-rw-r--r--sys/modules/Makefile3
-rw-r--r--sys/modules/if_ndis/Makefile3
-rw-r--r--usr.sbin/ndiscvt/Makefile7
-rw-r--r--usr.sbin/ndiscvt/ndisgen.882
-rw-r--r--usr.sbin/ndiscvt/ndisgen.sh500
-rw-r--r--usr.sbin/ndiscvt/windrv_stub.c245
19 files changed, 1043 insertions, 189 deletions
diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c
index b7b472a..56832ea 100644
--- a/sys/compat/ndis/kern_ndis.c
+++ b/sys/compat/ndis/kern_ndis.c
@@ -66,11 +66,11 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_ioctl.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>
-#include <compat/ndis/cfg_var.h>
#include <compat/ndis/usbd_var.h>
#include <dev/if_ndis/if_ndisvar.h>
diff --git a/sys/compat/ndis/kern_windrv.c b/sys/compat/ndis/kern_windrv.c
index cd631fd..11a5824 100644
--- a/sys/compat/ndis/kern_windrv.c
+++ b/sys/compat/ndis/kern_windrv.c
@@ -64,22 +64,6 @@ __FBSDID("$FreeBSD$");
#include <compat/ndis/hal_var.h>
#include <compat/ndis/usbd_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;
@@ -208,6 +192,29 @@ windrv_lookup(img, name)
return(NULL);
}
+struct drvdb_ent *
+windrv_match(matchfunc, ctx)
+ matchfuncptr matchfunc;
+ void *ctx;
+{
+ struct drvdb_ent *d;
+ int match;
+
+ mtx_lock(&drvdb_mtx);
+ STAILQ_FOREACH(d, &drvdb_head, link) {
+ if (d->windrv_devlist == NULL)
+ continue;
+ match = matchfunc(d->windrv_devlist, ctx);
+ if (match == TRUE) {
+ mtx_unlock(&drvdb_mtx);
+ return(d);
+ }
+ }
+ 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.
@@ -219,15 +226,52 @@ windrv_unload(mod, img, len)
vm_offset_t img;
int len;
{
- struct drvdb_ent *d, *r = NULL;
+ struct drvdb_ent *db, *r = NULL;
driver_object *drv;
+ device_object *d, *pdo;
+ device_t dev;
list_entry *e, *c;
+ drv = windrv_lookup(img, NULL);
+
+ /*
+ * When we unload a driver image, we need to force a
+ * detach of any devices that might be using it. We
+ * need the PDOs of all attached devices for this.
+ * Getting at them is a little hard. We basically
+ * have to walk the device lists of all our bus
+ * drivers.
+ */
+
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);
+ STAILQ_FOREACH(db, &drvdb_head, link) {
+ /*
+ * Fake bus drivers have no devlist info.
+ * If this driver has devlist info, it's
+ * a loaded Windows driver and has no PDOs,
+ * so skip it.
+ */
+ if (db->windrv_devlist != NULL)
+ continue;
+ pdo = db->windrv_object->dro_devobj;
+ while (pdo != NULL) {
+ d = pdo->do_attacheddev;
+ if (d->do_drvobj != drv) {
+ pdo = pdo->do_nextdev;
+ continue;
+ }
+ dev = pdo->do_devext;
+ pdo = pdo->do_nextdev;
+ mtx_unlock(&drvdb_mtx);
+ device_detach(dev);
+ mtx_lock(&drvdb_mtx);
+ }
+ }
+
+ STAILQ_FOREACH(db, &drvdb_head, link) {
+ if (db->windrv_object->dro_driverstart == (void *)img) {
+ r = db;
+ STAILQ_REMOVE(&drvdb_head, db, drvdb_ent, link);
break;
}
}
@@ -269,10 +313,13 @@ windrv_unload(mod, img, len)
*/
int
-windrv_load(mod, img, len)
+windrv_load(mod, img, len, bustype, devlist, regvals)
module_t mod;
vm_offset_t img;
int len;
+ interface_type bustype;
+ void *devlist;
+ ndis_cfg *regvals;
{
image_import_descriptor imp_desc;
image_optional_header opt_hdr;
@@ -350,6 +397,9 @@ windrv_load(mod, img, len)
&drv->dro_drivername.us_buf);
new->windrv_object = drv;
+ new->windrv_regvals = regvals;
+ new->windrv_devlist = devlist;
+ new->windrv_bustype = bustype;
/* Now call the DriverEntry() function. */
@@ -433,13 +483,16 @@ windrv_find_pdo(drv, bsddev)
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");
+ while (pdo != NULL) {
+ if (pdo->do_devext == bsddev) {
+ mtx_unlock(&drvdb_mtx);
+ return(pdo);
+ }
+ pdo = pdo->do_nextdev;
}
mtx_unlock(&drvdb_mtx);
- return(pdo);
+ return(NULL);
}
/*
@@ -628,9 +681,8 @@ ctxsw_wtou(void)
#ifdef EXTRA_SANITY
if (t->tid_cpu != curthread->td_oncpu)
- panic("ctxswGOT MOVED TO OTHER CPU!");
+ panic("ctxsw GOT MOVED TO OTHER CPU!");
#endif
-
return;
}
diff --git a/sys/compat/ndis/ntoskrnl_var.h b/sys/compat/ndis/ntoskrnl_var.h
index 55e3c1e..2ef6915 100644
--- a/sys/compat/ndis/ntoskrnl_var.h
+++ b/sys/compat/ndis/ntoskrnl_var.h
@@ -1162,14 +1162,25 @@ typedef struct driver_object driver_object;
#define WINDRV_WRAP_CDECL 4
#define WINDRV_WRAP_AMD64 5
+struct drvdb_ent {
+ driver_object *windrv_object;
+ void *windrv_devlist;
+ ndis_cfg *windrv_regvals;
+ interface_type windrv_bustype;
+ STAILQ_ENTRY(drvdb_ent) link;
+};
+
extern image_patch_table ntoskrnl_functbl[];
typedef void (*funcptr)(void);
+typedef int (*matchfuncptr)(void *, void *);
__BEGIN_DECLS
extern int windrv_libinit(void);
extern int windrv_libfini(void);
extern driver_object *windrv_lookup(vm_offset_t, char *);
-extern int windrv_load(module_t, vm_offset_t, int);
+extern struct drvdb_ent *windrv_match(matchfuncptr, void *);
+extern int windrv_load(module_t, vm_offset_t, int, interface_type,
+ void *, ndis_cfg *);
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);
diff --git a/sys/compat/ndis/subr_hal.c b/sys/compat/ndis/subr_hal.c
index b4170f4..c992c7e 100644
--- a/sys/compat/ndis/subr_hal.c
+++ b/sys/compat/ndis/subr_hal.c
@@ -55,6 +55,8 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <compat/ndis/pe_var.h>
+#include <compat/ndis/resource_var.h>
+#include <compat/ndis/cfg_var.h>
#include <compat/ndis/ntoskrnl_var.h>
#include <compat/ndis/hal_var.h>
diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c
index 992a539..7c0d4ad 100644
--- a/sys/compat/ndis/subr_ndis.c
+++ b/sys/compat/ndis/subr_ndis.c
@@ -99,11 +99,11 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcivar.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/hal_var.h>
#include <compat/ndis/ndis_var.h>
-#include <compat/ndis/cfg_var.h>
#include <dev/if_ndis/if_ndisvar.h>
static char ndis_filepath[MAXPATHLEN];
@@ -1014,7 +1014,7 @@ NdisWriteErrorLogEntry(ndis_handle adapter, ndis_error_code code,
block = (ndis_miniport_block *)adapter;
dev = block->nmb_physdeviceobj->do_devext;
- drv = block->nmb_physdeviceobj->do_drvobj;
+ drv = block->nmb_deviceobj->do_drvobj;
error = pe_get_message((vm_offset_t)drv->dro_driverstart,
code, &str, &i, &flags);
@@ -1262,7 +1262,6 @@ NdisMCancelTimer(timer, cancelled)
uint8_t *cancelled;
{
*cancelled = KeCancelTimer(&timer->nt_ktimer);
-
return;
}
@@ -2346,10 +2345,18 @@ NdisMSleep(usecs)
{
struct timeval tv;
- tv.tv_sec = 0;
- tv.tv_usec = usecs;
+ /*
+ * During system bootstrap, (i.e. cold == 1), we aren't
+ * allowed to msleep(), so calling ndis_thsuspend() here
+ * will return 0, and we won't actually have delayed. This
+ * is a problem because some drivers expect NdisMSleep()
+ * to always wait, and might fail if the expected delay
+ * period does not in fact elapse. As a workaround, if the
+ * attempt to sleep delay fails, we do a hard DELAY() instead.
+ */
- ndis_thsuspend(curthread->td_proc, NULL, tvtohz(&tv));
+ if (ndis_thsuspend(curthread->td_proc, NULL, tvtohz(&tv)) == 0)
+ DELAY(usecs);
return;
}
diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c
index bdb9c8f..b3b9040 100644
--- a/sys/compat/ndis/subr_ntoskrnl.c
+++ b/sys/compat/ndis/subr_ntoskrnl.c
@@ -68,13 +68,12 @@ __FBSDID("$FreeBSD$");
#include <vm/uma.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/hal_var.h>
-#include <compat/ndis/resource_var.h>
#include <compat/ndis/ndis_var.h>
-#define __regparm __attribute__((regparm(3)))
-
static uint8_t RtlEqualUnicodeString(ndis_unicode_string *,
ndis_unicode_string *, uint8_t);
static void RtlCopyUnicodeString(ndis_unicode_string *,
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index 085108f..6de730c 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -140,6 +140,7 @@ dev/if_ndis/if_ndis.c optional ndis
dev/if_ndis/if_ndis_pccard.c optional ndis pccard
dev/if_ndis/if_ndis_pci.c optional ndis cardbus
dev/if_ndis/if_ndis_pci.c optional ndis pci
+dev/if_ndis/if_ndis_usb.c optional ndis usb
dev/io/iodev.c optional io
dev/fdc/fdc.c optional fdc
dev/fdc/fdc_acpi.c optional fdc
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index 674de01..3554c30 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -178,6 +178,7 @@ dev/if_ndis/if_ndis.c optional ndis
dev/if_ndis/if_ndis_pccard.c optional ndis pccard
dev/if_ndis/if_ndis_pci.c optional ndis cardbus
dev/if_ndis/if_ndis_pci.c optional ndis pci
+dev/if_ndis/if_ndis_usb.c optional ndis usb
dev/io/iodev.c optional io
dev/kbd/atkbd.c optional atkbd
dev/kbd/atkbdc.c optional atkbdc
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index aa0f5c2..cb9e38c 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -76,17 +76,18 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcivar.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/hal_var.h>
#include <compat/ndis/ndis_var.h>
-#include <compat/ndis/cfg_var.h>
#include <dev/if_ndis/if_ndisvar.h>
-#define NDIS_IMAGE
-#define NDIS_REGVALS
+MODULE_DEPEND(ndis, ether, 1, 1, 1);
+MODULE_DEPEND(ndis, wlan, 1, 1, 1);
+MODULE_DEPEND(ndis, ndisapi, 1, 1, 1);
-#include "ndis_driver_data.h"
+MODULE_VERSION(ndis, 1);
int ndis_attach (device_t);
int ndis_detach (device_t);
@@ -158,8 +159,6 @@ ndisdrv_modevent(mod, cmd, arg)
ndisdrv_loaded++;
if (ndisdrv_loaded > 1)
break;
- if (windrv_load(mod, (vm_offset_t)drv_data, 0))
- return(EINVAL);
windrv_wrap((funcptr)ndis_rxeof, &ndis_rxeof_wrap,
3, WINDRV_WRAP_STDCALL);
windrv_wrap((funcptr)ndis_txeof, &ndis_txeof_wrap,
@@ -173,7 +172,6 @@ ndisdrv_modevent(mod, cmd, arg)
ndisdrv_loaded--;
if (ndisdrv_loaded > 0)
break;
- windrv_unload(mod, (vm_offset_t)drv_data, 0);
windrv_unwrap(ndis_rxeof_wrap);
windrv_unwrap(ndis_txeof_wrap);
windrv_unwrap(ndis_linksts_wrap);
@@ -432,11 +430,9 @@ ndis_attach(dev)
{
u_char eaddr[ETHER_ADDR_LEN];
struct ndis_softc *sc;
- driver_object *drv;
driver_object *pdrv;
device_object *pdo;
struct ifnet *ifp = NULL;
- void *img;
int error = 0, len;
int i;
@@ -472,12 +468,10 @@ ndis_attach(dev)
}
}
- sc->ndis_regvals = ndis_regvals;
-
#if __FreeBSD_version < 502113
sysctl_ctx_init(&sc->ndis_ctx);
-
#endif
+
/* Create sysctl registry nodes */
ndis_create_sysctls(sc);
@@ -497,17 +491,7 @@ ndis_attach(dev)
* for this device instance.
*/
- img = drv_data;
-
- drv = windrv_lookup((vm_offset_t)img, NULL);
-
- if (drv == NULL) {
- device_printf(dev, "failed to find driver_object!\n");
- error = ENXIO;
- goto fail;
- }
-
- if (NdisAddDevice(drv, pdo) != STATUS_SUCCESS) {
+ if (NdisAddDevice(sc->ndis_dobj, pdo) != STATUS_SUCCESS) {
device_printf(dev, "failed to create FDO!\n");
error = ENXIO;
goto fail;
diff --git a/sys/dev/if_ndis/if_ndis_pccard.c b/sys/dev/if_ndis/if_ndis_pccard.c
index 918e89c..c67941a 100644
--- a/sys/dev/if_ndis/if_ndis_pccard.c
+++ b/sys/dev/if_ndis/if_ndis_pccard.c
@@ -54,39 +54,22 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.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/cfg_var.h>
#include <dev/if_ndis/if_ndisvar.h>
#include <dev/pccard/pccardvar.h>
#include "card_if.h"
-#include "ndis_driver_data.h"
-
-#ifdef NDIS_PCMCIA_DEV_TABLE
-
MODULE_DEPEND(ndis, pccard, 1, 1, 1);
-MODULE_DEPEND(ndis, ether, 1, 1, 1);
-MODULE_DEPEND(ndis, wlan, 1, 1, 1);
-MODULE_DEPEND(ndis, ndisapi, 1, 1, 1);
-
-/*
- * Various supported device vendors/types and their names.
- * These are defined in the ndis_driver_data.h file.
- */
-static struct ndis_pccard_type ndis_devs[] = {
-#ifdef NDIS_PCMCIA_DEV_TABLE
- NDIS_PCMCIA_DEV_TABLE
-#endif
- { NULL, NULL, NULL }
-};
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);
+static int ndis_devcompare (struct ndis_pccard_type *, device_t);
extern int ndisdrv_modevent (module_t, int, void *);
extern int ndis_attach (device_t);
extern int ndis_shutdown (device_t);
@@ -118,63 +101,65 @@ static device_method_t ndis_methods[] = {
};
static driver_t ndis_driver = {
-#ifdef NDIS_DEVNAME
- NDIS_DEVNAME,
-#else
"ndis",
-#endif
ndis_methods,
sizeof(struct ndis_softc)
};
static devclass_t ndis_devclass;
-#ifdef NDIS_MODNAME
-#define NDIS_MODNAME_OVERRIDE_PCMCIA(x) \
- 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, ndisdrv_modevent, 0);
-#endif
-/*
- * Probe for an NDIS device. Check the PCI vendor and device
- * IDs against our list and return a device name if we find a match.
- */
static int
-ndis_probe_pccard(dev)
+ndis_devcompare(t, dev)
+ struct ndis_pccard_type *t;
device_t dev;
{
- struct ndis_pccard_type *t;
const char *prodstr, *vendstr;
int error;
- driver_object *drv;
-
- drv = windrv_lookup(0, "PCCARD Bus");
- if (drv == NULL)
- return(ENXIO);
-
- t = ndis_devs;
error = pccard_get_product_str(dev, &prodstr);
if (error)
- return(error);
+ return(FALSE);
error = pccard_get_vendor_str(dev, &vendstr);
if (error)
- return(error);
+ return(FALSE);
while(t->ndis_name != NULL) {
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);
+ return(TRUE);
}
t++;
}
+ return(FALSE);
+}
+
+/*
+ * Probe for an NDIS device. Check the PCI vendor and device
+ * IDs against our list and return a device name if we find a match.
+ */
+static int
+ndis_probe_pccard(dev)
+ device_t dev;
+{
+ driver_object *drv;
+ struct drvdb_ent *db;
+
+ drv = windrv_lookup(0, "PCCARD Bus");
+ if (drv == NULL)
+ return(ENXIO);
+
+ db = windrv_match((matchfuncptr)ndis_devcompare, dev);
+
+ if (db != NULL) {
+ /* Create PDO for this device instance */
+ windrv_create_pdo(drv, dev);
+ return(0);
+ }
+
return(ENXIO);
}
@@ -191,10 +176,16 @@ ndis_attach_pccard(dev)
struct ndis_pccard_type *t;
int devidx = 0;
const char *prodstr, *vendstr;
+ struct drvdb_ent *db;
sc = device_get_softc(dev);
unit = device_get_unit(dev);
sc->ndis_dev = dev;
+
+ db = windrv_match((matchfuncptr)ndis_devcompare, dev);
+ if (db == NULL)
+ return (ENXIO);
+
resource_list_init(&sc->ndis_rl);
sc->ndis_io_rid = 0;
@@ -230,7 +221,7 @@ ndis_attach_pccard(dev)
/* Figure out exactly which device we matched. */
- t = ndis_devs;
+ t = db->windrv_devlist;
error = pccard_get_product_str(dev, &prodstr);
if (error)
@@ -266,8 +257,6 @@ ndis_get_resource_list(dev, child)
return (&sc->ndis_rl);
}
-#endif /* NDIS_PCI_DEV_TABLE */
-
#define NDIS_AM_RID 3
int
diff --git a/sys/dev/if_ndis/if_ndis_pci.c b/sys/dev/if_ndis/if_ndis_pci.c
index 08109e6..1c8691b 100644
--- a/sys/dev/if_ndis/if_ndis_pci.c
+++ b/sys/dev/if_ndis/if_ndis_pci.c
@@ -56,36 +56,19 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcivar.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/cfg_var.h>
#include <dev/if_ndis/if_ndisvar.h>
-#include "ndis_driver_data.h"
-
-#ifdef NDIS_PCI_DEV_TABLE
-
MODULE_DEPEND(ndis, pci, 1, 1, 1);
-MODULE_DEPEND(ndis, ether, 1, 1, 1);
-MODULE_DEPEND(ndis, wlan, 1, 1, 1);
-MODULE_DEPEND(ndis, ndisapi, 1, 1, 1);
-
-/*
- * Various supported device vendors/types and their names.
- * These are defined in the ndis_driver_data.h file.
- */
-static struct ndis_pci_type ndis_devs[] = {
-#ifdef NDIS_PCI_DEV_TABLE
- NDIS_PCI_DEV_TABLE
-#endif
- { 0, 0, 0, NULL }
-};
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);
+static int ndis_devcompare (struct ndis_pci_type *, device_t);
extern int ndisdrv_modevent (module_t, int, void *);
extern int ndis_attach (device_t);
extern int ndis_shutdown (device_t);
@@ -93,8 +76,6 @@ extern int ndis_detach (device_t);
extern int ndis_suspend (device_t);
extern int ndis_resume (device_t);
-extern unsigned char drv_data[];
-
static device_method_t ndis_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ndis_probe_pci),
@@ -111,29 +92,34 @@ static device_method_t ndis_methods[] = {
};
static driver_t ndis_driver = {
-#ifdef NDIS_DEVNAME
- NDIS_DEVNAME,
-#else
"ndis",
-#endif
ndis_methods,
sizeof(struct ndis_softc)
};
static devclass_t ndis_devclass;
-#ifdef NDIS_MODNAME
-#define NDIS_MODNAME_OVERRIDE_PCI(x) \
- 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, \
- ndisdrv_modevent, 0)
-NDIS_MODNAME_OVERRIDE_PCI(NDIS_MODNAME);
-NDIS_MODNAME_OVERRIDE_CARDBUS(NDIS_MODNAME);
-#else
DRIVER_MODULE(ndis, pci, ndis_driver, ndis_devclass, ndisdrv_modevent, 0);
DRIVER_MODULE(ndis, cardbus, ndis_driver, ndis_devclass, ndisdrv_modevent, 0);
-#endif
+
+static int
+ndis_devcompare(t, dev)
+ struct ndis_pci_type *t;
+ device_t dev;
+{
+ while(t->ndis_name != NULL) {
+ if ((pci_get_vendor(dev) == t->ndis_vid) &&
+ (pci_get_device(dev) == t->ndis_did) &&
+ ((pci_read_config(dev, PCIR_SUBVEND_0, 4) ==
+ t->ndis_subsys) || t->ndis_subsys == 0)) {
+ device_set_desc(dev, t->ndis_name);
+ return(TRUE);
+ }
+ t++;
+ }
+
+ return(FALSE);
+}
/*
* Probe for an NDIS device. Check the PCI vendor and device
@@ -143,27 +129,20 @@ static int
ndis_probe_pci(dev)
device_t dev;
{
- struct ndis_pci_type *t;
driver_object *drv;
+ struct drvdb_ent *db;
- t = ndis_devs;
drv = windrv_lookup(0, "PCI Bus");
if (drv == NULL)
return(ENXIO);
- while(t->ndis_name != NULL) {
- if ((pci_get_vendor(dev) == t->ndis_vid) &&
- (pci_get_device(dev) == t->ndis_did) &&
- ((pci_read_config(dev, PCIR_SUBVEND_0, 4) ==
- t->ndis_subsys) || t->ndis_subsys == 0)) {
- device_set_desc(dev, t->ndis_name);
+ db = windrv_match((matchfuncptr)ndis_devcompare, dev);
- /* Create PDO for this device instance */
- windrv_create_pdo(drv, dev);
- return(0);
- }
- t++;
+ if (db != NULL) {
+ /* Create PDO for this device instance */
+ windrv_create_pdo(drv, dev);
+ return(0);
}
return(ENXIO);
@@ -183,11 +162,18 @@ ndis_attach_pci(dev)
int devidx = 0, defidx = 0;
struct resource_list *rl;
struct resource_list_entry *rle;
+ struct drvdb_ent *db;
sc = device_get_softc(dev);
unit = device_get_unit(dev);
sc->ndis_dev = dev;
+ db = windrv_match((matchfuncptr)ndis_devcompare, dev);
+ if (db == NULL)
+ return (ENXIO);
+ sc->ndis_dobj = db->windrv_object;
+ sc->ndis_regvals = db->windrv_regvals;
+
/*
* Map control/status registers.
*/
@@ -213,6 +199,7 @@ ndis_attach_pci(dev)
error = ENXIO;
goto fail;
}
+ pci_enable_io(dev, SYS_RES_IOPORT);
break;
case SYS_RES_MEMORY:
if (sc->ndis_res_altmem != NULL &&
@@ -250,6 +237,7 @@ ndis_attach_pci(dev)
goto fail;
}
}
+ pci_enable_io(dev, SYS_RES_MEMORY);
break;
case SYS_RES_IRQ:
rid = rle->rid;
@@ -312,7 +300,7 @@ ndis_attach_pci(dev)
/* Figure out exactly which device we matched. */
- t = ndis_devs;
+ t = db->windrv_devlist;
while(t->ndis_name != NULL) {
if ((pci_get_vendor(dev) == t->ndis_vid) &&
@@ -329,7 +317,7 @@ ndis_attach_pci(dev)
devidx++;
}
- if (ndis_devs[devidx].ndis_name == NULL)
+ if (t[devidx].ndis_name == NULL)
sc->ndis_devidx = defidx;
else
sc->ndis_devidx = devidx;
@@ -350,5 +338,3 @@ ndis_get_resource_list(dev, child)
sc = device_get_softc(dev);
return (BUS_GET_RESOURCE_LIST(device_get_parent(sc->ndis_dev), dev));
}
-
-#endif /* NDIS_PCI_DEV_TABLE */
diff --git a/sys/dev/if_ndis/if_ndis_usb.c b/sys/dev/if_ndis/if_ndis_usb.c
index 8199534..b5a6943 100644
--- a/sys/dev/if_ndis/if_ndis_usb.c
+++ b/sys/dev/if_ndis/if_ndis_usb.c
@@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sockio.h>
-#include <sys/mbuf.h>
+#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/socket.h>
@@ -56,26 +56,18 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
#include <dev/usb/usbdivar.h>
-#include <dev/usb/usbdevs.h>
-#include <dev/usb/usb_ethersubr.h>
+#include "usbdevs.h"
#include <net80211/ieee80211_var.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/cfg_var.h>
#include <dev/if_ndis/if_ndisvar.h>
MODULE_DEPEND(ndis, usb, 1, 1, 1);
-MODULE_DEPEND(ndis, ether, 1, 1, 1);
-MODULE_DEPEND(ndis, wlan, 1, 1, 1);
-MODULE_DEPEND(ndis, ndisapi, 1, 1, 1);
-
-#include "ndis_driver_data.h"
-
-#ifdef NDIS_USB_DEV_TABLE
Static int ndisusb_match (device_ptr_t);
Static int ndisusb_attach (device_ptr_t);
@@ -107,24 +99,14 @@ Static device_method_t ndis_methods[] = {
};
Static driver_t ndis_driver = {
-#ifdef NDIS_DEVNAME
- NDIS_DEVNAME,
-#else
"ndis",
-#endif
ndis_methods,
sizeof(struct ndis_softc)
};
Static devclass_t ndis_devclass;
-#ifdef NDIS_MODNAME
-#define NDIS_MODNAME_OVERRIDE_USB(x)
- DRIVER_MODULE(x, usb, ndis_driver, ndis_devclass, ndisdrv_modevent, 0)
-NDIS_MODNAME_OVERRIDE_USB(NDIS_MODNAME);
-#else
DRIVER_MODULE(ndis, uhub, ndis_driver, ndis_devclass, ndisdrv_modevent, 0);
-#endif
USB_MATCH(ndisusb)
{
@@ -147,6 +129,9 @@ USB_ATTACH(ndisusb)
sc = (struct ndis_softc *)dummy;
+ if (uaa->device == NULL)
+ USB_ATTACH_ERROR_RETURN;
+
sc->ndis_dev = self;
/* Create PDO for this device instance */
@@ -170,5 +155,3 @@ ndis_get_resource_list(dev, child)
sc = device_get_softc(dev);
return (BUS_GET_RESOURCE_LIST(device_get_parent(sc->ndis_dev), dev));
}
-
-#endif /* NDIS_USB_DEV_TABLE */
diff --git a/sys/dev/if_ndis/if_ndisvar.h b/sys/dev/if_ndis/if_ndisvar.h
index 0936aaf..68f30f9 100644
--- a/sys/dev/if_ndis/if_ndisvar.h
+++ b/sys/dev/if_ndis/if_ndisvar.h
@@ -122,6 +122,7 @@ struct ndis_softc {
#endif
int ndis_devidx;
interface_type ndis_iftype;
+ driver_object *ndis_dobj;
bus_dma_tag_t ndis_parent_tag;
struct ndis_shmem *ndis_shlist;
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index bfc5438..cc033d9 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -103,6 +103,7 @@ SUBDIR= ${_3dfx} \
if_faith \
if_gif \
if_gre \
+ ${_if_ndis} \
if_ppp \
if_sl \
if_stf \
@@ -333,6 +334,7 @@ _hfa= hfa
_i2c= i2c
_ibcs2= ibcs2
_ie= ie
+_if_ndis= if_ndis
_io= io
_linprocfs= linprocfs
_linux= linux
@@ -426,6 +428,7 @@ _em= em
_ext2fs= ext2fs
_i2c= i2c
_ida= ida
+_if_ndis= if_ndis
_iir= iir
_io= io
_ips= ips
diff --git a/sys/modules/if_ndis/Makefile b/sys/modules/if_ndis/Makefile
index bce7c96..cbc2ed0 100644
--- a/sys/modules/if_ndis/Makefile
+++ b/sys/modules/if_ndis/Makefile
@@ -3,7 +3,8 @@
.PATH: ${.CURDIR}/../../dev/if_ndis
KMOD= if_ndis
-SRCS= if_ndis.c if_ndis_pci.c if_ndis_pccard.c
+SRCS= if_ndis.c if_ndis_pci.c if_ndis_pccard.c if_ndis_usb.c
SRCS+= opt_bdg.h device_if.h bus_if.h pci_if.h card_if.h pccarddevs.h
+SRCS+= opt_usb.h usbdevs.h
.include <bsd.kmod.mk>
diff --git a/usr.sbin/ndiscvt/Makefile b/usr.sbin/ndiscvt/Makefile
index 8004897..90ecebb 100644
--- a/usr.sbin/ndiscvt/Makefile
+++ b/usr.sbin/ndiscvt/Makefile
@@ -8,6 +8,7 @@ SRCS+= subr_pe.c
SRCS+= inf.c inf-token.l inf-parse.y y.tab.h
MAN= ndiscvt.8
+MAN+= ndisgen.8
WARNS?= 4
@@ -20,4 +21,10 @@ CFLAGS+=-I. -I${.CURDIR} -I${.CURDIR}/../../sys
CLEANFILES= y.output
+FILES= windrv_stub.c
+FILESNAME= windrv_stub.c
+FILESDIR= /usr/share/misc
+
+SCRIPTS= ndisgen.sh
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/ndiscvt/ndisgen.8 b/usr.sbin/ndiscvt/ndisgen.8
new file mode 100644
index 0000000..d16c34d
--- /dev/null
+++ b/usr.sbin/ndiscvt/ndisgen.8
@@ -0,0 +1,82 @@
+.\" 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 24, 2005
+.Dt NDISGEN 8
+.Os
+.Sh NAME
+.Nm ndisgen
+.Nd generate a FreeBSD driver module from a
+.Tn Windows\[rg]
+NDIS driver distribution
+.Fx
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+The
+.Nm
+script uses the
+.Xr ndiscvt 8
+utility and other tools to generate a FreeBSD loadable driver module
+and a static ELF object module from a
+.Tn Windows\[rg]
+NDIS driver, for use with the
+.Xr ndis 4
+compatibility module.
+.Pp
+The
+.Nm
+script is interactive and contains its own help section. The script
+will prompt the user for the
+.Pa .INF
+and
+.Pa .SYS
+files (and any firmware or other external files) needed to generate
+the FreeBSD driver module.
+.Sh SEE ALSO
+.Xr ld 1 ,
+.Xr objcopy 1 ,
+.Xr ndis 4 ,
+.Xr kldload 8 ,
+.Xr ndiscvt 8 ,
+.Xr ndisapi 9
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+utility was written by
+.An Bill Paul Aq wpaul@windriver.com .
diff --git a/usr.sbin/ndiscvt/ndisgen.sh b/usr.sbin/ndiscvt/ndisgen.sh
new file mode 100644
index 0000000..3e31e88
--- /dev/null
+++ b/usr.sbin/ndiscvt/ndisgen.sh
@@ -0,0 +1,500 @@
+#!/bin/sh
+#
+# 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.
+#
+# $FreeBSD$
+#
+
+header () {
+clear
+echo " =================================================================="
+echo " ------------------ Windows(r) driver converter -------------------"
+echo " =================================================================="
+echo ""
+}
+
+mainmenu() {
+header
+echo " This is script is designed to guide you through the process"
+echo " of converting a Windows(r) binary driver module and .INF"
+echo " specification file into a FreeBSD ELF kernel module for use"
+echo " with the NDIS compatibility system."
+echo ""
+echo " The following options are available:"
+echo ""
+echo " 1] Learn about the NDIS compatibility system"
+echo " 2] Convert individual firmware files"
+echo " 3] Convert driver"
+echo " 4] Exit"
+echo ""
+echo -n " Enter your selection here and press return: "
+read KEYPRESS
+}
+
+
+help1 () {
+header
+echo " General information"
+echo ""
+echo " The NDIS compatibility system is designed to let you use Windows(r)"
+echo " binary drivers for networking devices with FreeBSD, in cases where"
+echo " a native FreeBSD driver is not available due to hardware manufacturer"
+echo " oversight or stupidity. NDIS stands for Network Driver Interface"
+echo " Standard, and refers to the programming model used to write Windows(r)"
+echo " network drivers. (These are often called \"NDIS miniport\" drivers.)"
+echo ""
+echo " In order to use your network device in NDIS compatibility mode,"
+echo " you need the Windows(r) driver that goes with it. Also, the driver"
+echo " must be compiled for the same architecture as the release of FreeBSD"
+echo " you have installed. At this time, the i386 and amd64 architectures"
+echo " are both supported. Note that you cannot use a Windows/i386 driver"
+echo " with FreeBSD/amd64: you must obtain a Windows/amd64 driver."
+echo ""
+echo -n " Press any key to continue... "
+read KEYPRESS
+}
+
+help2() {
+header
+echo " Where to get drivers"
+echo ""
+echo " If you purchased your network card separately from your computer,"
+echo " there should have been a driver distribution CD included with the"
+echo " card which contains Windows(r) drivers. The NDIS compatibility"
+echo " system is designed to emulate the NDIS API of a couple of different"
+echo " Windows(r) releases, however it works best with drivers designed"
+echo " for NDIS 5.0 or later. Drivers distributed for Windows 2000 should"
+echo " work, however for best results you should use a driver designed"
+echo " for Windows XP or Windows Server 2003."
+echo ""
+echo " If your card was supplied with your computer, or is a built-in device,"
+echo " drivers may have been included on a special driver bundle CD shipped"
+echo " with the computer."
+echo ""
+echo " If you don't have a driver CD, you should be able to find a driver"
+echo " kit on the card or computer vendor's web site."
+echo ""
+echo -n " Press any key to continue... "
+read KEYPRESS
+}
+
+help3 () {
+header
+echo " What files do I need?"
+echo ""
+echo " In most cases, you will need only two files: a .INF file and a .SYS"
+echo " file. The .INF file is a text file used by the Windows(r) installer to"
+echo " perform the driver installation. It contains information that tells"
+echo " the intaller what devices the driver supports and what registry keys"
+echo " should be created to control driver configuration. The .SYS file"
+echo " is the actual driver executable code in Windows(r) Portable Executable"
+echo " (PE) format. Note that sometimes the .INF file is supplied in unicode"
+echo " format. Unicode .INF files must be converted to ASCII form with the"
+echo " iconv(1) utility before this installer script can use them."
+echo " Occasionally, a driver may require firmware or register setup"
+echo " files that are external to the main .SYS file. These are provided"
+echo " on the same CD with the driver itself, and sometimes have a .BIN"
+echo " extension, though they can be named almost anything. You will need"
+echo " these additional files to make your device work with the NDIS"
+echo " compatibility system as well."
+echo ""
+echo -n " Press any key to continue... "
+read KEYPRESS
+}
+
+help4 () {
+header
+echo " How does it all work?"
+echo ""
+echo " The installer script uses the ndiscvt(1) utility to convert the .INF,"
+echo " .SYS and optional firmware files into a FreeBSD kernel loadable module"
+echo " (.ko) file. This module can be loaded via the kldload(8) utility or"
+echo " loaded automatically via the /boot/loader.conf file. The ndiscvt(1)"
+echo " utility extracts the device ID information and registry key data"
+echo " from the .INF file and converts it into a C header file. It also uses"
+echo " the objcopy(1) utility to convert the .SYS file and optional firmware"
+echo " files into ELF objects. The header file is compiled into a small C"
+echo " stub file which contains a small amount of code to interface with"
+echo " the FreeBSD module system. This stub is linked together with the"
+echo " converted ELF objects to form a FreeBSD kernel module. A static ELF"
+echo " object (.o) file is also created. This file can be linked into a"
+echo " static kernel image for those who want/need a fully linked kernel"
+echo " image (possibly for embedded bootstrap purposes, or just plain old"
+echo " experimentation)."
+echo ""
+echo -n " Press any key to continue... "
+read KEYPRESS
+}
+
+help5 () {
+header
+echo " Prerequisites"
+echo ""
+echo " Converting a driver requires the following utilities:"
+echo ""
+echo " - The FreeBSD C compiler, cc(1) (part of the base install)."
+echo " - The FreeBSD linker, ld(1) (part of the base install)."
+echo " - The objcopy(1) utility (part of the base install)."
+echo " - The ndiscvt(1) utility (part of the base install)."
+echo ""
+echo " If your happen to end up with a .INF file that's in unicode format,"
+echo " then you'll also need:"
+echo ""
+echo " - The iconv(1) utility."
+echo ""
+echo " If you have installed the X Window system or some sort of desktop"
+echo " environment, then iconv(1) should already be present. If not, you"
+echo " will need to install the libiconv package or port."
+echo ""
+echo -n " Press any key to continue... "
+read KEYPRESS
+}
+
+infconv () {
+header
+echo " INF file validation"
+echo ""
+echo ""
+echo " A .INF file is most often provided as an ASCII file, however"
+echo " files with multilanguage support are provided in Unicode format."
+echo " Please type in the path to your .INF file now."
+echo ""
+echo -n " > "
+read INFPATH
+if [ $INFPATH ] && [ -e $INFPATH ];
+then
+ INFTYPE=`${FILE} ${INFPATH}`
+
+ case ${INFTYPE} in
+ *ASCII*)
+ echo ""
+ echo " This .INF file appears to be ASCII."
+ echo ""
+ echo -n " Press any key to continue... "
+ read KEYPRESS
+ ;;
+ *text*)
+ echo ""
+ echo " This .INF file appears to be ASCII."
+ echo ""
+ echo -n " Press any key to continue... "
+ read KEYPRESS
+ ;;
+ *nicode*)
+ echo ""
+ echo " This .INF file appears to be Unicode."
+ if [ -e $ICONVPATH ];
+ then
+ echo " Trying to convert to ASCII..."
+ ${RM} -f /tmp/ascii.inf
+ ${ICONVPATH} -f utf-16 -t utf-8 ${INFPATH} > /tmp/ascii.inf
+ INFPATH=/tmp/ascii.inf
+ echo " Done."
+ echo ""
+ echo -n " Press any key to continue... "
+ read KEYPRESS
+ else
+ echo " The iconv(1) utility does not appear to be installed."
+ echo " Please install this utility or convert the .INF file"
+ echo " to ASCII and run this utility again."
+ echo ""
+ exit
+ fi
+ ;;
+ *)
+ echo ""
+ echo " I don't recognize this file format. It may not be a valid .INF file."
+ echo ""
+ echo -n " Press enter to try again, or ^C to quit. "
+ read KEYPRESS
+ INFPATH=""
+ ;;
+ esac
+else
+ echo ""
+ echo " The file '$INFPATH' was not found."
+ echo ""
+ echo -n " Press enter to try again, or ^C to quit. "
+ read KEYPRESS
+ INFPATH=""
+fi
+}
+
+sysconv() {
+header
+echo " Driver file validation"
+echo ""
+echo ""
+echo " Now you need to specify the name of the Windows(r) driver .SYS"
+echo " file for your device. Note that if you are running FreeBSD/amd64,"
+echo " then you must provide a driver that has been compiled for the"
+echo " 64-bit Windows(r) platform. If a 64-bit driver is not available"
+echo " for your device, you must install FreeBSD/ia32 and use the"
+echo " 32-bit driver instead."
+echo ""
+echo " Please type in the path to the Windows(r) driver .SYS file now."
+echo ""
+echo -n " > "
+read SYSPATH
+if [ $SYSPATH ] && [ -e $SYSPATH ];
+then
+ SYSTYPE=`${FILE} ${SYSPATH}`
+
+ case ${SYSTYPE} in
+ *Windows*)
+ echo ""
+ echo " This .SYS file appears to be in Windows(r) PE format."
+ echo ""
+ echo -n " Press any key to continue... "
+ read KEYPRESS
+ SYSBASE=`basename ${SYSPATH} | ${TR} '.' '_'`
+ ;;
+ *)
+ echo ""
+ echo " I don't recognize this file format. It may not be a valid .SYS file."
+ echo ""
+
+ echo -n " Press enter to try again, or ^C to quit. "
+ read KEYPRESS
+ SYSPATH=""
+ ;;
+ esac
+else
+ echo ""
+ echo " The file '$SYSPATH' was not found."
+ echo ""
+ echo -n " Press enter to try again, or ^C to quit. "
+ read KEYPRESS
+ SYSPATH=""
+fi
+}
+
+ndiscvt() {
+header
+echo " Driver file conversion"
+echo ""
+echo " The script will now try to convert the .INF and .SYS files"
+echo " using the ndiscvt(1) utility. This utility can handle most"
+echo " .INF files, however occasionally it can fail to parse some files"
+echo " due to subtle syntax issues: the .INF syntax is very complex,"
+echo " and the Windows(r) parser will sometimes allow files with small"
+echo " syntax errors to be processed correctly which ndiscvt(1) will"
+echo " not. If the conversion fails, you may have to edit the .INF"
+echo " file by hand to remove the offending lines."
+echo ""
+echo -n " Press enter to try converting the files now: "
+read KEYPRESS
+if ! ${NDISCVT} -i ${INFPATH} -s ${SYSPATH} -O -o ${DNAME}.h > /dev/null; then
+ echo "CONVERSION FAILED"
+ exit
+else
+ echo ""
+ echo " Conversion was successful."
+ echo ""
+ echo -n " Press enter to continue... "
+ read KEYPRESS
+fi
+}
+
+firmcvt() {
+ while : ; do
+header
+echo " Firmware file conversion"
+echo ""
+echo " If your driver uses additional firmware files, please list them"
+echo " below. When you're finished, just press enter to contiue. (If your"
+echo " driver doesn't need any extra firmware files, just press enter"
+echo " to move to the next step.)"
+echo ""
+ echo -n " > "
+ read FIRMPATH
+
+ if [ $FIRMPATH ] && [ $FIRMPATH != "" ]; then
+ if [ ! -e $FIRMPATH ]; then
+ echo ""
+ echo " The file '$FIRMPATH' was not found"
+ echo ""
+ echo -n " Press enter to try again, or ^C to quit. "
+ read KEYPRESS
+ continue
+ fi
+ if ! ${NDISCVT} -f ${FIRMPATH} > /dev/null; then
+ echo ""
+ echo "CONVERSION FAILED"
+ else
+ echo ""
+ echo " Conversion was successful."
+ echo ""
+ FRMBASE=`basename ${FIRMPATH}`
+ FRMBASE="${FRMBASE}.o"
+ FRMLIST="${FRMLIST} ${FRMBASE}"
+ fi
+ echo -n " Press enter to continue... "
+ read KEYPRESS
+ else
+ break
+ fi
+ done
+
+header
+echo ""
+echo " List of files converted firmware files:"
+echo ""
+for i in $FRMLIST
+do
+ echo " "$i
+done
+echo ""
+echo -n " Press enter to continue... "
+read KEYPRESS
+}
+
+drvgen () {
+header
+echo " Kernel module generation"
+echo ""
+echo ""
+echo " The script will now try to generate the kernel driver module."
+echo " This is the last step. Once this module is generated, you should"
+echo " be able to load it just like any other FreeBSD driver module."
+echo ""
+echo " Press enter to compile the stub module and generate the driver"
+echo -n " module now: "
+read KEYPRESS
+echo ""
+touch bus_if.h
+touch device_if.h
+echo -n " Compiling stub... "
+if ! ${CC} -D_KERNEL -DDRV_DATA_START=${SYSBASE}_drv_data_start -DDRV_NAME=${SYSBASE} -DDRV_DATA_END=${SYSBASE}_drv_data_end -I. ${STUBFILE} -c -o windrv_stub.o; then
+ echo "compilation failed. Exiting."
+ echo ""
+ exit
+else
+ echo "done."
+fi
+echo -n " Linking loadable kernel module... "
+if ! ${LD} -Bshareable -d -warn-common -o ${SYSBASE}.ko windrv_stub.o ${FRMLIST} ${DNAME}.o; then
+ echo "linking failed. Exiting."
+ echo ""
+ exit
+else
+ echo "done."
+fi
+echo -n " Linking static kernel module... "
+if ! ${LD} -r -d -warn-common -o ${SYSBASE}.o windrv_stub.o ${FRMLIST} ${DNAME}.o; then
+ echo "linking failed. Exiting."
+ echo ""
+ exit
+else
+ echo "done."
+fi
+echo -n " Cleaning up... "
+${RM} -f bus_if.h device_if.h windrv_stub.o
+${RM} -f ${DNAME}.h ${DNAME}.o
+echo "done."
+echo ""
+echo " The file $SYSBASE.ko has been successfully generated."
+echo " You can kldload this module to get started."
+echo ""
+echo -n " Press any key to exit. "
+read KEYPRESS
+echo ""
+echo ""
+}
+
+convert_driver () {
+ while : ; do
+ infconv
+ if [ $INFPATH ] && [ $INFPATH != "" ]; then
+ break
+ fi
+ done
+
+ while : ; do
+ sysconv
+ if [ $SYSPATH ] && [ $SYSPATH != "" ]; then
+ break
+ fi
+ done
+
+ ndiscvt
+ firmcvt
+ drvgen
+}
+
+ICONVPATH=/usr/local/bin/iconv
+NDISCVT=/usr/sbin/ndiscvt
+STUBFILE=/usr/share/misc/windrv_stub.c
+DNAME=windrv
+OBJCOPY=/usr/bin/objcopy
+CC=/usr/bin/cc
+LD=/usr/bin/ld
+RM=/bin/rm
+TR=/usr/bin/tr
+FILE=/usr/bin/file
+
+INFPATH=""
+FRMLIST=""
+SYSPATH=""
+SYSBASE=""
+FRMBASE=""
+
+while : ; do
+ mainmenu
+ case ${KEYPRESS} in
+ 1)
+ help1
+ help2
+ help3
+ help4
+ help5
+ ;;
+ 2)
+ firmcvt
+ ;;
+ 3)
+ convert_driver
+ ;;
+ 4)
+ header
+ echo ""
+ echo " Be seeing you!"
+ echo ""
+ exit
+ ;;
+ *)
+ header
+ echo ""
+ echo -n " Sorry, I didn't underatand that. Press enter to try again: "
+ read KEYPRESS
+ ;;
+ esac
+done
diff --git a/usr.sbin/ndiscvt/windrv_stub.c b/usr.sbin/ndiscvt/windrv_stub.c
new file mode 100644
index 0000000..2097e50
--- /dev/null
+++ b/usr.sbin/ndiscvt/windrv_stub.c
@@ -0,0 +1,245 @@
+/*-
+ * 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/kernel.h>
+#include <sys/module.h>
+#include <sys/conf.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/bus.h>
+
+#define NDIS_REGVALS
+
+struct ndis_cfg {
+ char *nc_cfgkey;
+ char *nc_cfgdesc;
+ char nc_val[256];
+ int nc_idx;
+};
+
+typedef struct ndis_cfg ndis_cfg;
+
+#include "windrv.h"
+
+struct ndis_pci_type {
+ uint16_t ndis_vid;
+ uint16_t ndis_did;
+ uint32_t ndis_subsys;
+ char *ndis_name;
+};
+
+struct ndis_pccard_type {
+ const char *ndis_vid;
+ const char *ndis_did;
+ char *ndis_name;
+};
+
+
+#ifdef NDIS_PCI_DEV_TABLE
+static struct ndis_pci_type ndis_devs[] = {
+ NDIS_PCI_DEV_TABLE
+ { 0, 0, 0, NULL }
+};
+#endif
+
+#ifdef NDIS_PCMCIA_DEV_TABLE
+static struct ndis_pccard_type ndis_devs[] = {
+ NDIS_PCMCIA_DEV_TABLE
+ { NULL, NULL, NULL }
+};
+#endif
+
+enum interface_type {
+ InterfaceTypeUndefined = -1,
+ Internal,
+ Isa,
+ Eisa,
+ MicroChannel,
+ TurboChannel,
+ PCIBus,
+ VMEBus,
+ NuBus,
+ PCMCIABus,
+ CBus,
+ MPIBus,
+ MPSABus,
+ ProcessorInternal,
+ InternalPowerBus,
+ PNPISABus,
+ PNPBus,
+ MaximumInterfaceType
+};
+
+typedef enum interface_type interface_type;
+
+/*
+ * XXX
+ * Ordinarily, device_probe_desc is defined in device_if.h, which
+ * is created from device_if.m. The problem is, the latter file
+ * is only available if you have the kernel source code installed,
+ * and not all users choose to install it. I'd like to let people
+ * load Windows driver modules with the minimal amount of hassle
+ * and dependencies. <sys/bus.h> wants both device_if.h and bus_if.h
+ * to be defined, but it turns out the only thing we really need
+ * to get this module compiled is device_probe_desc, so we define
+ * that here, and let the build script create empty copies of
+ * device_if.h and bus_if.h to make the compiler happy.
+ */
+
+extern struct kobjop_desc device_probe_desc;
+typedef int device_probe_t(device_t dev);
+
+extern int windrv_load(module_t, vm_offset_t, size_t,
+ interface_type, void *, void *);
+extern int windrv_unload(module_t, vm_offset_t, size_t);
+
+#ifndef DRV_DATA_START
+#define DRV_DATA_START UNDEF_START
+#endif
+
+#ifndef DRV_DATA_END
+#define DRV_DATA_END UNDEF_END
+#endif
+
+#ifndef DRV_NAME
+#define DRV_NAME UNDEF_NAME
+#endif
+
+extern uint8_t DRV_DATA_START;
+extern uint8_t DRV_DATA_END;
+
+/*
+ * The following is stub code that makes it look as though we want
+ * to be a child device of all the buses that our supported devices
+ * might want to attach to. Our probe routine always fails. The
+ * reason we need this code is so that loading an ELF-ified Windows
+ * driver module will trigger a bus reprobe.
+ */
+
+#define MODULE_DECL(x) \
+ MODULE_DEPEND(x, ndisapi, 1, 1, 1); \
+ MODULE_DEPEND(x, ndis, 1, 1, 1)
+
+MODULE_DECL(DRV_NAME);
+
+static int windrv_probe(device_t);
+static int windrv_modevent(module_t, int, void *);
+static int windrv_loaded = 0;
+
+static device_method_t windrv_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, windrv_probe),
+
+ { 0, 0 }
+};
+
+static driver_t windrv_driver = {
+ "windrv_stub",
+ windrv_methods,
+ 0
+};
+
+static devclass_t windrv_devclass;
+
+#define DRIVER_DECL(x) \
+ DRIVER_MODULE(x, pci, windrv_driver, \
+ windrv_devclass, windrv_modevent, NULL); \
+ DRIVER_MODULE(x, cardbus, windrv_driver, \
+ windrv_devclass, windrv_modevent, NULL); \
+ DRIVER_MODULE(x, pccard, windrv_driver, \
+ windrv_devclass, windrv_modevent, NULL); \
+ DRIVER_MODULE(x, uhub, windrv_driver, \
+ windrv_devclass, windrv_modevent, NULL); \
+ MODULE_VERSION(x, 1)
+
+DRIVER_DECL(DRV_NAME);
+
+static int
+windrv_probe(dev)
+ device_t dev;
+{
+ return (ENXIO);
+}
+
+static int
+windrv_modevent(mod, cmd, arg)
+ module_t mod;
+ int cmd;
+ void *arg;
+{
+ int drv_data_len;
+ int error = 0;
+ vm_offset_t drv_data_start;
+ vm_offset_t drv_data_end;
+ interface_type drv_type;
+
+#ifdef NDIS_PCI_DEV_TABLE
+ drv_type = PCIBus;
+#endif
+
+#ifdef NDIS_PCMCIA_DEV_TABLE
+ drv_type = PCMCIABus;
+#endif
+
+ drv_data_start = (vm_offset_t)&DRV_DATA_START;
+ drv_data_end = (vm_offset_t)&DRV_DATA_END;
+
+ drv_data_len = drv_data_end - drv_data_start;
+ switch (cmd) {
+ case MOD_LOAD:
+ windrv_loaded++;
+ if (windrv_loaded > 1)
+ break;
+ windrv_load(mod, drv_data_start, drv_data_len, drv_type,
+ ndis_devs, &ndis_regvals);
+ break;
+ case MOD_UNLOAD:
+ windrv_loaded--;
+ if (windrv_loaded > 0)
+ break;
+ windrv_unload(mod, drv_data_start, drv_data_len);
+ break;
+ case MOD_SHUTDOWN:
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+
+ return (error);
+}
OpenPOWER on IntegriCloud