]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - usr.sbin/ndiscvt/windrv_stub.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / usr.sbin / ndiscvt / windrv_stub.c
1 /*-
2  * Copyright (c) 2005
3  *      Bill Paul <wpaul@windriver.com>.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
19  *
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.
31  */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/kernel.h>
39 #include <sys/module.h>
40 #include <sys/conf.h>
41
42 #include <machine/bus.h>
43 #include <machine/resource.h>
44 #include <sys/bus.h>
45
46 #define NDIS_REGVALS
47
48 struct ndis_cfg {
49         char                    *nc_cfgkey;
50         char                    *nc_cfgdesc;
51         char                    nc_val[256];
52         int                     nc_idx;
53 };
54
55 typedef struct ndis_cfg ndis_cfg;
56
57 #include "windrv.h"
58
59 struct ndis_pci_type {
60         uint16_t                ndis_vid;
61         uint16_t                ndis_did;
62         uint32_t                ndis_subsys;
63         char                    *ndis_name;
64 };
65
66 struct ndis_pccard_type {
67         const char              *ndis_vid;
68         const char              *ndis_did;
69         char                    *ndis_name;
70 };
71
72
73 #ifdef NDIS_PCI_DEV_TABLE
74 static struct ndis_pci_type ndis_devs_pci[] = {
75         NDIS_PCI_DEV_TABLE
76         { 0, 0, 0, NULL }
77 };
78 #endif
79
80 #ifdef NDIS_PCMCIA_DEV_TABLE
81 static struct ndis_pccard_type ndis_devs_pccard[] = {
82         NDIS_PCMCIA_DEV_TABLE
83         { NULL, NULL, NULL }
84 };
85 #endif
86
87 enum interface_type {
88         InterfaceTypeUndefined = -1,
89         Internal,
90         Isa,
91         Eisa,
92         MicroChannel,
93         TurboChannel,
94         PCIBus,
95         VMEBus,
96         NuBus,
97         PCMCIABus,
98         CBus,
99         MPIBus,
100         MPSABus,
101         ProcessorInternal,
102         InternalPowerBus,
103         PNPISABus,
104         PNPBus,
105         MaximumInterfaceType
106 };
107
108 typedef enum interface_type interface_type;
109
110 /*
111  * XXX
112  * Ordinarily, device_probe_desc is defined in device_if.h, which
113  * is created from device_if.m. The problem is, the latter file
114  * is only available if you have the kernel source code installed,
115  * and not all users choose to install it. I'd like to let people
116  * load Windows driver modules with the minimal amount of hassle
117  * and dependencies. <sys/bus.h> wants both device_if.h and bus_if.h
118  * to be defined, but it turns out the only thing we really need
119  * to get this module compiled is device_probe_desc, so we define
120  * that here, and let the build script create empty copies of
121  * device_if.h and bus_if.h to make the compiler happy.
122  */
123
124 extern struct kobjop_desc device_probe_desc;
125 typedef int device_probe_t(device_t dev);
126
127 extern int windrv_load(module_t, vm_offset_t, size_t,
128         interface_type, void *, void *);
129 extern int windrv_unload(module_t, vm_offset_t, size_t);
130
131 #ifndef DRV_DATA_START
132 #define DRV_DATA_START UNDEF_START
133 #endif
134
135 #ifndef DRV_DATA_END
136 #define DRV_DATA_END UNDEF_END
137 #endif
138
139 #ifndef DRV_NAME
140 #define DRV_NAME UNDEF_NAME
141 #endif
142
143 extern uint8_t DRV_DATA_START;
144 extern uint8_t DRV_DATA_END;
145
146 /*
147  * The following is stub code that makes it look as though we want
148  * to be a child device of all the buses that our supported devices
149  * might want to attach to. Our probe routine always fails. The
150  * reason we need this code is so that loading an ELF-ified Windows
151  * driver module will trigger a bus reprobe.
152  */
153
154 #define MODULE_DECL(x)                          \
155         MODULE_DEPEND(x, ndisapi, 1, 1, 1);     \
156         MODULE_DEPEND(x, ndis, 1, 1, 1)
157
158 MODULE_DECL(DRV_NAME);
159
160 static int windrv_probe(device_t);
161 static int windrv_modevent(module_t, int, void *);
162 static int windrv_loaded = 0;
163
164 static device_method_t windrv_methods[] = {
165         /* Device interface */
166         DEVMETHOD(device_probe,         windrv_probe),
167
168         { 0, 0 }
169 };
170
171 static driver_t windrv_driver = {
172         "windrv_stub",
173         windrv_methods,
174         0
175 };
176
177 static devclass_t windrv_devclass;
178
179 #define DRIVER_DECL(x)                                  \
180         DRIVER_MODULE(x, pci, windrv_driver,            \
181             windrv_devclass, windrv_modevent, NULL);    \
182         DRIVER_MODULE(x, cardbus, windrv_driver,        \
183             windrv_devclass, windrv_modevent, NULL);    \
184         DRIVER_MODULE(x, pccard, windrv_driver,         \
185             windrv_devclass, windrv_modevent, NULL);    \
186         DRIVER_MODULE(x, uhub, windrv_driver,           \
187             windrv_devclass, windrv_modevent, NULL);    \
188         MODULE_VERSION(x, 1)
189
190 DRIVER_DECL(DRV_NAME);
191
192 static int
193 windrv_probe(dev)
194         device_t                dev;
195 {
196         return (ENXIO);
197 }
198
199 static int
200 windrv_modevent(mod, cmd, arg)
201         module_t                mod;
202         int                     cmd;
203         void                    *arg;
204 {
205         int                     drv_data_len;
206         int                     error = 0;
207         vm_offset_t             drv_data_start;
208         vm_offset_t             drv_data_end;
209
210         drv_data_start = (vm_offset_t)&DRV_DATA_START;
211         drv_data_end = (vm_offset_t)&DRV_DATA_END;
212
213         drv_data_len = drv_data_end - drv_data_start;
214         switch (cmd) {
215         case MOD_LOAD:
216                 windrv_loaded++;
217                 if (windrv_loaded > 1)
218                         break;
219 #ifdef NDIS_PCI_DEV_TABLE
220                 windrv_load(mod, drv_data_start, drv_data_len, PCIBus,
221                     ndis_devs_pci, &ndis_regvals);
222 #endif
223 #ifdef NDIS_PCMCIA_DEV_TABLE
224                 windrv_load(mod, drv_data_start, drv_data_len, PCMCIABus,
225                     ndis_devs_pccard, &ndis_regvals);
226 #endif
227                 break;
228         case MOD_UNLOAD:
229                 windrv_loaded--;
230                 if (windrv_loaded > 0)
231                         break;
232 #ifdef NDIS_PCI_DEV_TABLE
233                 windrv_unload(mod, drv_data_start, drv_data_len);
234 #endif
235 #ifdef NDIS_PCMCIA_DEV_TABLE
236                 windrv_unload(mod, drv_data_start, drv_data_len);
237 #endif
238                 break;
239         case MOD_SHUTDOWN:
240                 break;
241         default:
242                 error = EINVAL;
243                 break;
244         }
245
246         return (error);
247 }