3 * Bill Paul <wpaul@windriver.com>. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/kernel.h>
39 #include <sys/module.h>
42 #include <machine/bus.h>
43 #include <machine/resource.h>
55 typedef struct ndis_cfg ndis_cfg;
59 struct ndis_pci_type {
66 struct ndis_pccard_type {
72 struct ndis_usb_type {
78 #ifdef NDIS_PCI_DEV_TABLE
79 static struct ndis_pci_type ndis_devs_pci[] = {
85 #ifdef NDIS_PCMCIA_DEV_TABLE
86 static struct ndis_pccard_type ndis_devs_pccard[] = {
92 #ifdef NDIS_USB_DEV_TABLE
93 static struct ndis_usb_type ndis_devs_usb[] = {
100 InterfaceTypeUndefined = -1,
120 typedef enum interface_type interface_type;
124 * Ordinarily, device_probe_desc is defined in device_if.h, which
125 * is created from device_if.m. The problem is, the latter file
126 * is only available if you have the kernel source code installed,
127 * and not all users choose to install it. I'd like to let people
128 * load Windows driver modules with the minimal amount of hassle
129 * and dependencies. <sys/bus.h> wants both device_if.h and bus_if.h
130 * to be defined, but it turns out the only thing we really need
131 * to get this module compiled is device_probe_desc, so we define
132 * that here, and let the build script create empty copies of
133 * device_if.h and bus_if.h to make the compiler happy.
136 extern struct kobjop_desc device_probe_desc;
137 typedef int device_probe_t(device_t dev);
139 extern int windrv_load(module_t, vm_offset_t, size_t,
140 interface_type, void *, void *);
141 extern int windrv_unload(module_t, vm_offset_t, size_t);
143 #ifndef DRV_DATA_START
144 #define DRV_DATA_START UNDEF_START
148 #define DRV_DATA_END UNDEF_END
152 #define DRV_NAME UNDEF_NAME
155 extern uint8_t DRV_DATA_START;
156 extern uint8_t DRV_DATA_END;
159 * The following is stub code that makes it look as though we want
160 * to be a child device of all the buses that our supported devices
161 * might want to attach to. Our probe routine always fails. The
162 * reason we need this code is so that loading an ELF-ified Windows
163 * driver module will trigger a bus reprobe.
166 #define MODULE_DECL(x) \
167 MODULE_DEPEND(x, ndisapi, 1, 1, 1); \
168 MODULE_DEPEND(x, ndis, 1, 1, 1)
170 MODULE_DECL(DRV_NAME);
172 static int windrv_probe(device_t);
173 static int windrv_modevent(module_t, int, void *);
174 static int windrv_loaded = 0;
176 static device_method_t windrv_methods[] = {
177 /* Device interface */
178 DEVMETHOD(device_probe, windrv_probe),
183 static driver_t windrv_driver = {
189 static devclass_t windrv_devclass;
191 #define DRIVER_DECL(x) \
192 DRIVER_MODULE(x, pci, windrv_driver, \
193 windrv_devclass, windrv_modevent, NULL); \
194 DRIVER_MODULE(x, cardbus, windrv_driver, \
195 windrv_devclass, windrv_modevent, NULL); \
196 DRIVER_MODULE(x, pccard, windrv_driver, \
197 windrv_devclass, windrv_modevent, NULL); \
198 DRIVER_MODULE(x, uhub, windrv_driver, \
199 windrv_devclass, windrv_modevent, NULL); \
202 DRIVER_DECL(DRV_NAME);
212 windrv_modevent(mod, cmd, arg)
219 vm_offset_t drv_data_start;
220 vm_offset_t drv_data_end;
222 drv_data_start = (vm_offset_t)&DRV_DATA_START;
223 drv_data_end = (vm_offset_t)&DRV_DATA_END;
225 drv_data_len = drv_data_end - drv_data_start;
229 if (windrv_loaded > 1)
231 #ifdef NDIS_PCI_DEV_TABLE
232 windrv_load(mod, drv_data_start, drv_data_len, PCIBus,
233 ndis_devs_pci, &ndis_regvals);
235 #ifdef NDIS_PCMCIA_DEV_TABLE
236 windrv_load(mod, drv_data_start, drv_data_len, PCMCIABus,
237 ndis_devs_pccard, &ndis_regvals);
239 #ifdef NDIS_USB_DEV_TABLE
240 windrv_load(mod, drv_data_start, drv_data_len, PNPBus,
241 ndis_devs_usb, &ndis_regvals);
246 if (windrv_loaded > 0)
248 #ifdef NDIS_PCI_DEV_TABLE
249 windrv_unload(mod, drv_data_start, drv_data_len);
251 #ifdef NDIS_PCMCIA_DEV_TABLE
252 windrv_unload(mod, drv_data_start, drv_data_len);
254 #ifdef NDIS_USB_DEV_TABLE
255 windrv_unload(mod, drv_data_start, drv_data_len);