fc6cc0b9987f681deb4ab8293791e8486004c89f
[mirror/winof/.git] / core / iou / kernel / iou_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  * Provides the driver entry points for the InfiniBand I/O Unit Bus Driver.\r
35  */\r
36 \r
37 #include <complib/cl_types.h>\r
38 #include "iou_driver.h"\r
39 #if defined(EVENT_TRACING)\r
40 #ifdef offsetof\r
41 #undef offsetof\r
42 #endif\r
43 #include "iou_driver.tmh"\r
44 #endif\r
45 #include "iou_pnp.h"\r
46 #include <complib/cl_init.h>\r
47 \r
48 \r
49 iou_globals_t   iou_globals = {\r
50         NULL\r
51 };\r
52 \r
53 uint32_t                g_iou_dbg_level = TRACE_LEVEL_ERROR;\r
54 uint32_t                g_iou_dbg_flags = 0x00000fff;\r
55 \r
56 static NTSTATUS\r
57 __read_registry(\r
58         IN                              UNICODE_STRING* const           p_Param_Path );\r
59 \r
60 static NTSTATUS\r
61 iou_drv_open(\r
62         IN                              DEVICE_OBJECT                           *p_dev_obj,\r
63         IN                              IRP                                                     *p_irp );\r
64 \r
65 static NTSTATUS\r
66 iou_drv_close(\r
67         IN                              DEVICE_OBJECT                           *p_dev_obj,\r
68         IN                              IRP                                                     *p_irp );\r
69 \r
70 static NTSTATUS\r
71 iou_drv_ioctl(\r
72         IN                              DEVICE_OBJECT                           *p_dev_obj,\r
73         IN                              IRP                                                     *p_irp );\r
74 \r
75 /***f* InfiniBand Bus Driver/iou_sysctl\r
76 * NAME\r
77 *       iou_sysctl\r
78 *\r
79 * DESCRIPTION\r
80 *       Entry point for handling WMI IRPs.\r
81 *\r
82 * SYNOPSIS\r
83 */\r
84 static NTSTATUS\r
85 iou_sysctl(\r
86         IN                              DEVICE_OBJECT                           *p_dev_obj,\r
87         IN                              IRP                                                     *p_irp );\r
88 /**********/\r
89 \r
90 static void\r
91 iou_unload(\r
92         IN                              DRIVER_OBJECT                           *p_driver_obj );\r
93 \r
94 NTSTATUS\r
95 DriverEntry(\r
96         IN                              DRIVER_OBJECT                           *p_driver_obj,\r
97         IN                              UNICODE_STRING                          *p_registry_path );\r
98 \r
99 \r
100 \r
101 static NTSTATUS\r
102 __read_registry(\r
103         IN                              UNICODE_STRING* const           p_registry_path )\r
104 {\r
105         NTSTATUS                                        status;\r
106         /* Remember the terminating entry in the table below. */\r
107         RTL_QUERY_REGISTRY_TABLE        table[3];\r
108         UNICODE_STRING                          param_path;\r
109 \r
110         IOU_ENTER( IOU_DBG_DRV );\r
111 \r
112         RtlInitUnicodeString( &param_path, NULL );\r
113         param_path.MaximumLength = p_registry_path->Length + \r
114                 sizeof(L"\\Parameters");\r
115         param_path.Buffer = cl_zalloc( param_path.MaximumLength );\r
116         if( !param_path.Buffer )\r
117         {\r
118                 IOU_PRINT_EXIT( TRACE_LEVEL_ERROR,IOU_DBG_ERROR,\r
119                         ("Failed to allocate parameters path buffer.\n") );\r
120                 return STATUS_INSUFFICIENT_RESOURCES;\r
121         }\r
122 \r
123         RtlAppendUnicodeStringToString( &param_path, p_registry_path );\r
124         RtlAppendUnicodeToString( &param_path, L"\\Parameters" );\r
125 \r
126         /*\r
127          * Clear the table.  This clears all the query callback pointers,\r
128          * and sets up the terminating table entry.\r
129          */\r
130         cl_memclr( table, sizeof(table) );\r
131 \r
132         /* Setup the table entries. */\r
133         table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
134         table[0].Name = L"DebugLevel";\r
135         table[0].EntryContext = &g_iou_dbg_level;\r
136         table[0].DefaultType = REG_DWORD;\r
137         table[0].DefaultData = &g_iou_dbg_level;\r
138         table[0].DefaultLength = sizeof(ULONG);\r
139 \r
140         table[1].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
141         table[1].Name = L"DebugFlags";\r
142         table[1].EntryContext = &g_iou_dbg_flags;\r
143         table[1].DefaultType = REG_DWORD;\r
144         table[1].DefaultData = &g_iou_dbg_flags;\r
145         table[1].DefaultLength = sizeof(ULONG);\r
146         /* Have at it! */\r
147         status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE,\r
148                 param_path.Buffer, table, NULL, NULL );\r
149 \r
150 #ifndef EVENT_TRACING\r
151         if( g_iou_dbg_flags & IOU_DBG_ERR )\r
152                 g_iou_dbg_flags |= CL_DBG_ERROR;\r
153 #endif\r
154 \r
155         IOU_PRINT( TRACE_LEVEL_INFORMATION, IOU_DBG_DRV,\r
156                 ("debug level %d debug flags 0x%.8x\n",\r
157                 g_iou_dbg_level,\r
158                 g_iou_dbg_flags) );\r
159 \r
160         cl_free( param_path.Buffer );\r
161         IOU_EXIT( IOU_DBG_DRV );\r
162         return status;\r
163 }\r
164 \r
165 \r
166 static NTSTATUS\r
167 iou_sysctl(\r
168         IN                              DEVICE_OBJECT                           *p_dev_obj,\r
169         IN                              IRP                                                     *p_irp )\r
170 {\r
171         NTSTATUS                status;\r
172         cl_pnp_po_ext_t *p_ext;\r
173 \r
174         IOU_ENTER( IOU_DBG_DRV );\r
175 \r
176         CL_ASSERT( p_dev_obj );\r
177         CL_ASSERT( p_irp );\r
178 \r
179         p_ext = p_dev_obj->DeviceExtension;\r
180 \r
181         if( p_ext->p_next_do )\r
182         {\r
183                 IoSkipCurrentIrpStackLocation( p_irp );\r
184                 status = IoCallDriver( p_ext->p_next_do, p_irp );\r
185         }\r
186         else\r
187         {\r
188                 status = p_irp->IoStatus.Status;\r
189                 IoCompleteRequest( p_irp, IO_NO_INCREMENT );\r
190         }\r
191 \r
192         IOU_EXIT( IOU_DBG_DRV );\r
193         return status;\r
194 }\r
195 \r
196 \r
197 static void\r
198 iou_unload(\r
199         IN                              DRIVER_OBJECT                           *p_driver_obj )\r
200 {\r
201         IOU_ENTER( IOU_DBG_DRV );\r
202 \r
203 #if defined(EVENT_TRACING)\r
204         WPP_CLEANUP( p_driver_obj );\r
205 #else\r
206         UNUSED_PARAM( p_driver_obj );\r
207 #endif\r
208 \r
209         CL_DEINIT;\r
210 \r
211         IOU_EXIT( IOU_DBG_DRV );\r
212 }\r
213 \r
214 \r
215 NTSTATUS\r
216 DriverEntry(\r
217         IN                              DRIVER_OBJECT                           *p_driver_obj,\r
218         IN                              UNICODE_STRING                          *p_registry_path )\r
219 {\r
220         NTSTATUS                        status;\r
221 \r
222         IOU_ENTER( IOU_DBG_DRV );\r
223 \r
224 #if defined(EVENT_TRACING)\r
225         WPP_INIT_TRACING( p_driver_obj, p_registry_path );\r
226 #endif\r
227 \r
228         status = CL_INIT;\r
229         if( !NT_SUCCESS(status) )\r
230         {\r
231                 IOU_PRINT_EXIT( TRACE_LEVEL_ERROR, IOU_DBG_ERROR,\r
232                         ("cl_init returned %08X.\n", status) );\r
233                 return status;\r
234         }\r
235 \r
236         /* Store the driver object pointer in the global parameters. */\r
237         iou_globals.p_driver_obj = p_driver_obj;\r
238 \r
239         /* Get the registry values. */\r
240         status = __read_registry( p_registry_path );\r
241         if( !NT_SUCCESS(status) )\r
242         {\r
243                 CL_DEINIT;\r
244                 IOU_PRINT_EXIT( TRACE_LEVEL_ERROR, IOU_DBG_ERROR,\r
245                         ("__read_registry returned %08x.\n", status) );\r
246                 return status;\r
247         }\r
248 \r
249         /* Setup the entry points. */\r
250         p_driver_obj->MajorFunction[IRP_MJ_PNP] = cl_pnp;\r
251         p_driver_obj->MajorFunction[IRP_MJ_POWER] = cl_power;\r
252         p_driver_obj->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = iou_sysctl;\r
253         p_driver_obj->DriverUnload = iou_unload;\r
254         p_driver_obj->DriverExtension->AddDevice = iou_add_device;\r
255 \r
256         IOU_EXIT( IOU_DBG_DRV );\r
257         return STATUS_SUCCESS;\r
258 }\r