removed Revison keyword since ID keyword exists, deleted unused files
[mirror/winof/.git] / core / bus / kernel / bus_driver.c
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  *\r
4  * This software is available to you under the OpenIB.org BSD license\r
5  * below:\r
6  *\r
7  *     Redistribution and use in source and binary forms, with or\r
8  *     without modification, are permitted provided that the following\r
9  *     conditions are met:\r
10  *\r
11  *      - Redistributions of source code must retain the above\r
12  *        copyright notice, this list of conditions and the following\r
13  *        disclaimer.\r
14  *\r
15  *      - Redistributions in binary form must reproduce the above\r
16  *        copyright notice, this list of conditions and the following\r
17  *        disclaimer in the documentation and/or other materials\r
18  *        provided with the distribution.\r
19  *\r
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
24  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
25  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
27  * SOFTWARE.\r
28  *\r
29  * $Id$\r
30  */\r
31 \r
32 \r
33 \r
34 \r
35 /*\r
36  * Provides the driver entry points for the InfiniBand Bus Driver.\r
37  */\r
38 \r
39 #include "complib/cl_types.h"\r
40 #include "bus_driver.h"\r
41 #include "bus_pnp.h"\r
42 #include "al_mgr.h"\r
43 #include "al_dev.h"\r
44 #include "complib/cl_memory.h"\r
45 \r
46 bus_globals_t   bus_globals = {\r
47         BUS_DBG_ERROR,\r
48         TRUE,\r
49         NULL,\r
50         NULL\r
51 };\r
52 \r
53 \r
54 static NTSTATUS\r
55 __read_registry(\r
56         IN                              UNICODE_STRING* const           p_Param_Path );\r
57 \r
58 static NTSTATUS\r
59 bus_drv_open(\r
60         IN                              DEVICE_OBJECT                           *p_dev_obj,\r
61         IN                              IRP                                                     *p_irp );\r
62 \r
63 static NTSTATUS\r
64 bus_drv_cleanup(\r
65         IN                              DEVICE_OBJECT                           *p_dev_obj,\r
66         IN                              IRP                                                     *p_irp );\r
67 \r
68 static NTSTATUS\r
69 bus_drv_close(\r
70         IN                              DEVICE_OBJECT                           *p_dev_obj,\r
71         IN                              IRP                                                     *p_irp );\r
72 \r
73 static NTSTATUS\r
74 bus_drv_ioctl(\r
75         IN                              DEVICE_OBJECT                           *p_dev_obj,\r
76         IN                              IRP                                                     *p_irp );\r
77 \r
78 /***f* InfiniBand Bus Driver/bus_drv_sysctl\r
79 * NAME\r
80 *       bus_drv_sysctl\r
81 *\r
82 * DESCRIPTION\r
83 *       Entry point for handling WMI IRPs.\r
84 *\r
85 * SYNOPSIS\r
86 */\r
87 static NTSTATUS\r
88 bus_drv_sysctl(\r
89         IN                              DEVICE_OBJECT                           *p_dev_obj,\r
90         IN                              IRP                                                     *p_irp );\r
91 /**********/\r
92 \r
93 static void\r
94 bus_drv_unload(\r
95         IN                              DRIVER_OBJECT                           *p_driver_obj );\r
96 \r
97 NTSTATUS\r
98 DriverEntry(\r
99         IN                              DRIVER_OBJECT                           *p_driver_obj,\r
100         IN                              UNICODE_STRING                          *p_registry_path );\r
101 \r
102 #ifdef ALLOC_PRAGMA\r
103 #pragma alloc_text (INIT, DriverEntry)\r
104 #pragma alloc_text (INIT, __read_registry)\r
105 #pragma alloc_text (PAGE, bus_drv_unload)\r
106 #pragma alloc_text (PAGE, bus_drv_open)\r
107 #pragma alloc_text (PAGE, bus_drv_close)\r
108 #pragma alloc_text (PAGE, bus_drv_ioctl)\r
109 #pragma alloc_text (PAGE_PNP, bus_drv_sysctl)\r
110 #endif\r
111 \r
112 static NTSTATUS\r
113 __read_registry(\r
114         IN                              UNICODE_STRING* const           p_registry_path )\r
115 {\r
116         NTSTATUS                                        status;\r
117         /* Remember the terminating entry in the table below. */\r
118         RTL_QUERY_REGISTRY_TABLE        table[3];\r
119         UNICODE_STRING                          param_path;\r
120 \r
121         BUS_ENTER( BUS_DBG_DRV );\r
122 \r
123         RtlInitUnicodeString( &param_path, NULL );\r
124         param_path.MaximumLength = p_registry_path->Length + \r
125                 sizeof(L"\\Parameters");\r
126         param_path.Buffer = cl_zalloc( param_path.MaximumLength );\r
127         if( !param_path.Buffer )\r
128         {\r
129                 BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
130                         ("Failed to allocate parameters path buffer.\n") );\r
131                 return STATUS_INSUFFICIENT_RESOURCES;\r
132         }\r
133 \r
134         RtlAppendUnicodeStringToString( &param_path, p_registry_path );\r
135         RtlAppendUnicodeToString( &param_path, L"\\Parameters" );\r
136 \r
137         /*\r
138          * Clear the table.  This clears all the query callback pointers,\r
139          * and sets up the terminating table entry.\r
140          */\r
141         cl_memclr( table, sizeof(table) );\r
142 \r
143         /* Setup the table entries. */\r
144         table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
145         table[0].Name = L"ReportPortNIC";\r
146         table[0].EntryContext = &bus_globals.b_report_port_nic;\r
147         table[0].DefaultType = REG_DWORD;\r
148         table[0].DefaultData = &bus_globals.b_report_port_nic;\r
149         table[0].DefaultLength = sizeof(ULONG);\r
150 \r
151         table[1].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
152         table[1].Name = L"DebugFlags";\r
153         table[1].EntryContext = &bus_globals.dbg_lvl;\r
154         table[1].DefaultType = REG_DWORD;\r
155         table[1].DefaultData = &bus_globals.dbg_lvl;\r
156         table[1].DefaultLength = sizeof(ULONG);\r
157 \r
158         /* Have at it! */\r
159         status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, \r
160                 param_path.Buffer, table, NULL, NULL );\r
161 \r
162         cl_free( param_path.Buffer );\r
163         BUS_EXIT( BUS_DBG_DRV );\r
164         return status;\r
165 }\r
166 \r
167 \r
168 static NTSTATUS\r
169 bus_drv_open(\r
170         IN                              DEVICE_OBJECT                           *p_dev_obj,\r
171         IN                              IRP                                                     *p_irp )\r
172 {\r
173         BUS_ENTER( BUS_DBG_DRV );\r
174 \r
175         UNUSED_PARAM( p_dev_obj );\r
176 \r
177         CL_ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );\r
178 \r
179         /* We always succeed file handles creation. */\r
180         p_irp->IoStatus.Status = STATUS_SUCCESS;\r
181         p_irp->IoStatus.Information = 0;\r
182         IoCompleteRequest( p_irp, IO_NO_INCREMENT );\r
183 \r
184         BUS_EXIT( BUS_DBG_DRV );\r
185         return STATUS_SUCCESS;\r
186 }\r
187 \r
188 \r
189 static NTSTATUS\r
190 bus_drv_cleanup(\r
191         IN                              DEVICE_OBJECT                           *p_dev_obj,\r
192         IN                              IRP                                                     *p_irp )\r
193 {\r
194         NTSTATUS                        status;\r
195 \r
196         BUS_ENTER( BUS_DBG_DRV );\r
197 \r
198         UNUSED_PARAM( p_dev_obj );\r
199 \r
200         CL_ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );\r
201 \r
202         /*\r
203          * Note that we don't acquire the remove and stop lock on close to allow\r
204          * applications to close the device when the locks are already held.\r
205          */\r
206         status = cl_to_ntstatus( al_dev_close( p_irp ) );\r
207 \r
208         /* Complete the IRP. */\r
209         p_irp->IoStatus.Status = status;\r
210         p_irp->IoStatus.Information = 0;\r
211         IoCompleteRequest( p_irp, IO_NO_INCREMENT );\r
212 \r
213         BUS_EXIT( BUS_DBG_DRV );\r
214         return status;\r
215 }\r
216 \r
217 \r
218 static NTSTATUS\r
219 bus_drv_close(\r
220         IN                              DEVICE_OBJECT                           *p_dev_obj,\r
221         IN                              IRP                                                     *p_irp )\r
222 {\r
223         UNUSED_PARAM( p_dev_obj );\r
224 \r
225         p_irp->IoStatus.Status = STATUS_SUCCESS;\r
226         p_irp->IoStatus.Information = 0;\r
227         IoCompleteRequest( p_irp, IO_NO_INCREMENT );\r
228 \r
229         return STATUS_SUCCESS;\r
230 }\r
231 \r
232 \r
233 static NTSTATUS\r
234 bus_drv_ioctl(\r
235         IN                              DEVICE_OBJECT                           *p_dev_obj,\r
236         IN                              IRP                                                     *p_irp )\r
237 {\r
238         NTSTATUS                        status;\r
239         bus_fdo_ext_t           *p_ext;\r
240         PIO_STACK_LOCATION      p_io_stack;\r
241 \r
242         BUS_ENTER( BUS_DBG_DRV );\r
243 \r
244         /* Get the extension. */\r
245         p_ext = p_dev_obj->DeviceExtension;\r
246 \r
247         /* Get the stack location. */\r
248         p_io_stack = IoGetCurrentIrpStackLocation( p_irp );\r
249 \r
250         /* Acquire the stop lock. */\r
251         status = IoAcquireRemoveLock( &p_ext->cl_ext.stop_lock, p_irp );\r
252         if( !NT_SUCCESS( status ) )\r
253         {\r
254                 p_irp->IoStatus.Status = status;\r
255                 p_irp->IoStatus.Information = 0;\r
256                 IoCompleteRequest( p_irp, IO_NO_INCREMENT );\r
257                 BUS_EXIT( BUS_DBG_DRV );\r
258                 return status;\r
259         }\r
260 \r
261         /* Acquire the remove lock. */\r
262         status = IoAcquireRemoveLock( &p_ext->cl_ext.remove_lock, p_irp );\r
263         if( !NT_SUCCESS( status ) )\r
264         {\r
265                 IoReleaseRemoveLock( &p_ext->cl_ext.stop_lock, p_irp );\r
266                 p_irp->IoStatus.Status = status;\r
267                 p_irp->IoStatus.Information = 0;\r
268                 IoCompleteRequest( p_irp, IO_NO_INCREMENT );\r
269                 BUS_EXIT( BUS_DBG_DRV );\r
270                 return status;\r
271         }\r
272         \r
273         status = cl_to_ntstatus( al_dev_ioctl( p_irp ) );\r
274         \r
275         /* Only pass down if not handled and not PDO device. */\r
276         if( status == STATUS_INVALID_DEVICE_REQUEST && p_ext->cl_ext.p_next_do )\r
277         {\r
278                 IoSkipCurrentIrpStackLocation( p_irp );\r
279                 status = IoCallDriver( p_ext->cl_ext.p_next_do, p_irp );\r
280         }\r
281 \r
282         /* Release the remove and stop locks. */\r
283         IoReleaseRemoveLock( &p_ext->cl_ext.remove_lock, p_irp );\r
284         IoReleaseRemoveLock( &p_ext->cl_ext.stop_lock, p_irp );\r
285 \r
286         BUS_EXIT( BUS_DBG_DRV );\r
287         return status;\r
288 }\r
289 \r
290 \r
291 static NTSTATUS\r
292 bus_drv_sysctl(\r
293         IN                              DEVICE_OBJECT                           *p_dev_obj,\r
294         IN                              IRP                                                     *p_irp )\r
295 {\r
296         NTSTATUS                status;\r
297         bus_fdo_ext_t   *p_ext;\r
298 \r
299         BUS_ENTER( BUS_DBG_DRV );\r
300 \r
301         CL_ASSERT( p_dev_obj );\r
302         CL_ASSERT( p_irp );\r
303 \r
304         p_ext = p_dev_obj->DeviceExtension;\r
305 \r
306         if( p_ext->cl_ext.p_next_do )\r
307         {\r
308                 IoSkipCurrentIrpStackLocation( p_irp );\r
309                 status = IoCallDriver( p_ext->cl_ext.p_next_do, p_irp );\r
310         }\r
311         else\r
312         {\r
313                 status = p_irp->IoStatus.Status;\r
314                 IoCompleteRequest( p_irp, IO_NO_INCREMENT );\r
315         }\r
316 \r
317         BUS_EXIT( BUS_DBG_DRV );\r
318         return status;\r
319 }\r
320 \r
321 \r
322 static void\r
323 bus_drv_unload(\r
324         IN                              DRIVER_OBJECT                           *p_driver_obj )\r
325 {\r
326         BUS_ENTER( BUS_DBG_DRV );\r
327 \r
328         UNUSED_PARAM( p_driver_obj );\r
329 \r
330         BUS_EXIT( BUS_DBG_DRV );\r
331 }\r
332 \r
333 \r
334 NTSTATUS\r
335 DriverEntry(\r
336         IN                              DRIVER_OBJECT                           *p_driver_obj,\r
337         IN                              UNICODE_STRING                          *p_registry_path )\r
338 {\r
339         NTSTATUS                        status;\r
340 \r
341         BUS_ENTER( BUS_DBG_DRV );\r
342 \r
343         /* Store the driver object pointer in the global parameters. */\r
344         bus_globals.p_driver_obj = p_driver_obj;\r
345 \r
346         /* Get the registry values. */\r
347         status = __read_registry( p_registry_path );\r
348         if( !NT_SUCCESS(status) )\r
349         {\r
350                 BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
351                         ("__read_registry returned %08x.\n", status) );\r
352                 return status;\r
353         }\r
354 \r
355         /* Setup the entry points. */\r
356         p_driver_obj->MajorFunction[IRP_MJ_CREATE] = bus_drv_open;\r
357         p_driver_obj->MajorFunction[IRP_MJ_CLEANUP] = bus_drv_cleanup;\r
358         p_driver_obj->MajorFunction[IRP_MJ_CLOSE] = bus_drv_close;\r
359         p_driver_obj->MajorFunction[IRP_MJ_PNP] = cl_pnp;\r
360         p_driver_obj->MajorFunction[IRP_MJ_POWER] = cl_power;\r
361         p_driver_obj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = bus_drv_ioctl;\r
362         p_driver_obj->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = bus_drv_sysctl;\r
363         p_driver_obj->DriverUnload = bus_drv_unload;\r
364         p_driver_obj->DriverExtension->AddDevice = bus_add_device;\r
365 \r
366         BUS_EXIT( BUS_DBG_DRV );\r
367         return STATUS_SUCCESS;\r
368 }\r