1 /*++\r
2 Copyright (c) Texas Instruments Inc. All Rights Reserved.\r
3 Sample code for Dual LED FLASH LM3643.\r
4 \r
5 The MIT License (MIT)\r
6 \r
7 Permission is hereby granted, free of charge, to any person obtaining a copy\r
8 of this software and associated documentation files (the "Software"), to deal\r
9 in the Software without restriction, including without limitation the rights\r
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
11 copies of the Software, and to permit persons to whom the Software is\r
12 furnished to do so, subject to the following conditions:\r
13 \r
14 The above copyright notice and this permission notice shall be included in\r
15 all copies or substantial portions of the Software.\r
16 \r
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
23 THE SOFTWARE.\r
24 \r
25 Module Name:\r
26 \r
27 driver.c\r
28 \r
29 Abstract:\r
30 \r
31 This file contains the driver entry points and callbacks.\r
32 \r
33 Environment:\r
34 \r
35 Kernel-mode Driver Framework\r
36 \r
37 --*/\r
38 \r
39 #include "driver.h"\r
40 #include "driver.tmh"\r
41 #include "Public.h"\r
42 \r
43 #ifdef ALLOC_PRAGMA\r
44 #pragma alloc_text (INIT, DriverEntry)\r
45 #pragma alloc_text (PAGE, TxnwLedLm3643EvtDeviceAdd)\r
46 #pragma alloc_text (PAGE, TxnwLedLm3643EvtDriverContextCleanup)\r
47 #endif\r
49 #define TXN_DEVICE_NAME L"TxnwLedLm3643"\r
50 \r
51 NTSTATUS\r
52 DriverEntry(\r
53 _In_ PDRIVER_OBJECT DriverObject,\r
54 _In_ PUNICODE_STRING RegistryPath\r
55 )\r
56 /*++\r
57 \r
58 Routine Description:\r
59 DriverEntry initializes the driver and is the first routine called by the\r
60 system after the driver is loaded. DriverEntry specifies the other entry\r
61 points in the function driver, such as EvtDevice and DriverUnload.\r
62 \r
63 Parameters Description:\r
64 \r
65 DriverObject - represents the instance of the function driver that is loaded\r
66 into memory. DriverEntry must initialize members of DriverObject before it\r
67 returns to the caller. DriverObject is allocated by the system before the\r
68 driver is loaded, and it is released by the system after the system unloads\r
69 the function driver from memory.\r
70 \r
71 RegistryPath - represents the driver specific path in the Registry.\r
72 The function driver can use the path to store driver related data between\r
73 reboots. The path does not store hardware instance specific data.\r
74 \r
75 Return Value:\r
76 \r
77 STATUS_SUCCESS if successful,\r
78 STATUS_UNSUCCESSFUL otherwise.\r
79 \r
80 --*/\r
81 {\r
82 WDF_DRIVER_CONFIG config;\r
83 NTSTATUS status;\r
84 WDF_OBJECT_ATTRIBUTES attributes;\r
85 \r
86 //\r
87 // Initialize WPP Tracing\r
88 //\r
89 WPP_INIT_TRACING( DriverObject, RegistryPath );\r
90 \r
91 \r
92 //\r
93 // Register a cleanup callback so that we can call WPP_CLEANUP when\r
94 // the framework driver object is deleted during driver unload.\r
95 //\r
96 WDF_OBJECT_ATTRIBUTES_INIT(&attributes);\r
97 attributes.EvtCleanupCallback = TxnwLedLm3643EvtDriverContextCleanup;\r
98 \r
99 WDF_DRIVER_CONFIG_INIT(&config,\r
100 TxnwLedLm3643EvtDeviceAdd\r
101 );\r
102 \r
103 status = WdfDriverCreate(DriverObject,\r
104 RegistryPath,\r
105 &attributes,\r
106 &config,\r
107 WDF_NO_HANDLE\r
108 );\r
109 \r
110 if (!NT_SUCCESS(status)) {\r
111 WPP_CLEANUP(DriverObject);\r
112 return status;\r
113 }\r
114 \r
115 return status;\r
116 }\r
117 \r
118 NTSTATUS\r
119 TxnwLedLm3643EvtDeviceAdd(\r
120 _In_ WDFDRIVER Driver,\r
121 _Inout_ PWDFDEVICE_INIT DeviceInit\r
122 )\r
123 /*++\r
124 Routine Description:\r
125 \r
126 EvtDeviceAdd is called by the framework in response to AddDevice\r
127 call from the PnP manager. We create and initialize a device object to\r
128 represent a new instance of the device.\r
129 \r
130 Arguments:\r
131 \r
132 Driver - Handle to a framework driver object created in DriverEntry\r
133 \r
134 DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.\r
135 \r
136 Return Value:\r
137 \r
138 NTSTATUS\r
139 \r
140 --*/\r
141 {\r
142 WDF_OBJECT_ATTRIBUTES attributes;\r
143 PDEVICE_EXTENSION devContext;\r
144 WDFDEVICE fxDevice;\r
145 WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;\r
146 WDF_IO_QUEUE_CONFIG queueConfig;\r
147 NTSTATUS status;\r
148 \r
149 \r
150 UNREFERENCED_PARAMETER(Driver);\r
151 \r
152 PAGED_CODE();\r
153 \r
154 WdfDeviceInitSetPowerPolicyOwnership(DeviceInit, FALSE);\r
155 //\r
156 // This driver handles D0 Entry and Exit to power on and off the\r
157 // controller. It also handles prepare/release hardware so that it \r
158 // can acquire and free SPB resources needed to communicate with the \r
159 // touch controller.\r
160 //\r
161 WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);\r
162 \r
163 pnpPowerCallbacks.EvtDeviceD0Entry = OnD0Entry;\r
164 pnpPowerCallbacks.EvtDeviceD0Exit = OnD0Exit;\r
165 pnpPowerCallbacks.EvtDevicePrepareHardware = OnPrepareHardware;\r
166 pnpPowerCallbacks.EvtDeviceReleaseHardware = OnReleaseHardware;\r
167 \r
168 WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);\r
169 \r
170 //\r
171 // Create a framework device object. This call will in turn create\r
172 // a WDM device object, attach to the lower stack, and set the\r
173 // appropriate flags and attributes.\r
174 //\r
175 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_EXTENSION);\r
176 \r
177 status = WdfDeviceCreate(&DeviceInit, &attributes, &fxDevice);\r
178 \r
179 if (!NT_SUCCESS(status))\r
180 {\r
181 goto exit;\r
182 }\r
183 \r
184 devContext = GetDeviceContext(fxDevice);\r
185 devContext->FxDevice = fxDevice;\r
186 \r
187 //\r
188 // Create a parallel dispatch queue to handle requests\r
189 //\r
190 WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(\r
191 &queueConfig,\r
192 WdfIoQueueDispatchSequential);\r
193 \r
194 queueConfig.EvtIoDeviceControl = OnDeviceControl;\r
195 queueConfig.PowerManaged = WdfFalse;\r
196 \r
197 status = WdfIoQueueCreate(\r
198 fxDevice,\r
199 &queueConfig,\r
200 WDF_NO_OBJECT_ATTRIBUTES,\r
201 &devContext->DefaultQueue);\r
202 \r
203 if (!NT_SUCCESS(status))\r
204 {\r
205 goto exit;\r
206 }\r
207 \r
208 //\r
209 // Register a manual I/O queue for Read Requests. This queue will be used \r
210 // for storing read-requests until data is available to complete them.\r
211 //\r
212 WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual);\r
213 \r
214 queueConfig.PowerManaged = WdfFalse;\r
215 \r
216 status = WdfIoQueueCreate(\r
217 fxDevice,\r
218 &queueConfig,\r
219 WDF_NO_OBJECT_ATTRIBUTES,\r
220 &devContext->PingPongQueue);\r
221 \r
222 if (!NT_SUCCESS(status))\r
223 {\r
224 goto exit;\r
225 }\r
226 //\r
227 // Register one last manual I/O queue for parking idle power\r
228 // requests. This queue stores idle requests until they're cancelled,\r
229 // and could be used to complete a wait/wake request.\r
230 //\r
231 \r
232 WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual);\r
233 \r
234 queueConfig.PowerManaged = WdfFalse;\r
235 \r
236 status = WdfIoQueueCreate(\r
237 fxDevice,\r
238 &queueConfig,\r
239 WDF_NO_OBJECT_ATTRIBUTES,\r
240 &devContext->IdleQueue\r
241 );\r
242 \r
243 if (!NT_SUCCESS(status))\r
244 {\r
245 goto exit;\r
246 }\r
247 \r
248 DECLARE_CONST_UNICODE_STRING(symbolicLink, L"\\DosDevices\\" LM3643_DEVICE_NAME);\r
249 status = WdfDeviceCreateSymbolicLink(fxDevice, &symbolicLink);\r
250 \r
251 exit:\r
252 return status;\r
253 }\r
254 \r
255 VOID\r
256 TxnwLedLm3643EvtDriverContextCleanup(\r
257 _In_ WDFOBJECT DriverObject\r
258 )\r
259 /*++\r
260 Routine Description:\r
261 \r
262 Free all the resources allocated in DriverEntry.\r
263 \r
264 Arguments:\r
265 \r
266 DriverObject - handle to a WDF Driver object.\r
267 \r
268 Return Value:\r
269 \r
270 VOID.\r
271 \r
272 --*/\r
273 {\r
274 UNREFERENCED_PARAMETER(DriverObject);\r
275 \r
276 PAGED_CODE ();\r
277 \r
278 WPP_CLEANUP( WdfDriverWdmGetDriverObject( (WDFDRIVER) DriverObject) );\r
279 }\r