2 * Copyright (c) 2005 SilverStorm Technologies. All rights reserved.
\r
4 * This software is available to you under the OpenIB.org BSD license
\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
11 * - Redistributions of source code must retain the above
\r
12 * copyright notice, this list of conditions and the following
\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
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
36 * Provides the driver entry points for the InfiniBand Bus Driver.
\r
39 #include "complib/cl_types.h"
\r
40 #include "bus_driver.h"
\r
41 #include "bus_pnp.h"
\r
44 #include "complib/cl_memory.h"
\r
46 bus_globals_t bus_globals = {
\r
56 IN UNICODE_STRING* const p_Param_Path );
\r
60 IN DEVICE_OBJECT *p_dev_obj,
\r
65 IN DEVICE_OBJECT *p_dev_obj,
\r
70 IN DEVICE_OBJECT *p_dev_obj,
\r
75 IN DEVICE_OBJECT *p_dev_obj,
\r
78 /***f* InfiniBand Bus Driver/bus_drv_sysctl
\r
83 * Entry point for handling WMI IRPs.
\r
89 IN DEVICE_OBJECT *p_dev_obj,
\r
95 IN DRIVER_OBJECT *p_driver_obj );
\r
99 IN DRIVER_OBJECT *p_driver_obj,
\r
100 IN UNICODE_STRING *p_registry_path );
\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
114 IN UNICODE_STRING* const p_registry_path )
\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
121 BUS_ENTER( BUS_DBG_DRV );
\r
123 RtlInitUnicodeString( ¶m_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
129 BUS_TRACE_EXIT( BUS_DBG_ERROR,
\r
130 ("Failed to allocate parameters path buffer.\n") );
\r
131 return STATUS_INSUFFICIENT_RESOURCES;
\r
134 RtlAppendUnicodeStringToString( ¶m_path, p_registry_path );
\r
135 RtlAppendUnicodeToString( ¶m_path, L"\\Parameters" );
\r
138 * Clear the table. This clears all the query callback pointers,
\r
139 * and sets up the terminating table entry.
\r
141 cl_memclr( table, sizeof(table) );
\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
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
159 status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE,
\r
160 param_path.Buffer, table, NULL, NULL );
\r
162 cl_free( param_path.Buffer );
\r
163 BUS_EXIT( BUS_DBG_DRV );
\r
170 IN DEVICE_OBJECT *p_dev_obj,
\r
173 BUS_ENTER( BUS_DBG_DRV );
\r
175 UNUSED_PARAM( p_dev_obj );
\r
177 CL_ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
\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
184 BUS_EXIT( BUS_DBG_DRV );
\r
185 return STATUS_SUCCESS;
\r
191 IN DEVICE_OBJECT *p_dev_obj,
\r
196 BUS_ENTER( BUS_DBG_DRV );
\r
198 UNUSED_PARAM( p_dev_obj );
\r
200 CL_ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
\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
206 status = cl_to_ntstatus( al_dev_close( p_irp ) );
\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
213 BUS_EXIT( BUS_DBG_DRV );
\r
220 IN DEVICE_OBJECT *p_dev_obj,
\r
223 UNUSED_PARAM( p_dev_obj );
\r
225 p_irp->IoStatus.Status = STATUS_SUCCESS;
\r
226 p_irp->IoStatus.Information = 0;
\r
227 IoCompleteRequest( p_irp, IO_NO_INCREMENT );
\r
229 return STATUS_SUCCESS;
\r
235 IN DEVICE_OBJECT *p_dev_obj,
\r
239 bus_fdo_ext_t *p_ext;
\r
240 PIO_STACK_LOCATION p_io_stack;
\r
242 BUS_ENTER( BUS_DBG_DRV );
\r
244 /* Get the extension. */
\r
245 p_ext = p_dev_obj->DeviceExtension;
\r
247 /* Get the stack location. */
\r
248 p_io_stack = IoGetCurrentIrpStackLocation( p_irp );
\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
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
261 /* Acquire the remove lock. */
\r
262 status = IoAcquireRemoveLock( &p_ext->cl_ext.remove_lock, p_irp );
\r
263 if( !NT_SUCCESS( status ) )
\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
273 status = cl_to_ntstatus( al_dev_ioctl( p_irp ) );
\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
278 IoSkipCurrentIrpStackLocation( p_irp );
\r
279 status = IoCallDriver( p_ext->cl_ext.p_next_do, p_irp );
\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
286 BUS_EXIT( BUS_DBG_DRV );
\r
293 IN DEVICE_OBJECT *p_dev_obj,
\r
297 bus_fdo_ext_t *p_ext;
\r
299 BUS_ENTER( BUS_DBG_DRV );
\r
301 CL_ASSERT( p_dev_obj );
\r
302 CL_ASSERT( p_irp );
\r
304 p_ext = p_dev_obj->DeviceExtension;
\r
306 if( p_ext->cl_ext.p_next_do )
\r
308 IoSkipCurrentIrpStackLocation( p_irp );
\r
309 status = IoCallDriver( p_ext->cl_ext.p_next_do, p_irp );
\r
313 status = p_irp->IoStatus.Status;
\r
314 IoCompleteRequest( p_irp, IO_NO_INCREMENT );
\r
317 BUS_EXIT( BUS_DBG_DRV );
\r
324 IN DRIVER_OBJECT *p_driver_obj )
\r
326 BUS_ENTER( BUS_DBG_DRV );
\r
328 UNUSED_PARAM( p_driver_obj );
\r
330 BUS_EXIT( BUS_DBG_DRV );
\r
336 IN DRIVER_OBJECT *p_driver_obj,
\r
337 IN UNICODE_STRING *p_registry_path )
\r
341 BUS_ENTER( BUS_DBG_DRV );
\r
343 /* Store the driver object pointer in the global parameters. */
\r
344 bus_globals.p_driver_obj = p_driver_obj;
\r
346 /* Get the registry values. */
\r
347 status = __read_registry( p_registry_path );
\r
348 if( !NT_SUCCESS(status) )
\r
350 BUS_TRACE_EXIT( BUS_DBG_ERROR,
\r
351 ("__read_registry returned %08x.\n", status) );
\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
366 BUS_EXIT( BUS_DBG_DRV );
\r
367 return STATUS_SUCCESS;
\r