win-pvdrivers

view xenpci/xenpci_export.c @ 1047:0248483f90cc

Turn some debug prints back on for free builds
author James Harper <james.harper@bendigoit.com.au>
date Mon May 13 20:50:48 2013 +1000 (2013-05-13)
parents b3de9dba6fee
children 471c94d04d8a
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
3 Copyright (C) 2012 James Harper
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
20 #include "xenpci.h"
21 #include <aux_klib.h>
23 ULONG
24 XnGetVersion() {
25 return 1;
26 }
28 VOID
29 XenPci_BackendStateCallback(char *path, PVOID context) {
30 PXENPCI_PDO_DEVICE_DATA xppdd = context;
31 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
32 PCHAR err;
33 PCHAR value;
34 ULONG backend_state;
35 ULONG frontend_state;
37 FUNCTION_ENTER();
38 //RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
39 FUNCTION_MSG("Read path=%s\n", path);
40 err = XenBus_Read(xpdd, XBT_NIL, path, &value);
41 if (err) {
42 FUNCTION_MSG("Error %s\n", err);
43 XenPci_FreeMem(err);
44 /* this is pretty catastrophic... */
45 /* maybe call the callback with an unknown or something... or just ignore? */
46 FUNCTION_EXIT();
47 return;
48 }
49 FUNCTION_MSG("Read value=%s\n", value);
50 backend_state = atoi(value);
51 XenPci_FreeMem(value);
52 if (backend_state == XenbusStateClosing) {
53 /* check to see if transition to closing was initiated by backend */
54 CHAR frontend_state_path[128];
55 FUNCTION_MSG("backend path is closing. checking frontend path\n");
56 RtlStringCbCopyA(frontend_state_path, ARRAY_SIZE(frontend_state_path), xppdd->path);
57 RtlStringCbCatA(frontend_state_path, ARRAY_SIZE(frontend_state_path), "/state");
58 err = XenBus_Read(xpdd, XBT_NIL, frontend_state_path, &value);
59 if (err) {
60 FUNCTION_MSG("Error %s\n", err);
61 XenPci_FreeMem(err);
62 FUNCTION_EXIT();
63 return;
64 }
65 FUNCTION_MSG("Read value=%s\n", value);
66 frontend_state = atoi(value);
67 XenPci_FreeMem(value);
68 if (frontend_state == XenbusStateConnected) {
69 FUNCTION_MSG("initiated by backend. Requesting eject\n");
70 /* frontend is still connected. disconnection was initiated by backend */
71 WdfPdoRequestEject(xppdd->wdf_device);
72 }
73 }
74 xppdd->device_callback(xppdd->device_callback_context, XN_DEVICE_CALLBACK_BACKEND_STATE, (PVOID)(ULONG_PTR)backend_state);
75 FUNCTION_EXIT();
76 }
78 XN_HANDLE
79 XnOpenDevice(PDEVICE_OBJECT pdo, PXN_DEVICE_CALLBACK callback, PVOID context) {
80 WDFDEVICE device;
81 PXENPCI_PDO_DEVICE_DATA xppdd;
82 PXENPCI_DEVICE_DATA xpdd;
83 PCHAR response;
84 CHAR path[128];
86 FUNCTION_ENTER();
87 device = WdfWdmDeviceGetWdfDeviceHandle(pdo);
88 if (!device) {
89 FUNCTION_MSG("Failed to get WDFDEVICE for %p\n", pdo);
90 return NULL;
91 }
92 xppdd = GetXppdd(device);
93 xpdd = xppdd->xpdd;
94 xppdd->device_callback = callback;
95 xppdd->device_callback_context = context;
96 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
97 response = XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackendStateCallback, xppdd);
98 if (response) {
99 FUNCTION_MSG("XnAddWatch - %s = %s\n", path, response);
100 XenPci_FreeMem(response);
101 xppdd->device_callback = NULL;
102 xppdd->device_callback_context = NULL;
103 FUNCTION_EXIT();
104 return NULL;
105 }
107 FUNCTION_EXIT();
108 return xppdd;
109 }
111 VOID
112 XnCloseDevice(XN_HANDLE handle) {
113 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
114 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
115 PCHAR response;
116 CHAR path[128];
118 FUNCTION_ENTER();
119 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
120 response = XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackendStateCallback, xppdd);
121 if (response) {
122 FUNCTION_MSG("XnRemWatch - %s = %s\n", path, response);
123 XenPci_FreeMem(response);
124 }
125 xppdd->device_callback = NULL;
126 xppdd->device_callback_context = NULL;
127 FUNCTION_EXIT();
128 return;
129 }
131 NTSTATUS
132 XnBindEvent(XN_HANDLE handle, evtchn_port_t *port, PXN_EVENT_CALLBACK callback, PVOID context) {
133 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
134 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
135 *port = EvtChn_AllocUnbound(xpdd, xppdd->backend_id);
136 return EvtChn_Bind(xpdd, *port, callback, context, EVT_ACTION_FLAGS_DEFAULT);
137 }
139 NTSTATUS
140 XnUnbindEvent(XN_HANDLE handle, evtchn_port_t port) {
141 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
142 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
143 EvtChn_Unbind(xpdd, port);
144 EvtChn_Close(xpdd, port);
145 return STATUS_SUCCESS;
146 }
148 grant_ref_t
149 XnGrantAccess(XN_HANDLE handle, uint32_t frame, int readonly, grant_ref_t ref, ULONG tag) {
150 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
151 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
152 return GntTbl_GrantAccess(xpdd, xppdd->backend_id, frame, readonly, ref, tag);
153 }
155 BOOLEAN
156 XnEndAccess(XN_HANDLE handle, grant_ref_t ref, BOOLEAN keepref, ULONG tag) {
157 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
158 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
159 return GntTbl_EndAccess(xpdd, ref, keepref, tag);
160 }
162 grant_ref_t
163 XnAllocateGrant(XN_HANDLE handle, ULONG tag) {
164 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
165 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
166 return GntTbl_GetRef(xpdd, tag);
167 }
169 VOID
170 XnFreeGrant(XN_HANDLE handle, grant_ref_t ref, ULONG tag) {
171 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
172 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
173 GntTbl_PutRef(xpdd, ref, tag);
174 }
176 /* result must be freed with XnFreeMem() */
177 NTSTATUS
178 XnReadString(XN_HANDLE handle, ULONG base, PCHAR path, PCHAR *value) {
179 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
180 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
181 PCHAR response;
182 CHAR full_path[1024];
184 switch(base) {
185 case XN_BASE_FRONTEND:
186 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
187 break;
188 case XN_BASE_BACKEND:
189 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
190 break;
191 case XN_BASE_GLOBAL:
192 full_path[0] = 0;
193 }
194 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
195 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
197 response = XenBus_Read(xpdd, XBT_NIL, full_path, value);
198 if (response) {
199 FUNCTION_MSG("Error reading %s - %s\n", full_path, response);
200 XenPci_FreeMem(response);
201 return STATUS_UNSUCCESSFUL;
202 }
203 return STATUS_SUCCESS;
204 }
206 NTSTATUS
207 XnWriteString(XN_HANDLE handle, ULONG base, PCHAR path, PCHAR value) {
208 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
209 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
210 PCHAR response;
211 CHAR full_path[1024];
213 switch(base) {
214 case XN_BASE_FRONTEND:
215 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
216 break;
217 case XN_BASE_BACKEND:
218 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
219 break;
220 case XN_BASE_GLOBAL:
221 full_path[0] = 0;
222 }
223 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
224 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
226 //FUNCTION_MSG("XnWriteString(%s, %s)\n", full_path, value);
227 response = XenBus_Write(xpdd, XBT_NIL, full_path, value);
228 if (response) {
229 FUNCTION_MSG("XnWriteString - %s = %s\n", full_path, response);
230 XenPci_FreeMem(response);
231 FUNCTION_EXIT();
232 return STATUS_UNSUCCESSFUL;
233 }
234 return STATUS_SUCCESS;
235 }
237 NTSTATUS
238 XnReadInt32(XN_HANDLE handle, ULONG base, PCHAR path, ULONG *value) {
239 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
240 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
241 CHAR full_path[1024];
242 PCHAR response;
243 PCHAR string_value;
245 switch(base) {
246 case XN_BASE_FRONTEND:
247 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
248 break;
249 case XN_BASE_BACKEND:
250 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
251 break;
252 case XN_BASE_GLOBAL:
253 full_path[0] = 0;
254 }
255 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
256 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
258 response = XenBus_Read(xpdd, XBT_NIL, full_path, &string_value);
259 if (response) {
260 FUNCTION_MSG("XnReadInt - %s = %s\n", full_path, response);
261 XenPci_FreeMem(response);
262 FUNCTION_EXIT();
263 return STATUS_UNSUCCESSFUL;
264 }
265 *value = atoi(string_value);
266 return STATUS_SUCCESS;
267 }
269 NTSTATUS
270 XnWriteInt32(XN_HANDLE handle, ULONG base, PCHAR path, ULONG value) {
271 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
272 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
273 CHAR full_path[1024];
274 PCHAR response;
276 switch(base) {
277 case XN_BASE_FRONTEND:
278 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
279 break;
280 case XN_BASE_BACKEND:
281 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
282 break;
283 case XN_BASE_GLOBAL:
284 full_path[0] = 0;
285 }
286 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
287 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
289 //FUNCTION_MSG("XnWriteInt32(%s, %d)\n", full_path, value);
290 response = XenBus_Printf(xpdd, XBT_NIL, full_path, "%d", value);
291 if (response) {
292 FUNCTION_MSG("XnWriteInt - %s = %s\n", full_path, response);
293 XenPci_FreeMem(response);
294 FUNCTION_EXIT();
295 return STATUS_UNSUCCESSFUL;
296 }
297 return STATUS_SUCCESS;
298 }
300 NTSTATUS
301 XnReadInt64(XN_HANDLE handle, ULONG base, PCHAR path, ULONGLONG *value) {
302 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
303 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
304 CHAR full_path[1024];
305 PCHAR response;
306 PCHAR string_value;
307 PCHAR ptr;
309 switch(base) {
310 case XN_BASE_FRONTEND:
311 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
312 break;
313 case XN_BASE_BACKEND:
314 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
315 break;
316 case XN_BASE_GLOBAL:
317 full_path[0] = 0;
318 }
319 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
320 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
322 response = XenBus_Read(xpdd, XBT_NIL, full_path, &string_value);
323 if (response) {
324 FUNCTION_MSG("XnReadInt - %s = %s\n", full_path, response);
325 XenPci_FreeMem(response);
326 FUNCTION_EXIT();
327 return STATUS_UNSUCCESSFUL;
328 }
329 *value = 0;
330 for (ptr = string_value; *ptr && *ptr >= '0' && *ptr <= '9'; ptr++) {
331 *value *= 10;
332 *value += (*ptr) - '0';
333 }
334 return STATUS_SUCCESS;
335 }
337 NTSTATUS
338 XnWriteInt64(XN_HANDLE handle, ULONG base, PCHAR path, ULONGLONG value) {
339 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
340 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
341 CHAR full_path[1024];
342 PCHAR response;
344 switch(base) {
345 case XN_BASE_FRONTEND:
346 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
347 break;
348 case XN_BASE_BACKEND:
349 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
350 break;
351 case XN_BASE_GLOBAL:
352 full_path[0] = 0;
353 }
354 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
355 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
357 response = XenBus_Printf(xpdd, XBT_NIL, full_path, "%I64d", value);
358 if (response) {
359 FUNCTION_MSG("XnWriteInt - %s = %s\n", full_path, response);
360 XenPci_FreeMem(response);
361 FUNCTION_EXIT();
362 return STATUS_UNSUCCESSFUL;
363 }
364 return STATUS_SUCCESS;
365 }
367 NTSTATUS
368 XnNotify(XN_HANDLE handle, evtchn_port_t port) {
369 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
370 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
371 return EvtChn_Notify(xpdd, port);
372 }
374 /* called at PASSIVE_LEVEL */
375 VOID
376 XnGetValue(XN_HANDLE handle, ULONG value_type, PVOID value) {
377 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
378 //PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
379 DECLARE_UNICODE_STRING_SIZE(my_device_name, 128);
380 ULONG i;
382 switch (value_type) {
383 case XN_VALUE_TYPE_QEMU_HIDE_FLAGS:
384 *(PULONG)value = (ULONG)qemu_hide_flags_value;
385 break;
386 case XN_VALUE_TYPE_QEMU_FILTER:
387 *(PULONG)value = FALSE;
388 RtlUnicodeStringPrintf(&my_device_name, L"#%S#", xppdd->device);
389 for (i = 0; i < WdfCollectionGetCount(qemu_hide_devices); i++) {
390 WDFSTRING wdf_string = WdfCollectionGetItem(qemu_hide_devices, i);
391 UNICODE_STRING hide_device_name;
392 WdfStringGetUnicodeString(wdf_string, &hide_device_name);
393 if (RtlCompareUnicodeString(&hide_device_name, &my_device_name, TRUE) != 0) {
394 *(PULONG)value = TRUE;
395 break;
396 }
397 }
398 break;
399 default:
400 FUNCTION_MSG("GetValue unknown type %d\n", value_type);
401 break;
402 }
403 }
405 NTSTATUS
406 XnDebugPrint(PCHAR format, ...) {
407 NTSTATUS status;
408 va_list args;
410 va_start(args, format);
411 status = XenPci_DebugPrintV(format, args);
412 va_end(args);
414 return status;
415 }
417 VOID
418 XnPrintDump() {
419 KBUGCHECK_DATA bugcheck_data;
421 bugcheck_data.BugCheckDataSize = sizeof(bugcheck_data);
422 AuxKlibGetBugCheckData(&bugcheck_data);
423 if (bugcheck_data.BugCheckCode != 0) {
424 /* use XnDebugPrint so this gets printed even not in debug mode */
425 XnDebugPrint("Bug check 0x%08x (0x%p, 0x%p, 0x%p, 0x%p)\n", bugcheck_data.BugCheckCode, bugcheck_data.Parameter1, bugcheck_data.Parameter2, bugcheck_data.Parameter3, bugcheck_data.Parameter4);
426 }
427 }