diff options
author | wpaul <wpaul@FreeBSD.org> | 2005-05-08 23:07:51 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2005-05-08 23:07:51 +0000 |
commit | ebc77ad8939abbd4361290c615b7ad4b3c52fdfb (patch) | |
tree | 4e6bc7c75c9d9968ddf02e3220b8910641043fbb | |
parent | 072d05d6e995d5d2aece606732e0048517a31cd9 (diff) | |
download | FreeBSD-src-ebc77ad8939abbd4361290c615b7ad4b3c52fdfb.zip FreeBSD-src-ebc77ad8939abbd4361290c615b7ad4b3c52fdfb.tar.gz |
Fix support for Windows drivers that support both PCI and PCMCIA devices at
the same time.
Fix if_ndis_pccard.c so that it sets sc->ndis_dobj and sc->ndis_regvals.
Correct IMPORT_SFUNC() macros for the READ_PORT_BUFFER_xxx() routines,
which take 3 arguments, not 2.
This fixes it so that the Windows driver for my Cisco Aironet 340 PCMCIA
card works again. (Yes, I know the an(4) driver supports this card natively,
but it's the only PCMCIA device I have with a Windows XP driver.)
-rw-r--r-- | sys/compat/ndis/kern_windrv.c | 11 | ||||
-rw-r--r-- | sys/compat/ndis/subr_hal.c | 6 | ||||
-rw-r--r-- | sys/dev/if_ndis/if_ndis_pccard.c | 3 | ||||
-rw-r--r-- | usr.sbin/ndiscvt/windrv_stub.c | 28 |
4 files changed, 31 insertions, 17 deletions
diff --git a/sys/compat/ndis/kern_windrv.c b/sys/compat/ndis/kern_windrv.c index 11a5824..afaf638 100644 --- a/sys/compat/ndis/kern_windrv.c +++ b/sys/compat/ndis/kern_windrv.c @@ -307,6 +307,8 @@ windrv_unload(mod, img, len) return(0); } +#define WINDRV_LOADED htonl(0x42534F44) + /* * Loader routine for actual Windows driver modules, ultimately * calls the driver's DriverEntry() routine. @@ -327,12 +329,17 @@ windrv_load(mod, img, len, bustype, devlist, regvals) struct drvdb_ent *new; struct driver_object *drv; int status; + uint32_t *ptr; /* * First step: try to relocate and dynalink the executable * driver image. */ + ptr = (uint32_t *)(img + 8); + if (*ptr == WINDRV_LOADED) + goto skipreloc; + /* Perform text relocation */ if (pe_relocate(img)) return(ENOEXEC); @@ -357,6 +364,10 @@ windrv_load(mod, img, len, bustype, devlist, regvals) return(ENOEXEC); } + *ptr = WINDRV_LOADED; + +skipreloc: + /* Next step: find the driver entry point. */ pe_get_optional_header(img, &opt_hdr); diff --git a/sys/compat/ndis/subr_hal.c b/sys/compat/ndis/subr_hal.c index 96ecd37..c6508ed 100644 --- a/sys/compat/ndis/subr_hal.c +++ b/sys/compat/ndis/subr_hal.c @@ -394,9 +394,9 @@ image_patch_table hal_functbl[] = { IMPORT_SFUNC(READ_PORT_ULONG, 1), IMPORT_SFUNC(READ_PORT_USHORT, 1), IMPORT_SFUNC(READ_PORT_UCHAR, 1), - IMPORT_SFUNC(READ_PORT_BUFFER_ULONG, 2), - IMPORT_SFUNC(READ_PORT_BUFFER_USHORT, 2), - IMPORT_SFUNC(READ_PORT_BUFFER_UCHAR, 2), + IMPORT_SFUNC(READ_PORT_BUFFER_ULONG, 3), + IMPORT_SFUNC(READ_PORT_BUFFER_USHORT, 3), + IMPORT_SFUNC(READ_PORT_BUFFER_UCHAR, 3), IMPORT_FFUNC(KfAcquireSpinLock, 1), IMPORT_FFUNC(KfReleaseSpinLock, 1), IMPORT_SFUNC(KeGetCurrentIrql, 0), diff --git a/sys/dev/if_ndis/if_ndis_pccard.c b/sys/dev/if_ndis/if_ndis_pccard.c index c67941a..1963ff8 100644 --- a/sys/dev/if_ndis/if_ndis_pccard.c +++ b/sys/dev/if_ndis/if_ndis_pccard.c @@ -185,7 +185,8 @@ ndis_attach_pccard(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; resource_list_init(&sc->ndis_rl); sc->ndis_io_rid = 0; diff --git a/usr.sbin/ndiscvt/windrv_stub.c b/usr.sbin/ndiscvt/windrv_stub.c index 2097e50..30e74bf 100644 --- a/usr.sbin/ndiscvt/windrv_stub.c +++ b/usr.sbin/ndiscvt/windrv_stub.c @@ -71,14 +71,14 @@ struct ndis_pccard_type { #ifdef NDIS_PCI_DEV_TABLE -static struct ndis_pci_type ndis_devs[] = { +static struct ndis_pci_type ndis_devs_pci[] = { NDIS_PCI_DEV_TABLE { 0, 0, 0, NULL } }; #endif #ifdef NDIS_PCMCIA_DEV_TABLE -static struct ndis_pccard_type ndis_devs[] = { +static struct ndis_pccard_type ndis_devs_pccard[] = { NDIS_PCMCIA_DEV_TABLE { NULL, NULL, NULL } }; @@ -206,15 +206,6 @@ windrv_modevent(mod, cmd, arg) 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; @@ -225,14 +216,25 @@ windrv_modevent(mod, cmd, arg) windrv_loaded++; if (windrv_loaded > 1) break; - windrv_load(mod, drv_data_start, drv_data_len, drv_type, - ndis_devs, &ndis_regvals); +#ifdef NDIS_PCI_DEV_TABLE + windrv_load(mod, drv_data_start, drv_data_len, PCIBus, + ndis_devs_pci, &ndis_regvals); +#endif +#ifdef NDIS_PCMCIA_DEV_TABLE + windrv_load(mod, drv_data_start, drv_data_len, PCMCIABus, + ndis_devs_pccard, &ndis_regvals); +#endif break; case MOD_UNLOAD: windrv_loaded--; if (windrv_loaded > 0) break; +#ifdef NDIS_PCI_DEV_TABLE windrv_unload(mod, drv_data_start, drv_data_len); +#endif +#ifdef NDIS_PCMCIA_DEV_TABLE + windrv_unload(mod, drv_data_start, drv_data_len); +#endif break; case MOD_SHUTDOWN: break; |