win-pvdrivers

view xenpci/xenpci_export.c @ 1022:cd72cd0e1c19

hooking debug doesn't survive hibernate under win8. Remove it.
Remove initial balloon down - doesn't work under xen 4.2 without xenbus being loaded
author James Harper <james.harper@bendigoit.com.au>
date Tue Feb 19 15:11:49 2013 +1100 (2013-02-19)
parents 9fb8690938b3
children b3de9dba6fee
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;
36 FUNCTION_ENTER();
37 //RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
38 FUNCTION_MSG("Read path=%s\n", path);
39 err = XenBus_Read(xpdd, XBT_NIL, path, &value);
40 if (err) {
41 FUNCTION_MSG("Error %s\n", err);
42 XenPci_FreeMem(err);
43 /* this is pretty catastrophic... */
44 /* maybe call the callback with an unknown or something... or just ignore? */
45 FUNCTION_EXIT();
46 return;
47 }
48 FUNCTION_MSG("Read value=%s\n", value);
49 backend_state = atoi(value);
50 XenPci_FreeMem(value);
51 xppdd->device_callback(xppdd->device_callback_context, XN_DEVICE_CALLBACK_BACKEND_STATE, (PVOID)(ULONG_PTR)backend_state);
52 FUNCTION_EXIT();
53 }
55 XN_HANDLE
56 XnOpenDevice(PDEVICE_OBJECT pdo, PXN_DEVICE_CALLBACK callback, PVOID context) {
57 WDFDEVICE device;
58 PXENPCI_PDO_DEVICE_DATA xppdd;
59 PXENPCI_DEVICE_DATA xpdd;
60 PCHAR response;
61 CHAR path[128];
63 FUNCTION_ENTER();
64 device = WdfWdmDeviceGetWdfDeviceHandle(pdo);
65 if (!device) {
66 FUNCTION_MSG("Failed to get WDFDEVICE for %p\n", pdo);
67 return NULL;
68 }
69 xppdd = GetXppdd(device);
70 xpdd = xppdd->xpdd;
71 xppdd->device_callback = callback;
72 xppdd->device_callback_context = context;
73 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
74 response = XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackendStateCallback, xppdd);
75 if (response) {
76 FUNCTION_MSG("XnAddWatch - %s = %s\n", path, response);
77 XenPci_FreeMem(response);
78 xppdd->device_callback = NULL;
79 xppdd->device_callback_context = NULL;
80 FUNCTION_EXIT();
81 return NULL;
82 }
84 FUNCTION_EXIT();
85 return xppdd;
86 }
88 VOID
89 XnCloseDevice(XN_HANDLE handle) {
90 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
91 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
92 PCHAR response;
93 CHAR path[128];
95 FUNCTION_ENTER();
96 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
97 response = XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackendStateCallback, xppdd);
98 if (response) {
99 FUNCTION_MSG("XnRemWatch - %s = %s\n", path, response);
100 XenPci_FreeMem(response);
101 }
102 xppdd->device_callback = NULL;
103 xppdd->device_callback_context = NULL;
104 FUNCTION_EXIT();
105 return;
106 }
108 NTSTATUS
109 XnBindEvent(XN_HANDLE handle, evtchn_port_t *port, PXN_EVENT_CALLBACK callback, PVOID context) {
110 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
111 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
112 *port = EvtChn_AllocUnbound(xpdd, xppdd->backend_id);
113 return EvtChn_Bind(xpdd, *port, callback, context, EVT_ACTION_FLAGS_DEFAULT);
114 }
116 NTSTATUS
117 XnUnbindEvent(XN_HANDLE handle, evtchn_port_t port) {
118 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
119 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
120 EvtChn_Unbind(xpdd, port);
121 EvtChn_Close(xpdd, port);
122 return STATUS_SUCCESS;
123 }
125 grant_ref_t
126 XnGrantAccess(XN_HANDLE handle, uint32_t frame, int readonly, grant_ref_t ref, ULONG tag) {
127 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
128 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
129 return GntTbl_GrantAccess(xpdd, xppdd->backend_id, frame, readonly, ref, tag);
130 }
132 BOOLEAN
133 XnEndAccess(XN_HANDLE handle, grant_ref_t ref, BOOLEAN keepref, ULONG tag) {
134 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
135 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
136 return GntTbl_EndAccess(xpdd, ref, keepref, tag);
137 }
139 grant_ref_t
140 XnAllocateGrant(XN_HANDLE handle, ULONG tag) {
141 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
142 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
143 return GntTbl_GetRef(xpdd, tag);
144 }
146 VOID
147 XnFreeGrant(XN_HANDLE handle, grant_ref_t ref, ULONG tag) {
148 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
149 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
150 GntTbl_PutRef(xpdd, ref, tag);
151 }
153 /* result must be freed with XnFreeMem() */
154 NTSTATUS
155 XnReadString(XN_HANDLE handle, ULONG base, PCHAR path, PCHAR *value) {
156 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
157 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
158 PCHAR response;
159 CHAR full_path[1024];
161 switch(base) {
162 case XN_BASE_FRONTEND:
163 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
164 break;
165 case XN_BASE_BACKEND:
166 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
167 break;
168 case XN_BASE_GLOBAL:
169 full_path[0] = 0;
170 }
171 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
172 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
174 response = XenBus_Read(xpdd, XBT_NIL, full_path, value);
175 if (response) {
176 FUNCTION_MSG("Error reading %s - %s\n", full_path, response);
177 XenPci_FreeMem(response);
178 return STATUS_UNSUCCESSFUL;
179 }
180 return STATUS_SUCCESS;
181 }
183 NTSTATUS
184 XnWriteString(XN_HANDLE handle, ULONG base, PCHAR path, PCHAR value) {
185 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
186 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
187 PCHAR response;
188 CHAR full_path[1024];
190 switch(base) {
191 case XN_BASE_FRONTEND:
192 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
193 break;
194 case XN_BASE_BACKEND:
195 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
196 break;
197 case XN_BASE_GLOBAL:
198 full_path[0] = 0;
199 }
200 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
201 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
203 //FUNCTION_MSG("XnWriteString(%s, %s)\n", full_path, value);
204 response = XenBus_Write(xpdd, XBT_NIL, full_path, value);
205 if (response) {
206 FUNCTION_MSG("XnWriteString - %s = %s\n", full_path, response);
207 XenPci_FreeMem(response);
208 FUNCTION_EXIT();
209 return STATUS_UNSUCCESSFUL;
210 }
211 return STATUS_SUCCESS;
212 }
214 NTSTATUS
215 XnReadInt32(XN_HANDLE handle, ULONG base, PCHAR path, ULONG *value) {
216 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
217 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
218 CHAR full_path[1024];
219 PCHAR response;
220 PCHAR string_value;
222 switch(base) {
223 case XN_BASE_FRONTEND:
224 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
225 break;
226 case XN_BASE_BACKEND:
227 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
228 break;
229 case XN_BASE_GLOBAL:
230 full_path[0] = 0;
231 }
232 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
233 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
235 response = XenBus_Read(xpdd, XBT_NIL, full_path, &string_value);
236 if (response) {
237 FUNCTION_MSG("XnReadInt - %s = %s\n", full_path, response);
238 XenPci_FreeMem(response);
239 FUNCTION_EXIT();
240 return STATUS_UNSUCCESSFUL;
241 }
242 *value = atoi(string_value);
243 return STATUS_SUCCESS;
244 }
246 NTSTATUS
247 XnWriteInt32(XN_HANDLE handle, ULONG base, PCHAR path, ULONG value) {
248 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
249 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
250 CHAR full_path[1024];
251 PCHAR response;
253 switch(base) {
254 case XN_BASE_FRONTEND:
255 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
256 break;
257 case XN_BASE_BACKEND:
258 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
259 break;
260 case XN_BASE_GLOBAL:
261 full_path[0] = 0;
262 }
263 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
264 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
266 //FUNCTION_MSG("XnWriteInt32(%s, %d)\n", full_path, value);
267 response = XenBus_Printf(xpdd, XBT_NIL, full_path, "%d", value);
268 if (response) {
269 FUNCTION_MSG("XnWriteInt - %s = %s\n", full_path, response);
270 XenPci_FreeMem(response);
271 FUNCTION_EXIT();
272 return STATUS_UNSUCCESSFUL;
273 }
274 return STATUS_SUCCESS;
275 }
277 NTSTATUS
278 XnReadInt64(XN_HANDLE handle, ULONG base, PCHAR path, ULONGLONG *value) {
279 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
280 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
281 CHAR full_path[1024];
282 PCHAR response;
283 PCHAR string_value;
284 PCHAR ptr;
286 switch(base) {
287 case XN_BASE_FRONTEND:
288 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
289 break;
290 case XN_BASE_BACKEND:
291 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
292 break;
293 case XN_BASE_GLOBAL:
294 full_path[0] = 0;
295 }
296 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
297 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
299 response = XenBus_Read(xpdd, XBT_NIL, full_path, &string_value);
300 if (response) {
301 FUNCTION_MSG("XnReadInt - %s = %s\n", full_path, response);
302 XenPci_FreeMem(response);
303 FUNCTION_EXIT();
304 return STATUS_UNSUCCESSFUL;
305 }
306 *value = 0;
307 for (ptr = string_value; *ptr && *ptr >= '0' && *ptr <= '9'; ptr++) {
308 *value *= 10;
309 *value += (*ptr) - '0';
310 }
311 return STATUS_SUCCESS;
312 }
314 NTSTATUS
315 XnWriteInt64(XN_HANDLE handle, ULONG base, PCHAR path, ULONGLONG value) {
316 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
317 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
318 CHAR full_path[1024];
319 PCHAR response;
321 switch(base) {
322 case XN_BASE_FRONTEND:
323 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
324 break;
325 case XN_BASE_BACKEND:
326 RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
327 break;
328 case XN_BASE_GLOBAL:
329 full_path[0] = 0;
330 }
331 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
332 RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
334 response = XenBus_Printf(xpdd, XBT_NIL, full_path, "%I64d", value);
335 if (response) {
336 FUNCTION_MSG("XnWriteInt - %s = %s\n", full_path, response);
337 XenPci_FreeMem(response);
338 FUNCTION_EXIT();
339 return STATUS_UNSUCCESSFUL;
340 }
341 return STATUS_SUCCESS;
342 }
344 NTSTATUS
345 XnNotify(XN_HANDLE handle, evtchn_port_t port) {
346 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
347 PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
348 return EvtChn_Notify(xpdd, port);
349 }
351 /* called at PASSIVE_LEVEL */
352 VOID
353 XnGetValue(XN_HANDLE handle, ULONG value_type, PVOID value) {
354 PXENPCI_PDO_DEVICE_DATA xppdd = handle;
355 //PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
356 DECLARE_UNICODE_STRING_SIZE(my_device_name, 128);
357 ULONG i;
359 switch (value_type) {
360 case XN_VALUE_TYPE_QEMU_HIDE_FLAGS:
361 *(PULONG)value = (ULONG)qemu_hide_flags_value;
362 break;
363 case XN_VALUE_TYPE_QEMU_FILTER:
364 *(PULONG)value = FALSE;
365 RtlUnicodeStringPrintf(&my_device_name, L"#%S#", xppdd->device);
366 for (i = 0; i < WdfCollectionGetCount(qemu_hide_devices); i++) {
367 WDFSTRING wdf_string = WdfCollectionGetItem(qemu_hide_devices, i);
368 UNICODE_STRING hide_device_name;
369 WdfStringGetUnicodeString(wdf_string, &hide_device_name);
370 if (RtlCompareUnicodeString(&hide_device_name, &my_device_name, TRUE) != 0) {
371 *(PULONG)value = TRUE;
372 break;
373 }
374 }
375 break;
376 default:
377 FUNCTION_MSG("GetValue unknown type %d\n", value_type);
378 break;
379 }
380 }
382 NTSTATUS
383 XnDebugPrint(PCHAR format, ...) {
384 NTSTATUS status;
385 va_list args;
387 va_start(args, format);
388 status = XenPci_DebugPrintV(format, args);
389 va_end(args);
391 return status;
392 }
394 VOID
395 XnPrintDump() {
396 KBUGCHECK_DATA bugcheck_data;
398 bugcheck_data.BugCheckDataSize = sizeof(bugcheck_data);
399 AuxKlibGetBugCheckData(&bugcheck_data);
400 if (bugcheck_data.BugCheckCode != 0) {
401 FUNCTION_MSG("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);
402 }
403 }