2 * SPDX-License-Identifier: BSD-4-Clause
5 * Bill Paul <wpaul@windriver.com>. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Bill Paul.
18 * 4. Neither the name of the author nor the names of any co-contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/kernel.h>
41 #include <sys/module.h>
44 #include <machine/bus.h>
45 #include <machine/resource.h>
57 typedef struct ndis_cfg ndis_cfg;
61 struct ndis_pci_type {
68 struct ndis_pccard_type {
74 struct ndis_usb_type {
80 #ifdef NDIS_PCI_DEV_TABLE
81 static struct ndis_pci_type ndis_devs_pci[] = {
87 #ifdef NDIS_PCMCIA_DEV_TABLE
88 static struct ndis_pccard_type ndis_devs_pccard[] = {
94 #ifdef NDIS_USB_DEV_TABLE
95 static struct ndis_usb_type ndis_devs_usb[] = {
101 enum interface_type {
102 InterfaceTypeUndefined = -1,
122 typedef enum interface_type interface_type;
126 * Ordinarily, device_probe_desc is defined in device_if.h, which
127 * is created from device_if.m. The problem is, the latter file
128 * is only available if you have the kernel source code installed,
129 * and not all users choose to install it. I'd like to let people
130 * load Windows driver modules with the minimal amount of hassle
131 * and dependencies. <sys/bus.h> wants both device_if.h and bus_if.h
132 * to be defined, but it turns out the only thing we really need
133 * to get this module compiled is device_probe_desc, so we define
134 * that here, and let the build script create empty copies of
135 * device_if.h and bus_if.h to make the compiler happy.
138 extern struct kobjop_desc device_probe_desc;
139 typedef int device_probe_t(device_t dev);
141 extern int windrv_load(module_t, vm_offset_t, size_t,
142 interface_type, void *, void *);
143 extern int windrv_unload(module_t, vm_offset_t, size_t);
145 #ifndef DRV_DATA_START
146 #define DRV_DATA_START UNDEF_START
150 #define DRV_DATA_END UNDEF_END
154 #define DRV_NAME UNDEF_NAME
157 extern uint8_t DRV_DATA_START;
158 extern uint8_t DRV_DATA_END;
161 * The following is stub code that makes it look as though we want
162 * to be a child device of all the buses that our supported devices
163 * might want to attach to. Our probe routine always fails. The
164 * reason we need this code is so that loading an ELF-ified Windows
165 * driver module will trigger a bus reprobe.
168 #define MODULE_DECL(x) \
169 MODULE_DEPEND(x, ndisapi, 1, 1, 1); \
170 MODULE_DEPEND(x, ndis, 1, 1, 1)
172 MODULE_DECL(DRV_NAME);
174 static int windrv_probe(device_t);
175 static int windrv_modevent(module_t, int, void *);
176 static int windrv_loaded = 0;
178 static device_method_t windrv_methods[] = {
179 /* Device interface */
180 DEVMETHOD(device_probe, windrv_probe),
185 static driver_t windrv_driver = {
191 static devclass_t windrv_devclass;
193 #define DRIVER_DECL(x) \
194 DRIVER_MODULE(x, pci, windrv_driver, \
195 windrv_devclass, windrv_modevent, NULL); \
196 DRIVER_MODULE(x, cardbus, windrv_driver, \
197 windrv_devclass, windrv_modevent, NULL); \
198 DRIVER_MODULE(x, pccard, windrv_driver, \
199 windrv_devclass, windrv_modevent, NULL); \
200 DRIVER_MODULE(x, uhub, windrv_driver, \
201 windrv_devclass, windrv_modevent, NULL); \
204 DRIVER_DECL(DRV_NAME);
214 windrv_modevent(mod, cmd, arg)
221 vm_offset_t drv_data_start;
222 vm_offset_t drv_data_end;
224 drv_data_start = (vm_offset_t)&DRV_DATA_START;
225 drv_data_end = (vm_offset_t)&DRV_DATA_END;
227 drv_data_len = drv_data_end - drv_data_start;
231 if (windrv_loaded > 1)
233 #ifdef NDIS_PCI_DEV_TABLE
234 windrv_load(mod, drv_data_start, drv_data_len, PCIBus,
235 ndis_devs_pci, &ndis_regvals);
237 #ifdef NDIS_PCMCIA_DEV_TABLE
238 windrv_load(mod, drv_data_start, drv_data_len, PCMCIABus,
239 ndis_devs_pccard, &ndis_regvals);
241 #ifdef NDIS_USB_DEV_TABLE
242 windrv_load(mod, drv_data_start, drv_data_len, PNPBus,
243 ndis_devs_usb, &ndis_regvals);
248 if (windrv_loaded > 0)
250 #ifdef NDIS_PCI_DEV_TABLE
251 windrv_unload(mod, drv_data_start, drv_data_len);
253 #ifdef NDIS_PCMCIA_DEV_TABLE
254 windrv_unload(mod, drv_data_start, drv_data_len);
256 #ifdef NDIS_USB_DEV_TABLE
257 windrv_unload(mod, drv_data_start, drv_data_len);