win-pvdrivers

view xenpci/xenpci.c @ 38:a5617e7e9f54

fixups from manual merge
author Andy Grover <andy.grover@oracle.com>
date Wed Dec 05 11:37:53 2007 -0800 (2007-12-05)
parents 3ac5c4431dbb
children 94d0f2823b42
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
3 Copyright (C) 2007 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 "hypercall.h"
22 #include <stdlib.h>
24 #define SHUTDOWN_PATH "control/shutdown"
25 #define BALLOON_PATH "memory/target"
27 DRIVER_INITIALIZE DriverEntry;
28 static NTSTATUS
29 XenPCI_AddDevice(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit);
30 static NTSTATUS
31 XenPCI_PrepareHardware(WDFDEVICE hDevice, WDFCMRESLIST Resources, WDFCMRESLIST ResourcesTranslated);
32 static NTSTATUS
33 XenPCI_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated);
34 static NTSTATUS
35 XenPCI_D0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
36 static NTSTATUS
37 XenPCI_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
38 static NTSTATUS
39 XenPCI_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState);
40 static NTSTATUS
41 XenPCI_D0ExitPreInterruptsDisabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState);
42 static VOID
43 XenPCI_IoDefault(WDFQUEUE Queue, WDFREQUEST Request);
44 static NTSTATUS
45 XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice);
46 static NTSTATUS
47 XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice);
48 static NTSTATUS
49 XenPCI_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit);
50 static NTSTATUS
51 XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
52 static NTSTATUS
53 XenPCI_FilterRemoveResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
54 static NTSTATUS
55 XenPCI_FilterAddResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList);
56 static NTSTATUS
57 XenPCI_RemoveAddedResources(WDFDEVICE Device, WDFCMRESLIST ResourcesRaw, WDFCMRESLIST ResourcesTranslated);
59 static VOID
60 XenBus_ShutdownHandler(char *Path, PVOID Data);
61 static VOID
62 XenBus_BalloonHandler(char *Path, PVOID Data);
63 static VOID
64 XenPCI_XenBusWatchHandler(char *Path, PVOID Data);
66 #ifdef ALLOC_PRAGMA
67 #pragma alloc_text (INIT, DriverEntry)
68 #pragma alloc_text (PAGE, XenPCI_AddDevice)
69 #endif
71 /* Global (driver-wide) variables */
72 static BOOLEAN AutoEnumerate;
74 NTSTATUS
75 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
76 {
77 WDF_DRIVER_CONFIG config;
78 NTSTATUS status;
79 UNICODE_STRING RegKeyName;
80 UNICODE_STRING RegValueName;
81 HANDLE RegHandle;
82 OBJECT_ATTRIBUTES RegObjectAttributes;
83 char Buf[200];
84 ULONG BufLen = 200;
85 PKEY_VALUE_PARTIAL_INFORMATION KeyPartialValue;
86 int State = 0;
87 int StartPos = 0;
88 WCHAR *SystemStartOptions;
89 size_t SystemStartOptionsLen;
90 size_t i;
92 KdPrint((__DRIVER_NAME " --> DriverEntry\n"));
94 RtlInitUnicodeString(&RegKeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
95 InitializeObjectAttributes(&RegObjectAttributes, &RegKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
96 status = ZwOpenKey(&RegHandle, KEY_READ, &RegObjectAttributes);
97 if(!NT_SUCCESS(status))
98 {
99 KdPrint((__DRIVER_NAME " ZwOpenKey returned %08x\n", status));
100 }
102 RtlInitUnicodeString(&RegValueName, L"SystemStartOptions");
103 status = ZwQueryValueKey(RegHandle, &RegValueName, KeyValuePartialInformation, Buf, BufLen, &BufLen);
104 if(!NT_SUCCESS(status))
105 {
106 KdPrint((__DRIVER_NAME " ZwQueryKeyValue returned %08x\n", status));
107 }
108 //KdPrint((__DRIVER_NAME " BufLen = %d\n", BufLen));
109 KeyPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
110 KdPrint((__DRIVER_NAME " Buf = %ws\n", KeyPartialValue->Data));
111 SystemStartOptions = (WCHAR *)KeyPartialValue->Data;
113 AutoEnumerate = FALSE;
115 RtlStringCbLengthW(SystemStartOptions, KeyPartialValue->DataLength, &SystemStartOptionsLen);
117 for (i = 0; i <= SystemStartOptionsLen/2; i++)
118 {
119 //KdPrint((__DRIVER_NAME " pos = %d, state = %d, char = '%wc' (%d)\n", i, State, SystemStartOptions[i], SystemStartOptions[i]));
121 switch (State)
122 {
123 case 0:
124 if (SystemStartOptions[i] == L'G')
125 {
126 StartPos = i;
127 State = 2;
128 } else if (SystemStartOptions[i] != L' ')
129 {
130 State = 1;
131 }
132 break;
133 case 1:
134 if (SystemStartOptions[i] == L' ')
135 State = 0;
136 break;
137 case 2:
138 if (SystemStartOptions[i] == L'P')
139 State = 3;
140 else
141 State = 0;
142 break;
143 case 3:
144 if (SystemStartOptions[i] == L'L')
145 State = 4;
146 else
147 State = 0;
148 break;
149 case 4:
150 if (SystemStartOptions[i] == L'P')
151 State = 5;
152 else
153 State = 0;
154 break;
155 case 5:
156 if (SystemStartOptions[i] == L'V')
157 State = 6;
158 else
159 State = 0;
160 break;
161 case 6:
162 if (SystemStartOptions[i] == L' ' || SystemStartOptions[i] == 0)
163 AutoEnumerate = TRUE;
164 State = 0;
165 break;
166 }
167 }
169 KdPrint((__DRIVER_NAME " AutoEnumerate = %d\n", AutoEnumerate));
171 WDF_DRIVER_CONFIG_INIT(&config, XenPCI_AddDevice);
172 status = WdfDriverCreate(
173 DriverObject,
174 RegistryPath,
175 WDF_NO_OBJECT_ATTRIBUTES,
176 &config,
177 WDF_NO_HANDLE);
178 if(!NT_SUCCESS(status))
179 {
180 KdPrint((__DRIVER_NAME " WdfDriverCreate failed with status 0x%08x\n", status));
181 }
183 KdPrint((__DRIVER_NAME " <-- DriverEntry\n"));
185 return status;
186 }
188 static NTSTATUS
189 get_hypercall_stubs(WDFDEVICE Device)
190 {
191 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
192 DWORD32 cpuid_output[4];
193 char xensig[13];
194 ULONG i;
195 ULONG pages;
196 ULONG msr;
198 __cpuid(cpuid_output, 0x40000000);
199 *(ULONG*)(xensig + 0) = cpuid_output[1];
200 *(ULONG*)(xensig + 4) = cpuid_output[2];
201 *(ULONG*)(xensig + 8) = cpuid_output[3];
202 xensig[12] = '\0';
203 KdPrint((__DRIVER_NAME " Xen Signature = %s, EAX = 0x%08x\n", xensig, cpuid_output[0]));
205 __cpuid(cpuid_output, 0x40000002);
206 pages = cpuid_output[0];
207 msr = cpuid_output[1];
208 //KdPrint((__DRIVER_NAME " Hypercall area is %u pages.\n", pages));
210 xpdd->hypercall_stubs = ExAllocatePoolWithTag(NonPagedPool, pages * PAGE_SIZE, XENPCI_POOL_TAG);
211 //KdPrint((__DRIVER_NAME " Hypercall area at %08x\n", hypercall_stubs));
213 if (!xpdd->hypercall_stubs)
214 return 1;
215 for (i = 0; i < pages; i++) {
216 ULONG pfn;
217 //pfn = vmalloc_to_pfn((char *)hypercall_stubs + i * PAGE_SIZE);
218 pfn = (ULONG)(MmGetPhysicalAddress(xpdd->hypercall_stubs + i * PAGE_SIZE).QuadPart >> PAGE_SHIFT);
219 //KdPrint((__DRIVER_NAME " pfn = %08X\n", pfn));
220 __writemsr(msr, ((ULONGLONG)pfn << PAGE_SHIFT) + i);
221 }
222 return STATUS_SUCCESS;
223 }
225 PHYSICAL_ADDRESS
226 XenPCI_AllocMMIO(WDFDEVICE Device, ULONG len)
227 {
228 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
230 PHYSICAL_ADDRESS addr;
232 addr = xpdd->platform_mmio_addr;
233 addr.QuadPart += xpdd->platform_mmio_alloc;
234 xpdd->platform_mmio_alloc += len;
236 return addr;
237 }
239 static int
240 init_xen_info(WDFDEVICE Device)
241 {
242 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
243 struct xen_add_to_physmap xatp;
244 int ret;
245 PHYSICAL_ADDRESS shared_info_area_unmapped;
247 //setup_xen_features();
248 //KdPrint((__DRIVER_NAME " init_xen_info Hypercall area at %08x\n", hypercall_stubs));
250 shared_info_area_unmapped = XenPCI_AllocMMIO(Device, PAGE_SIZE);
251 xatp.domid = DOMID_SELF;
252 xatp.idx = 0;
253 xatp.space = XENMAPSPACE_shared_info;
254 xatp.gpfn = (xen_pfn_t)(shared_info_area_unmapped.QuadPart >> PAGE_SHIFT);
255 ret = HYPERVISOR_memory_op(Device, XENMEM_add_to_physmap, &xatp);
256 //KdPrint((__DRIVER_NAME " ret = %d\n", ret));
258 xpdd->shared_info_area = MmMapIoSpace(shared_info_area_unmapped,
259 PAGE_SIZE, MmNonCached);
261 return 0;
262 }
264 static int
265 set_callback_irq(WDFDEVICE Device, ULONGLONG irq)
266 {
267 struct xen_hvm_param a;
268 int retval;
270 //KdPrint((__DRIVER_NAME " --> set_callback_irq\n"));
271 a.domid = DOMID_SELF;
272 a.index = HVM_PARAM_CALLBACK_IRQ;
273 a.value = irq;
274 retval = HYPERVISOR_hvm_op(Device, HVMOP_set_param, &a);
275 //KdPrint((__DRIVER_NAME " HYPERVISOR_hvm_op retval = %d\n", retval));
276 //KdPrint((__DRIVER_NAME " <-- set_callback_irq\n"));
277 return retval;
278 }
280 static NTSTATUS
281 XenPCI_AddDevice(
282 IN WDFDRIVER Driver,
283 IN PWDFDEVICE_INIT DeviceInit
284 )
285 {
286 NTSTATUS status;
287 WDF_CHILD_LIST_CONFIG config;
288 WDF_OBJECT_ATTRIBUTES attributes;
289 WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
290 WDF_INTERRUPT_CONFIG interruptConfig;
291 PNP_BUS_INFORMATION busInfo;
292 BUS_INTERFACE_STANDARD BusInterface;
293 WDFDEVICE Device;
294 PXENPCI_DEVICE_DATA xpdd;
296 UNREFERENCED_PARAMETER(Driver);
298 KdPrint((__DRIVER_NAME " --> DeviceAdd\n"));
300 // get PDO
301 // get parent (should be PCI bus) (WdfPdoGetParent)
302 //
304 WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
305 WDF_CHILD_LIST_CONFIG_INIT(&config, sizeof(XENPCI_IDENTIFICATION_DESCRIPTION), XenPCI_ChildListCreateDevice);
306 WdfFdoInitSetDefaultChildListConfig(DeviceInit, &config, WDF_NO_OBJECT_ATTRIBUTES);
308 // WDF_FDO_EVENT_CALLBACKS_INIT(&FdoCallbacks);
309 // FdoCallbacks.EvtDeviceFilterRemoveResourceRequirements = XenPCI_FilterRemoveResourceRequirements;
310 // FdoCallbacks.EvtDeviceFilterAddResourceRequirements = XenPCI_FilterAddResourceRequirements;
311 // FdoCallbacks.EvtDeviceRemoveAddedResources = XenPCI_RemoveAddedResources;
312 // WdfFdoInitSetEventCallbacks(DeviceInit, &FdoCallbacks);
314 WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
315 pnpPowerCallbacks.EvtDevicePrepareHardware = XenPCI_PrepareHardware;
316 pnpPowerCallbacks.EvtDeviceReleaseHardware = XenPCI_ReleaseHardware;
317 pnpPowerCallbacks.EvtDeviceD0Entry = XenPCI_D0Entry;
318 pnpPowerCallbacks.EvtDeviceD0EntryPostInterruptsEnabled
319 = XenPCI_D0EntryPostInterruptsEnabled;
320 pnpPowerCallbacks.EvtDeviceD0ExitPreInterruptsDisabled
321 = XenPCI_D0ExitPreInterruptsDisabled;
322 pnpPowerCallbacks.EvtDeviceD0Exit = XenPCI_D0Exit;
323 WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
325 WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);
327 /*initialize storage for the device context*/
328 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, XENPCI_DEVICE_DATA);
330 /*create a device instance.*/
331 status = WdfDeviceCreate(&DeviceInit, &attributes, &Device);
332 if(!NT_SUCCESS(status))
333 {
334 KdPrint((__DRIVER_NAME " WdfDeviceCreate failed with status 0x%08x\n", status));
335 return status;
336 }
337 xpdd = GetDeviceData(Device);
338 xpdd->Device = Device;
340 WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFilePaging, TRUE);
341 WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFileHibernation, TRUE);
342 WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFileDump, TRUE);
344 status = WdfFdoQueryForInterface(Device, &GUID_BUS_INTERFACE_STANDARD, (PINTERFACE) &BusInterface, sizeof(BUS_INTERFACE_STANDARD), 1, NULL);
345 if(!NT_SUCCESS(status))
346 {
347 KdPrint((__DRIVER_NAME " WdfFdoQueryForInterface (BusInterface) failed with status 0x%08x\n", status));
348 }
350 busInfo.BusTypeGuid = GUID_XENPCI_DEVCLASS;
351 busInfo.LegacyBusType = PNPBus;
352 busInfo.BusNumber = 0;
354 WdfDeviceSetBusInformationForChildren(Device, &busInfo);
356 WDF_INTERRUPT_CONFIG_INIT(&interruptConfig, EvtChn_Interrupt, NULL);
357 interruptConfig.EvtInterruptEnable = XenPCI_InterruptEnable;
358 interruptConfig.EvtInterruptDisable = XenPCI_InterruptDisable;
359 status = WdfInterruptCreate(Device, &interruptConfig, WDF_NO_OBJECT_ATTRIBUTES, &xpdd->XenInterrupt);
360 if (!NT_SUCCESS (status))
361 {
362 KdPrint((__DRIVER_NAME "WdfInterruptCreate failed 0x%08x\n", status));
363 return status;
364 }
366 KdPrint((__DRIVER_NAME " <-- DeviceAdd\n"));
367 return status;
368 }
370 static NTSTATUS
371 XenPCI_PrepareHardware(
372 IN WDFDEVICE Device,
373 IN WDFCMRESLIST ResourceList,
374 IN WDFCMRESLIST ResourceListTranslated)
375 {
376 NTSTATUS status = STATUS_SUCCESS;
377 PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor;
378 ULONG i;
379 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
381 KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware\n"));
383 for (i = 0; i < WdfCmResourceListGetCount(ResourceList); i++)
384 {
385 descriptor = WdfCmResourceListGetDescriptor(ResourceList, i);
386 if(!descriptor)
387 continue;
388 switch (descriptor->Type)
389 {
390 case CmResourceTypeInterrupt:
391 xpdd->irqNumber = descriptor->u.Interrupt.Vector;
392 break;
393 }
394 }
396 //KdPrint((__DRIVER_NAME " GSI = %d\n", irqNumber));
398 //KdPrint((__DRIVER_NAME " ResourceListTranslated\n"));
399 for (i = 0; i < WdfCmResourceListGetCount(ResourceListTranslated); i++)
400 {
401 descriptor = WdfCmResourceListGetDescriptor(ResourceListTranslated, i);
402 if(!descriptor)
403 {
404 KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware (No descriptor)\n"));
405 return STATUS_DEVICE_CONFIGURATION_ERROR;
406 }
407 switch (descriptor->Type) {
408 case CmResourceTypePort:
409 //KdPrint((__DRIVER_NAME " I/O mapped CSR: (%x) Length: (%d)\n", descriptor->u.Port.Start.LowPart, descriptor->u.Port.Length));
410 // xpdd->IoBaseAddress = ULongToPtr(descriptor->u.Port.Start.LowPart);
411 // xpdd->IoRange = descriptor->u.Port.Length;
412 break;
413 case CmResourceTypeMemory:
414 KdPrint((__DRIVER_NAME " Memory mapped CSR:(%x:%x) Length:(%d)\n", descriptor->u.Memory.Start.LowPart, descriptor->u.Memory.Start.HighPart, descriptor->u.Memory.Length));
415 xpdd->platform_mmio_addr = descriptor->u.Memory.Start; //(ULONG)MmMapIoSpace(descriptor->u.Memory.Start, descriptor->u.Memory.Length, MmNonCached);
416 xpdd->platform_mmio_len = descriptor->u.Memory.Length;
417 xpdd->platform_mmio_alloc = 0;
418 break;
419 case CmResourceTypeInterrupt:
420 //KdPrint((__DRIVER_NAME " Interrupt level: 0x%0x, Vector: 0x%0x\n", descriptor->u.Interrupt.Level, descriptor->u.Interrupt.Vector));
421 break;
422 case CmResourceTypeDevicePrivate:
423 //KdPrint((__DRIVER_NAME " Private Data: 0x%02x 0x%02x 0x%02x\n", descriptor->u.DevicePrivate.Data[0], descriptor->u.DevicePrivate.Data[1], descriptor->u.DevicePrivate.Data[2] ));
424 break;
425 default:
426 //KdPrint((__DRIVER_NAME " Unhandled resource type (0x%x)\n", descriptor->Type));
427 break;
428 }
429 }
431 get_hypercall_stubs(Device);
433 init_xen_info(Device);
435 GntTbl_Init(Device);
437 EvtChn_Init(Device);
439 set_callback_irq(Device, xpdd->irqNumber);
441 XenBus_Init(Device);
443 //KdPrint((__DRIVER_NAME " upcall_pending = %d\n", shared_info_area->vcpu_info[0].evtchn_upcall_pending));
445 xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_mask = 0;
447 //xen_reboot_init();
449 KdPrint((__DRIVER_NAME " <-- EvtDevicePrepareHardware\n"));
451 return status;
452 }
454 static NTSTATUS
455 XenPCI_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated)
456 {
457 UNREFERENCED_PARAMETER(Device);
458 UNREFERENCED_PARAMETER(ResourcesTranslated);
460 return STATUS_SUCCESS;
461 }
463 static NTSTATUS
464 XenPCI_D0Entry(
465 IN WDFDEVICE Device,
466 IN WDF_POWER_DEVICE_STATE PreviousState
467 )
468 {
469 NTSTATUS status = STATUS_SUCCESS;
471 UNREFERENCED_PARAMETER(Device);
472 UNREFERENCED_PARAMETER(PreviousState);
474 KdPrint((__DRIVER_NAME " --> EvtDeviceD0Entry\n"));
476 KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Entry\n"));
478 return status;
479 }
481 static NTSTATUS
482 XenPCI_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState)
483 {
484 NTSTATUS status = STATUS_SUCCESS;
485 //OBJECT_ATTRIBUTES oa;
486 char *response;
487 char *msgTypes;
488 char **Types;
489 int i;
490 char buffer[128];
492 UNREFERENCED_PARAMETER(PreviousState);
494 KdPrint((__DRIVER_NAME " --> EvtDeviceD0EntryPostInterruptsEnabled\n"));
496 XenBus_Start(Device);
498 KdPrint((__DRIVER_NAME " A\n"));
500 response = XenBus_AddWatch(Device, XBT_NIL, SHUTDOWN_PATH, XenBus_ShutdownHandler, Device);
501 KdPrint((__DRIVER_NAME " shutdown watch response = '%s'\n", response));
503 response = XenBus_AddWatch(Device, XBT_NIL, BALLOON_PATH, XenBus_BalloonHandler, Device);
504 KdPrint((__DRIVER_NAME " shutdown watch response = '%s'\n", response));
506 response = XenBus_AddWatch(Device, XBT_NIL, "device", XenPCI_XenBusWatchHandler, Device);
507 KdPrint((__DRIVER_NAME " device watch response = '%s'\n", response));
509 msgTypes = XenBus_List(Device, XBT_NIL, "device", &Types);
510 if (!msgTypes) {
511 for (i = 0; Types[i]; i++)
512 {
513 RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/%s", Types[i]);
514 //KdPrint((__DRIVER_NAME " ls device[%d] -> %s\n", i, Types[i]));
515 XenPCI_XenBusWatchHandler(buffer, Device);
516 ExFreePoolWithTag(Types[i], XENPCI_POOL_TAG);
517 }
518 }
519 KdPrint((__DRIVER_NAME " <-- EvtDeviceD0EntryPostInterruptsEnabled\n"));
521 return status;
522 }
524 static NTSTATUS
525 XenPCI_D0ExitPreInterruptsDisabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
526 {
527 NTSTATUS status = STATUS_SUCCESS;
529 UNREFERENCED_PARAMETER(TargetState);
531 KdPrint((__DRIVER_NAME " --> D0ExitPreInterruptsDisabled\n"));
533 switch (KeGetCurrentIrql())
534 {
535 case PASSIVE_LEVEL:
536 KdPrint((__DRIVER_NAME " PASSIVE_LEVEL\n"));
537 break;
538 case APC_LEVEL:
539 KdPrint((__DRIVER_NAME " APC_LEVEL\n"));
540 break;
541 case DISPATCH_LEVEL:
542 KdPrint((__DRIVER_NAME " DISPATCH_LEVEL\n"));
543 break;
544 default:
545 KdPrint((__DRIVER_NAME " %d\n", KeGetCurrentIrql()));
546 break;
547 }
549 XenBus_Stop(Device);
551 KdPrint((__DRIVER_NAME " <-- D0ExitPreInterruptsDisabled\n"));
553 return status;
554 }
556 static NTSTATUS
557 XenPCI_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
558 {
559 NTSTATUS status = STATUS_SUCCESS;
561 UNREFERENCED_PARAMETER(Device);
562 UNREFERENCED_PARAMETER(TargetState);
564 KdPrint((__DRIVER_NAME " --> DeviceD0Exit\n"));
566 switch (KeGetCurrentIrql())
567 {
568 case PASSIVE_LEVEL:
569 KdPrint((__DRIVER_NAME " PASSIVE_LEVEL\n"));
570 break;
571 case APC_LEVEL:
572 KdPrint((__DRIVER_NAME " APC_LEVEL\n"));
573 break;
574 case DISPATCH_LEVEL:
575 KdPrint((__DRIVER_NAME " DISPATCH_LEVEL\n"));
576 break;
577 default:
578 KdPrint((__DRIVER_NAME " %d\n", KeGetCurrentIrql()));
579 break;
580 }
582 XenBus_Close(Device);
584 KdPrint((__DRIVER_NAME " <-- DeviceD0Exit\n"));
586 return status;
587 }
589 static VOID
590 XenPCI_IoDefault(
591 IN WDFQUEUE Queue,
592 IN WDFREQUEST Request
593 )
594 {
595 UNREFERENCED_PARAMETER(Queue);
597 KdPrint((__DRIVER_NAME " --> EvtDeviceIoDefault\n"));
599 WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
601 KdPrint((__DRIVER_NAME " <-- EvtDeviceIoDefault\n"));
602 }
604 static NTSTATUS
605 XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
606 {
607 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(AssociatedDevice);
608 UNREFERENCED_PARAMETER(Interrupt);
610 KdPrint((__DRIVER_NAME " --> EvtInterruptEnable\n"));
612 xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_mask = 0;
614 KdPrint((__DRIVER_NAME " <-- EvtInterruptEnable\n"));
616 return STATUS_SUCCESS;
617 }
619 static NTSTATUS
620 XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
621 {
622 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(AssociatedDevice);
623 UNREFERENCED_PARAMETER(Interrupt);
625 //KdPrint((__DRIVER_NAME " --> EvtInterruptDisable\n"));
627 xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_mask = 1;
628 // should we kick off any pending interrupts here?
630 //KdPrint((__DRIVER_NAME " <-- EvtInterruptDisable\n"));
632 return STATUS_SUCCESS;
633 }
635 static NTSTATUS
636 XenPCI_ChildListCreateDevice(
637 WDFCHILDLIST ChildList,
638 PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription,
639 PWDFDEVICE_INIT ChildInit)
640 {
641 NTSTATUS status;
642 WDFDEVICE ChildDevice = NULL;
643 PXENPCI_IDENTIFICATION_DESCRIPTION XenIdentificationDesc;
644 XEN_IFACE_EVTCHN EvtChnInterface;
645 XEN_IFACE_XENBUS XenBusInterface;
646 //XEN_IFACE_XEN XenInterface;
647 XEN_IFACE_GNTTBL GntTblInterface;
648 DECLARE_UNICODE_STRING_SIZE(buffer, 20);
649 WDF_OBJECT_ATTRIBUTES PdoAttributes;
650 DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
651 WDF_QUERY_INTERFACE_CONFIG qiConfig;
652 PXENPCI_XEN_DEVICE_DATA ChildDeviceData = NULL;
654 UNREFERENCED_PARAMETER(ChildList);
656 //KdPrint((__DRIVER_NAME " --> ChildListCreateDevice\n"));
658 XenIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENPCI_IDENTIFICATION_DESCRIPTION, Header);
660 //KdPrint((__DRIVER_NAME " Type = %wZ\n", &XenIdentificationDesc->DeviceType));
662 //DeviceInit = WdfPdoInitAllocate(Device);
663 WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_CONTROLLER);
665 status = RtlUnicodeStringPrintf(&buffer, L"Xen\\%wZ\0", &XenIdentificationDesc->DeviceType);
666 status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
667 status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
668 status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
670 status = RtlUnicodeStringPrintf(&buffer, L"%02d", 0);
671 status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
673 status = RtlUnicodeStringPrintf( &buffer, L"%wZ", &XenIdentificationDesc->DeviceType);
674 status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
676 WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
678 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&PdoAttributes, XENPCI_XEN_DEVICE_DATA);
680 // WDF_PDO_EVENT_CALLBACKS_INIT(&PdoCallbacks);
681 // PdoCallbacks.EvtDeviceResourceRequirementsQuery = XenPCI_DeviceResourceRequirementsQuery;
682 // WdfPdoInitSetEventCallbacks(ChildInit, &PdoCallbacks);
684 status = WdfDeviceCreate(&ChildInit, &PdoAttributes, &ChildDevice);
685 if (!NT_SUCCESS(status))
686 {
687 KdPrint((__DRIVER_NAME " WdfDeviceCreate status = %08X\n", status));
688 }
690 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFilePaging, TRUE);
691 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileHibernation, TRUE);
692 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileDump, TRUE);
694 ChildDeviceData = GetXenDeviceData(ChildDevice);
695 strncpy(ChildDeviceData->BasePath, XenIdentificationDesc->Path, 128);
697 RtlZeroMemory(&EvtChnInterface, sizeof(EvtChnInterface));
698 EvtChnInterface.InterfaceHeader.Size = sizeof(EvtChnInterface);
699 EvtChnInterface.InterfaceHeader.Version = 1;
700 EvtChnInterface.InterfaceHeader.Context = WdfPdoGetParent(ChildDevice);
701 EvtChnInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
702 EvtChnInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
703 EvtChnInterface.Bind = EvtChn_Bind;
704 EvtChnInterface.Unbind = EvtChn_Unbind;
705 EvtChnInterface.Mask = EvtChn_Mask;
706 EvtChnInterface.Unmask = EvtChn_Unmask;
707 EvtChnInterface.Notify = EvtChn_Notify;
708 EvtChnInterface.AllocUnbound = EvtChn_AllocUnbound;
709 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&EvtChnInterface, &GUID_XEN_IFACE_EVTCHN, NULL);
710 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
711 if (!NT_SUCCESS(status))
712 {
713 return status;
714 }
716 /* nobody uses this yet, maybe it isn't needed? */
717 #if 0
718 RtlZeroMemory(&XenInterface, sizeof(XenInterface));
719 XenInterface.InterfaceHeader.Size = sizeof(XenInterface);
720 XenInterface.InterfaceHeader.Version = 1;
721 XenInterface.InterfaceHeader.Context = WdfPdoGetParent(ChildDevice);
722 XenInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
723 XenInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
724 XenInterface.AllocMMIO = XenPCI_AllocMMIO;
725 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&XenInterface, &GUID_XEN_IFACE_XEN, NULL);
726 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
727 if (!NT_SUCCESS(status)) {
728 return status;
729 }
730 #endif
732 RtlZeroMemory(&GntTblInterface, sizeof(GntTblInterface));
733 GntTblInterface.InterfaceHeader.Size = sizeof(GntTblInterface);
734 GntTblInterface.InterfaceHeader.Version = 1;
735 GntTblInterface.InterfaceHeader.Context = WdfPdoGetParent(ChildDevice);
736 GntTblInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
737 GntTblInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
738 GntTblInterface.GrantAccess = GntTbl_GrantAccess;
739 GntTblInterface.EndAccess = GntTbl_EndAccess;
740 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&GntTblInterface, &GUID_XEN_IFACE_GNTTBL, NULL);
741 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
742 if (!NT_SUCCESS(status)) {
743 return status;
744 }
746 RtlZeroMemory(&XenBusInterface, sizeof(XenBusInterface));
748 XenBusInterface.InterfaceHeader.Size = sizeof(XenBusInterface);
749 XenBusInterface.InterfaceHeader.Version = 1;
750 XenBusInterface.InterfaceHeader.Context = WdfPdoGetParent(ChildDevice);
751 //XenBusInterface.InterfaceHeader.Context = ExAllocatePoolWithTag(NonPagedPool, (strlen(XenIdentificationDesc->Path) + 1), XENPCI_POOL_TAG);
752 //strcpy(XenBusInterface.InterfaceHeader.Context, XenIdentificationDesc->Path);
753 XenBusInterface.Read = XenBus_Read;
754 XenBusInterface.Write = XenBus_Write;
755 XenBusInterface.Printf = XenBus_Printf;
756 XenBusInterface.StartTransaction = XenBus_StartTransaction;
757 XenBusInterface.EndTransaction = XenBus_EndTransaction;
758 XenBusInterface.List = XenBus_List;
759 XenBusInterface.AddWatch = XenBus_AddWatch;
760 XenBusInterface.RemWatch = XenBus_RemWatch;
761 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&XenBusInterface, &GUID_XEN_IFACE_XENBUS, NULL);
762 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
763 if (!NT_SUCCESS(status)) {
764 return status;
765 }
767 //KdPrint((__DRIVER_NAME " <-- ChildListCreateDevice\n"));
769 return status;
770 }
772 VOID
773 XenPCI_XenBusWatchHandler(char *Path, PVOID Data)
774 {
775 XENPCI_IDENTIFICATION_DESCRIPTION description;
776 NTSTATUS status;
777 char **Bits;
778 int Count;
779 WDFDEVICE Device = Data;
780 WDFCHILDLIST ChildList;
781 WDF_CHILD_LIST_ITERATOR ChildIterator;
782 WDFDEVICE ChildDevice;
783 PXENPCI_XEN_DEVICE_DATA ChildDeviceData;
785 ANSI_STRING AnsiBuf;
787 UNREFERENCED_PARAMETER(Data);
789 KdPrint((__DRIVER_NAME " --> XenBusWatchHandle\n"));
791 //KdPrint((__DRIVER_NAME " %s\n", Path));
793 ChildList = WdfFdoGetDefaultChildList(Device);
795 Bits = SplitString(Path, '/', 3, &Count);
796 switch (Count)
797 {
798 case 0:
799 case 1:
800 break;
801 case 2:
802 // add or update the device node
803 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&description.Header, sizeof(description));
804 strncpy(description.Path, Path, 128);
805 RtlInitAnsiString(&AnsiBuf, Bits[1]);
806 //KdPrint((__DRIVER_NAME " Name = %s\n", Bits[1]));
807 RtlAnsiStringToUnicodeString(&description.DeviceType, &AnsiBuf, TRUE);
808 status = WdfChildListAddOrUpdateChildDescriptionAsPresent(ChildList, &description.Header, NULL);
809 break;
810 case 3:
811 WDF_CHILD_LIST_ITERATOR_INIT(&ChildIterator, WdfRetrievePresentChildren);
812 WdfChildListBeginIteration(ChildList, &ChildIterator);
813 while (NT_SUCCESS(WdfChildListRetrieveNextDevice(ChildList, &ChildIterator, &ChildDevice, NULL)))
814 {
815 ChildDeviceData = GetXenDeviceData(ChildDevice);
816 if (!ChildDeviceData)
817 {
818 KdPrint((__FUNCTION__ " No child device data, should never happen\n"));
819 continue;
820 }
821 if (strncmp(ChildDeviceData->BasePath, Path, strlen(ChildDeviceData->BasePath)) == 0 && Path[strlen(ChildDeviceData->BasePath)] == '/')
822 {
823 //KdPrint((__DRIVER_NAME " Child Path = %s (Match - WatchHandler = %08x)\n", ChildDeviceData->BasePath, ChildDeviceData->WatchHandler));
824 if (ChildDeviceData->WatchHandler != NULL)
825 ChildDeviceData->WatchHandler(Path, NULL);
826 }
827 else
828 {
829 //KdPrint((__DRIVER_NAME " Child Path = %s (No Match)\n", ChildDeviceData->BasePath));
830 }
831 }
832 WdfChildListEndIteration(ChildList, &ChildIterator);
833 break;
834 default:
835 KdPrint((__FUNCTION__ ": Unknown case %d\n", Count));
836 break;
837 }
839 FreeSplitString(Bits, Count);
841 KdPrint((__DRIVER_NAME " <-- XenBusWatchHandle\n"));
842 }
844 static void
845 XenBus_ShutdownHandler(char *Path, PVOID Data)
846 {
847 WDFDEVICE Device = Data;
848 char *value;
849 xenbus_transaction_t xbt;
850 int retry;
852 UNREFERENCED_PARAMETER(Path);
854 KdPrint((__DRIVER_NAME " --> XenBus_ShutdownHandler\n"));
856 XenBus_StartTransaction(Device, &xbt);
858 XenBus_Read(Device, XBT_NIL, SHUTDOWN_PATH, &value);
860 KdPrint((__DRIVER_NAME " Shutdown Value = %s\n", value));
862 // should check for error here... but why have we been called at all???
863 if (value != NULL && strlen(value) != 0)
864 XenBus_Write(Device, XBT_NIL, SHUTDOWN_PATH, "");
866 XenBus_EndTransaction(Device, xbt, 0, &retry);
868 KdPrint((__DRIVER_NAME " <-- XenBus_ShutdownHandler\n"));
869 }
871 static VOID
872 XenBus_BalloonHandler(char *Path, PVOID Data)
873 {
874 WDFDEVICE Device = Data;
875 char *value;
876 xenbus_transaction_t xbt;
877 int retry;
879 UNREFERENCED_PARAMETER(Path);
881 KdPrint((__DRIVER_NAME " --> XenBus_BalloonHandler\n"));
883 XenBus_StartTransaction(Device, &xbt);
885 XenBus_Read(Device, XBT_NIL, BALLOON_PATH, &value);
887 KdPrint((__DRIVER_NAME " Balloon Value = %s\n", value));
889 // use the memory_op(unsigned int op, void *arg) hypercall to adjust this
890 // use XENMEM_increase_reservation and XENMEM_decrease_reservation
892 XenBus_EndTransaction(Device, xbt, 0, &retry);
894 KdPrint((__DRIVER_NAME " <-- XenBus_BalloonHandler\n"));
895 }
897 /*
898 IO_RESOURCE_DESCRIPTOR MemoryDescriptor;
900 static NTSTATUS
901 XenPCI_FilterRemoveResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList)
902 {
903 NTSTATUS status;
904 WDFIORESLIST ResourceList;
905 PIO_RESOURCE_DESCRIPTOR Descriptor;
907 int i, j;
908 int offset;
910 //KdPrint((__DRIVER_NAME " --> FilterRemoveResourceRequirements\n"));
912 for (i = 0; i < WdfIoResourceRequirementsListGetCount(RequirementsList); i++)
913 {
914 ResourceList = WdfIoResourceRequirementsListGetIoResList(RequirementsList, i);
915 //KdPrint((__DRIVER_NAME " Resource List %d\n", i));
916 //KdPrint((__DRIVER_NAME " %d resources in list\n", WdfIoResourceListGetCount(ResourceList)));
917 offset = 0;
918 for (j = 0; j < WdfIoResourceListGetCount(ResourceList); j++)
919 {
920 //KdPrint((__DRIVER_NAME " Resource %d\n", j));
921 Descriptor = WdfIoResourceListGetDescriptor(ResourceList, j - offset);
923 switch (Descriptor->Type) {
924 case CmResourceTypePort:
925 //KdPrint((__DRIVER_NAME " Port\n"));
926 break;
927 case CmResourceTypeMemory:
928 //KdPrint((__DRIVER_NAME " Memory %08X%08X - %08X%08X\n", Descriptor->u.Memory.MinimumAddress.HighPart, Descriptor->u.Memory.MinimumAddress.LowPart, Descriptor->u.Memory.MaximumAddress.HighPart, Descriptor->u.Memory.MaximumAddress.LowPart));
929 //KdPrint((__DRIVER_NAME " Length %08X\n", Descriptor->u.Memory.Length));
930 //KdPrint((__DRIVER_NAME " ShareDisposition %02X\n", Descriptor->ShareDisposition));
931 //KdPrint((__DRIVER_NAME " Option %02X\n", Descriptor->Option));
932 if (!Descriptor->Option || Descriptor->Option == IO_RESOURCE_PREFERRED) {
933 memcpy(&MemoryDescriptor, Descriptor, sizeof(IO_RESOURCE_DESCRIPTOR));
934 //platform_mmio_orig_len = MemoryDescriptor.u.Memory.Length;
935 //MemoryDescriptor.u.Memory.Length = PAGE_SIZE;
936 MemoryDescriptor.ShareDisposition = CmResourceShareShared;
937 }
938 WdfIoResourceListRemove(ResourceList, j - offset);
939 offset++;
940 break;
941 case CmResourceTypeInterrupt:
942 //KdPrint((__DRIVER_NAME " Interrupt\n"));
943 break;
944 case CmResourceTypeDevicePrivate:
945 //KdPrint((__DRIVER_NAME " Private\n"));
946 break;
947 default:
948 //KdPrint((__DRIVER_NAME " Unknown Type (0x%x)\n", Descriptor->Type));
949 break;
950 }
951 }
952 }
953 status = STATUS_SUCCESS;
955 KdPrint((__DRIVER_NAME " <-- FilterRemoveResourceRequirements\n"));
957 return status;
958 }
961 static NTSTATUS
962 XenPCI_FilterAddResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList)
963 {
964 NTSTATUS status;
965 WDFIORESLIST ResourceList;
966 PIO_RESOURCE_DESCRIPTOR Descriptor;
968 int i, j;
970 KdPrint((__DRIVER_NAME " --> FilterAddResourceRequirements\n"));
973 for (i = 0; i < WdfIoResourceRequirementsListGetCount(RequirementsList); i++)
974 {
975 ResourceList = WdfIoResourceRequirementsListGetIoResList(RequirementsList, i);
976 //KdPrint((__DRIVER_NAME " Resource List %d\n", i));
977 //KdPrint((__DRIVER_NAME " %d resources in list\n", WdfIoResourceListGetCount(ResourceList)));
978 WdfIoResourceListAppendDescriptor(ResourceList, &MemoryDescriptor);
979 //KdPrint((__DRIVER_NAME " Memory %08X%08X - %08X%08X\n", MemoryDescriptor.u.Memory.MinimumAddress.HighPart, MemoryDescriptor.u.Memory.MinimumAddress.LowPart, MemoryDescriptor.u.Memory.MaximumAddress.HighPart, MemoryDescriptor.u.Memory.MaximumAddress.LowPart));
980 //KdPrint((__DRIVER_NAME " Length %08X\n", MemoryDescriptor.u.Memory.Length));
981 for (j = 0; j < WdfIoResourceListGetCount(ResourceList); j++)
982 {
983 //KdPrint((__DRIVER_NAME " Resource %d\n", j));
984 Descriptor = WdfIoResourceListGetDescriptor(ResourceList, j);
986 switch (Descriptor->Type) {
987 case CmResourceTypePort:
988 //KdPrint((__DRIVER_NAME " Port\n"));
989 break;
990 case CmResourceTypeMemory:
991 //KdPrint((__DRIVER_NAME " Memory %08X%08X - %08X%08X\n", Descriptor->u.Memory.MinimumAddress.HighPart, Descriptor->u.Memory.MinimumAddress.LowPart, Descriptor->u.Memory.MaximumAddress.HighPart, Descriptor->u.Memory.MaximumAddress.LowPart));
992 //KdPrint((__DRIVER_NAME " Length %08X\n", Descriptor->u.Memory.Length));
993 //KdPrint((__DRIVER_NAME " ShareDisposition %02X\n", Descriptor->ShareDisposition));
994 //Descriptor->ShareDisposition = CmResourceShareShared;
995 //memcpy(&MemoryDescriptor, Descriptor, sizeof(IO_RESOURCE_DESCRIPTOR));
996 //platform_mmio_orig_len = MemoryDescriptor.u.Memory.Length;
997 //MemoryDescriptor.u.Memory.Length = PAGE_SIZE;
998 //WdfIoResourceListRemove(ResourceList, j);
999 break;
1000 case CmResourceTypeInterrupt:
1001 //KdPrint((__DRIVER_NAME " Interrupt\n"));
1002 break;
1003 case CmResourceTypeDevicePrivate:
1004 //KdPrint((__DRIVER_NAME " Private\n"));
1005 break;
1006 default:
1007 //KdPrint((__DRIVER_NAME " Unknown Type (0x%x)\n", Descriptor->Type));
1008 break;
1012 status = STATUS_SUCCESS;
1014 //KdPrint((__DRIVER_NAME " <-- FilterAddResourceRequirements\n"));
1016 return status;
1019 static NTSTATUS
1020 XenPCI_RemoveAddedResources(WDFDEVICE Device, WDFCMRESLIST ResourcesRaw, WDFCMRESLIST ResourcesTranslated)
1022 //KdPrint((__DRIVER_NAME " --> RemoveAddedResources\n"));
1023 //KdPrint((__DRIVER_NAME " <-- RemoveAddedResources\n"));
1025 return STATUS_SUCCESS;
1028 */
1030 static NTSTATUS
1031 XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList)
1033 NTSTATUS status;
1034 WDFIORESLIST resourceList;
1035 IO_RESOURCE_DESCRIPTOR descriptor;
1036 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
1038 //KdPrint((__DRIVER_NAME " --> DeviceResourceRequirementsQuery\n"));
1040 status = WdfIoResourceListCreate(IoResourceRequirementsList, WDF_NO_OBJECT_ATTRIBUTES, &resourceList);
1041 if (!NT_SUCCESS(status))
1042 return status;
1044 /*
1045 RtlZeroMemory(&descriptor, sizeof(descriptor));
1047 descriptor.Option = 0;
1048 descriptor.Type = CmResourceTypeInterrupt;
1049 descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
1050 descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
1051 descriptor.u.Interrupt.MinimumVector = 1024;
1052 descriptor.u.Interrupt.MaximumVector = 1024+255;
1054 //KdPrint((__DRIVER_NAME " MinimumVector = %d, MaximumVector = %d\n", descriptor.u.Interrupt.MinimumVector, descriptor.u.Interrupt.MaximumVector));
1056 status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
1057 if (!NT_SUCCESS(status))
1058 return status;
1059 */
1061 RtlZeroMemory(&descriptor, sizeof(descriptor));
1063 descriptor.Option = 0;
1064 descriptor.Type = CmResourceTypeMemory;
1065 descriptor.ShareDisposition = CmResourceShareShared; //CmResourceShareDeviceExclusive;
1066 descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
1067 descriptor.u.Memory.Length = PAGE_SIZE;
1068 descriptor.u.Memory.Alignment = PAGE_SIZE;
1069 descriptor.u.Memory.MinimumAddress.QuadPart
1070 = xpdd->platform_mmio_addr.QuadPart + PAGE_SIZE;
1071 descriptor.u.Memory.MaximumAddress.QuadPart
1072 = xpdd->platform_mmio_addr.QuadPart + xpdd->platform_mmio_len - 1;
1074 //KdPrint((__DRIVER_NAME " MinimumAddress = %08x, MaximumAddress = %08X\n", descriptor.u.Memory.MinimumAddress.LowPart, descriptor.u.Memory.MaximumAddress.LowPart));
1076 status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
1077 if (!NT_SUCCESS(status))
1078 return status;
1080 status = WdfIoResourceRequirementsListAppendIoResList(IoResourceRequirementsList, resourceList);
1081 if (!NT_SUCCESS(status))
1082 return status;
1084 //KdPrint((__DRIVER_NAME " <-- DeviceResourceRequirementsQuery\n"));
1086 return status;