win-pvdrivers

view xenpci/xenpci_fdo.c @ 310:60372bd2582d

First cut of putting xenbus config details in the .inf file - xenvbd may yet pass WHQL
author James Harper <james.harper@bendigoit.com.au>
date Fri Jun 13 14:16:50 2008 +1000 (2008-06-13)
parents 873944504204
children bb891f6d10e4
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 <wdmsec.h>
22 #include <stdlib.h>
24 #define SYSRQ_PATH "control/sysrq"
25 #define SHUTDOWN_PATH "control/shutdown"
26 #define BALLOON_PATH "memory/target"
28 static VOID
29 XenBus_BalloonHandler(char *Path, PVOID Data);
31 /*
32 static VOID
33 XenPCI_XenBusWatchHandler(char *Path, PVOID Data);
34 */
36 #pragma warning(disable : 4200) // zero-sized array
38 //CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptRaw;
39 //CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptTranslated;
41 NTSTATUS
42 XenPci_Power_Fdo(PDEVICE_OBJECT device_object, PIRP irp)
43 {
44 NTSTATUS status;
45 PIO_STACK_LOCATION stack;
46 POWER_STATE_TYPE power_type;
47 POWER_STATE power_state;
48 PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
49 //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
51 UNREFERENCED_PARAMETER(device_object);
53 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
55 stack = IoGetCurrentIrpStackLocation(irp);
56 power_type = stack->Parameters.Power.Type;
57 power_state = stack->Parameters.Power.State;
59 switch (stack->MinorFunction)
60 {
61 case IRP_MN_POWER_SEQUENCE:
62 KdPrint((__DRIVER_NAME " IRP_MN_POWER_SEQUENCE\n"));
63 break;
64 case IRP_MN_QUERY_POWER:
65 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_POWER\n"));
66 break;
67 case IRP_MN_SET_POWER:
68 KdPrint((__DRIVER_NAME " IRP_MN_SET_POWER\n"));
69 switch (power_type) {
70 case DevicePowerState:
71 KdPrint((__DRIVER_NAME " DevicePowerState\n"));
72 break;
73 case SystemPowerState:
74 KdPrint((__DRIVER_NAME " SystemPowerState\n"));
75 break;
76 default:
77 break;
78 }
79 break;
80 case IRP_MN_WAIT_WAKE:
81 break;
82 }
83 PoStartNextPowerIrp(irp);
84 IoSkipCurrentIrpStackLocation(irp);
85 status = PoCallDriver (xpdd->common.lower_do, irp);
87 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
89 return status;
90 }
92 NTSTATUS
93 XenPci_Dummy_Fdo(PDEVICE_OBJECT device_object, PIRP irp)
94 {
95 NTSTATUS status;
96 PIO_STACK_LOCATION stack;
97 PXENPCI_DEVICE_DATA xpdd;
99 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
101 xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
102 stack = IoGetCurrentIrpStackLocation(irp);
103 IoSkipCurrentIrpStackLocation(irp);
104 status = IoCallDriver(xpdd->common.lower_do, irp);
106 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
108 return status;
109 }
111 /*
112 * Alloc MMIO from the device's MMIO region. There is no corresponding free() fn
113 */
114 PHYSICAL_ADDRESS
115 XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len)
116 {
117 PHYSICAL_ADDRESS addr;
119 len = (len + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
121 addr = xpdd->platform_mmio_addr;
122 addr.QuadPart += xpdd->platform_mmio_alloc;
123 xpdd->platform_mmio_alloc += len;
125 ASSERT(xpdd->platform_mmio_alloc <= xpdd->platform_mmio_len);
127 return addr;
128 }
130 static NTSTATUS
131 XenPci_Init(PXENPCI_DEVICE_DATA xpdd)
132 {
133 struct xen_add_to_physmap xatp;
134 int ret;
135 PHYSICAL_ADDRESS shared_info_area_unmapped;
137 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
139 hvm_get_stubs(xpdd);
141 shared_info_area_unmapped = XenPci_AllocMMIO(xpdd, PAGE_SIZE);
142 KdPrint((__DRIVER_NAME " shared_info_area_unmapped.QuadPart = %lx\n", shared_info_area_unmapped.QuadPart));
143 xatp.domid = DOMID_SELF;
144 xatp.idx = 0;
145 xatp.space = XENMAPSPACE_shared_info;
146 xatp.gpfn = (xen_pfn_t)(shared_info_area_unmapped.QuadPart >> PAGE_SHIFT);
147 KdPrint((__DRIVER_NAME " gpfn = %d\n", xatp.gpfn));
148 ret = HYPERVISOR_memory_op(xpdd, XENMEM_add_to_physmap, &xatp);
149 KdPrint((__DRIVER_NAME " hypervisor memory op ret = %d\n", ret));
150 xpdd->shared_info_area = MmMapIoSpace(shared_info_area_unmapped,
151 PAGE_SIZE, MmNonCached);
152 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
154 return STATUS_SUCCESS;
155 }
157 #if 0
158 WDFQUEUE ReadQueue;
159 #endif
161 static NTSTATUS
162 XenPci_Pnp_IoCompletion(PDEVICE_OBJECT device_object, PIRP irp, PVOID context)
163 {
164 PKEVENT event = (PKEVENT)context;
166 UNREFERENCED_PARAMETER(device_object);
168 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
170 if (irp->PendingReturned)
171 {
172 KeSetEvent(event, IO_NO_INCREMENT, FALSE);
173 }
175 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
177 return STATUS_MORE_PROCESSING_REQUIRED;
178 }
180 static NTSTATUS
181 XenPci_QueueWorkItem(PDEVICE_OBJECT device_object, PIO_WORKITEM_ROUTINE routine, PVOID context)
182 {
183 PIO_WORKITEM work_item;
184 NTSTATUS status = STATUS_SUCCESS;
186 work_item = IoAllocateWorkItem(device_object);
187 IoQueueWorkItem(work_item, routine, DelayedWorkQueue, context);
189 return status;
190 }
192 static NTSTATUS
193 XenPci_SendAndWaitForIrp(PDEVICE_OBJECT device_object, PIRP irp)
194 {
195 NTSTATUS status;
196 PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
197 KEVENT event;
199 UNREFERENCED_PARAMETER(device_object);
201 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
203 KeInitializeEvent(&event, NotificationEvent, FALSE);
205 IoCopyCurrentIrpStackLocationToNext(irp);
206 IoSetCompletionRoutine(irp, XenPci_Pnp_IoCompletion, &event, TRUE, TRUE, TRUE);
208 status = IoCallDriver(xpdd->common.lower_do, irp);
210 if (status == STATUS_PENDING)
211 {
212 KdPrint((__DRIVER_NAME " waiting ...\n"));
213 KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
214 KdPrint((__DRIVER_NAME " ... done\n"));
215 status = irp->IoStatus.Status;
216 }
218 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
220 return status;
221 }
223 static NTSTATUS
224 XenPci_ProcessShutdownIrp(PXENPCI_DEVICE_DATA xpdd)
225 {
226 PIO_STACK_LOCATION stack;
227 NTSTATUS status;
228 PIRP irp;
229 KIRQL old_irql;
230 ULONG length;
232 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
234 KeAcquireSpinLock(&xpdd->shutdown_ring_lock, &old_irql);
235 if (xpdd->shutdown_irp)
236 {
237 irp = xpdd->shutdown_irp;
238 stack = IoGetCurrentIrpStackLocation(irp);
239 KdPrint((__DRIVER_NAME " stack = %p\n", stack));
240 KdPrint((__DRIVER_NAME " length = %d, buffer = %p\n", stack->Parameters.Read.Length, irp->AssociatedIrp.SystemBuffer));
241 length = min(xpdd->shutdown_prod - xpdd->shutdown_cons, stack->Parameters.Read.Length);
242 KdPrint((__DRIVER_NAME " length = %d\n", length));
243 if (length > 0)
244 {
245 memcpy(irp->AssociatedIrp.SystemBuffer, &xpdd->shutdown_ring[xpdd->shutdown_cons & (SHUTDOWN_RING_SIZE - 1)], length);
246 xpdd->shutdown_cons += length;
247 if (xpdd->shutdown_cons > SHUTDOWN_RING_SIZE)
248 {
249 xpdd->shutdown_cons -= SHUTDOWN_RING_SIZE;
250 xpdd->shutdown_prod -= SHUTDOWN_RING_SIZE;
251 xpdd->shutdown_start -= SHUTDOWN_RING_SIZE;
252 }
253 xpdd->shutdown_irp = NULL;
254 KeReleaseSpinLock(&xpdd->shutdown_ring_lock, old_irql);
255 status = STATUS_SUCCESS;
256 irp->IoStatus.Status = status;
257 irp->IoStatus.Information = length;
258 IoSetCancelRoutine(irp, NULL);
259 IoCompleteRequest(irp, IO_NO_INCREMENT);
260 }
261 else
262 {
263 KeReleaseSpinLock(&xpdd->shutdown_ring_lock, old_irql);
264 KdPrint((__DRIVER_NAME " nothing to read... pending\n"));
265 IoMarkIrpPending(irp);
266 status = STATUS_PENDING;
267 }
268 }
269 else
270 {
271 KdPrint((__DRIVER_NAME " no pending irp\n"));
272 KeReleaseSpinLock(&xpdd->shutdown_ring_lock, old_irql);
273 status = STATUS_SUCCESS;
274 }
276 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
278 return status;
279 }
281 static VOID
282 XenBus_ShutdownIoCancel(PDEVICE_OBJECT device_object, PIRP irp)
283 {
284 PXENPCI_DEVICE_DATA xpdd;
285 KIRQL old_irql;
287 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
289 xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
290 IoReleaseCancelSpinLock(irp->CancelIrql);
291 KeAcquireSpinLock(&xpdd->shutdown_ring_lock, &old_irql);
292 if (irp == xpdd->shutdown_irp)
293 {
294 KdPrint((__DRIVER_NAME " Not the current irp???\n"));
295 xpdd->shutdown_irp = NULL;
296 }
297 irp->IoStatus.Status = STATUS_CANCELLED;
298 irp->IoStatus.Information = 0;
299 KeReleaseSpinLock(&xpdd->shutdown_ring_lock, old_irql);
300 IoCompleteRequest(irp, IO_NO_INCREMENT);
302 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
303 }
305 struct {
306 ULONG do_spin;
307 ULONG nr_spinning;
308 } typedef SUSPEND_INFO, *PSUSPEND_INFO;
310 static VOID
311 XenPci_Suspend(
312 PRKDPC Dpc,
313 PVOID Context,
314 PVOID SystemArgument1,
315 PVOID SystemArgument2)
316 {
317 PXENPCI_DEVICE_DATA xpdd = Context;
318 PSUSPEND_INFO suspend_info = SystemArgument1;
319 ULONG ActiveProcessorCount;
320 KIRQL OldIrql;
321 int cancelled;
322 int i;
324 UNREFERENCED_PARAMETER(Dpc);
325 UNREFERENCED_PARAMETER(SystemArgument2);
327 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (CPU = %d)\n", KeGetCurrentProcessorNumber()));
329 if (KeGetCurrentProcessorNumber() != 0)
330 {
331 KdPrint((__DRIVER_NAME " spinning...\n"));
332 InterlockedIncrement((volatile LONG *)&suspend_info->nr_spinning);
333 KeMemoryBarrier();
334 while(suspend_info->do_spin)
335 {
336 /* we should be able to wait more nicely than this... */
337 }
338 KeMemoryBarrier();
339 InterlockedDecrement((volatile LONG *)&suspend_info->nr_spinning);
340 KdPrint((__DRIVER_NAME " ...done spinning\n"));
341 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n", KeGetCurrentProcessorNumber()));
342 return;
343 }
344 ActiveProcessorCount = (ULONG)KeNumberProcessors;
346 KdPrint((__DRIVER_NAME " waiting for all other processors to spin\n"));
347 while (suspend_info->nr_spinning < ActiveProcessorCount - 1)
348 {
349 /* we should be able to wait more nicely than this... */
350 }
351 KdPrint((__DRIVER_NAME " all other processors are spinning\n"));
353 KeRaiseIrql(HIGH_LEVEL, &OldIrql);
354 KdPrint((__DRIVER_NAME " calling suspend\n"));
355 cancelled = hvm_shutdown(Context, SHUTDOWN_suspend);
356 KdPrint((__DRIVER_NAME " back from suspend, cancelled = %d\n", cancelled));
357 KeLowerIrql(OldIrql);
359 KdPrint((__DRIVER_NAME " waiting for all other processors to stop spinning\n"));
360 suspend_info->do_spin = 0;
361 while (suspend_info->nr_spinning != 0)
362 {
363 /* we should be able to wait more nicely than this... */
364 }
365 KdPrint((__DRIVER_NAME " all other processors have stopped spinning\n"));
367 for (i = 0; i < MAX_VIRT_CPUS; i++)
368 {
369 xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 1;
370 }
372 GntTbl_Map(Context, 0, NR_GRANT_FRAMES - 1);
373 XenBus_Resume(xpdd);
374 // TODO: Enable xenbus
375 // TODO: Enable all our devices
377 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n", KeGetCurrentProcessorNumber()));
378 }
380 static VOID
381 XenPci_BeginSuspend(PXENPCI_DEVICE_DATA xpdd)
382 {
383 //KAFFINITY ActiveProcessorMask = 0; // this is for Vista+
384 ULONG ActiveProcessorCount;
385 ULONG i;
386 PSUSPEND_INFO suspend_info;
387 PKDPC Dpc;
388 KIRQL OldIrql;
390 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
392 if (!xpdd->suspending)
393 {
394 xpdd->suspending = 1;
395 suspend_info = ExAllocatePoolWithTag(NonPagedPool, sizeof(SUSPEND_INFO), XENPCI_POOL_TAG);
396 suspend_info->do_spin = 1;
397 RtlZeroMemory(suspend_info, sizeof(SUSPEND_INFO));
399 // TODO: Disable all our devices
400 // TODO: Disable xenbus
402 for (i = 0; i < MAX_VIRT_CPUS; i++)
403 {
404 xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 1;
405 }
406 //ActiveProcessorCount = KeQueryActiveProcessorCount(&ActiveProcessorMask); // this is for Vista+
407 ActiveProcessorCount = (ULONG)KeNumberProcessors;
408 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
409 for (i = 0; i < ActiveProcessorCount; i++)
410 {
411 Dpc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KDPC), XENPCI_POOL_TAG);
412 KeInitializeDpc(Dpc, XenPci_Suspend, xpdd);
413 KeSetTargetProcessorDpc(Dpc, (CCHAR)i);
414 KeInsertQueueDpc(Dpc, suspend_info, NULL);
415 }
416 KeLowerIrql(OldIrql);
417 }
418 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
419 }
421 static void
422 XenPci_ShutdownHandler(char *path, PVOID context)
423 {
424 PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)context;
425 char *res;
426 char *value;
427 KIRQL old_irql;
429 UNREFERENCED_PARAMETER(path);
431 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
433 res = XenBus_Read(xpdd, XBT_NIL, SHUTDOWN_PATH, &value);
434 if (res)
435 {
436 KdPrint(("Error reading shutdown path - %s\n", res));
437 XenPci_FreeMem(res);
438 return;
439 }
441 KdPrint((__DRIVER_NAME " Shutdown value = %s\n", value));
443 if (strlen(value) != 0)
444 {
445 if (strcmp(value, "suspend") == 0)
446 {
447 KdPrint((__DRIVER_NAME " Suspend detected\n"));
448 XenPci_BeginSuspend(xpdd);
449 }
450 else
451 {
452 KeAcquireSpinLock(&xpdd->shutdown_ring_lock, &old_irql);
453 if (xpdd->shutdown_start >= xpdd->shutdown_cons)
454 xpdd->shutdown_prod = xpdd->shutdown_start;
455 else
456 xpdd->shutdown_start = xpdd->shutdown_prod;
457 memcpy(&xpdd->shutdown_ring[xpdd->shutdown_prod], value, strlen(value));
458 xpdd->shutdown_prod += (ULONG)strlen(value);
459 xpdd->shutdown_ring[xpdd->shutdown_prod++] = '\r';
460 xpdd->shutdown_ring[xpdd->shutdown_prod++] = '\n';
461 KeReleaseSpinLock(&xpdd->shutdown_ring_lock, old_irql);
462 XenPci_ProcessShutdownIrp(xpdd);
463 }
464 }
466 //XenPci_FreeMem(value);
468 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
469 }
471 static VOID
472 XenPci_SysrqHandler(char *path, PVOID context)
473 {
474 PXENPCI_DEVICE_DATA xpdd = context;
475 char *value;
476 char letter;
477 char *res;
479 UNREFERENCED_PARAMETER(path);
481 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
483 XenBus_Read(xpdd, XBT_NIL, SYSRQ_PATH, &value);
485 KdPrint((__DRIVER_NAME " SysRq Value = %s\n", value));
487 if (value != NULL && strlen(value) != 0)
488 {
489 letter = *value;
490 res = XenBus_Write(xpdd, XBT_NIL, SYSRQ_PATH, "");
491 if (res)
492 {
493 KdPrint(("Error writing sysrq path\n"));
494 XenPci_FreeMem(res);
495 return;
496 }
497 }
498 else
499 {
500 letter = 0;
501 }
503 if (value != NULL)
504 {
505 XenPci_FreeMem(value);
506 }
508 switch (letter)
509 {
510 case 'B':
511 KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000001, 0x00000000, 0x00000000, 0x00000000);
512 break;
513 default:
514 KdPrint((" Unhandled sysrq letter %c\n", letter));
515 break;
516 }
518 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
519 }
521 static VOID
522 XenPci_DeviceWatchHandler(char *path, PVOID context)
523 {
524 char **bits;
525 int count;
526 char *err;
527 char *value;
528 PXENPCI_DEVICE_DATA xpdd = context;
530 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
532 KdPrint((__DRIVER_NAME " path = %s\n", path));
533 bits = SplitString(path, '/', 4, &count);
534 KdPrint((__DRIVER_NAME " count = %d\n", count));
536 if (count == 3)
537 {
538 err = XenBus_Read(xpdd, XBT_NIL, path, &value);
539 if (err)
540 {
541 /* obviously path no longer exists, in which case the removal is being taken care of elsewhere and we shouldn't invalidate now */
542 XenPci_FreeMem(err);
543 }
544 else
545 {
546 XenPci_FreeMem(value);
547 /* we probably have to be a bit smarter here and do nothing if xenpci isn't running yet */
548 KdPrint((__DRIVER_NAME " Invalidating Device Relations\n"));
549 IoInvalidateDeviceRelations(xpdd->common.pdo, BusRelations);
550 }
551 }
552 FreeSplitString(bits, count);
554 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
555 }
557 static VOID
558 XenPci_Pnp_StartDeviceCallback(PDEVICE_OBJECT device_object, PVOID context)
559 {
560 NTSTATUS status = STATUS_SUCCESS;
561 PXENPCI_DEVICE_DATA xpdd = device_object->DeviceExtension;
562 PIRP irp = context;
563 char *response;
565 //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
567 XenPci_Init(xpdd);
569 GntTbl_Init(xpdd);
571 EvtChn_Init(xpdd);
573 XenBus_Init(xpdd);
575 response = XenBus_AddWatch(xpdd, XBT_NIL, SYSRQ_PATH, XenPci_SysrqHandler, xpdd);
576 KdPrint((__DRIVER_NAME " sysrqwatch response = '%s'\n", response));
578 response = XenBus_AddWatch(xpdd, XBT_NIL, SHUTDOWN_PATH, XenPci_ShutdownHandler, xpdd);
579 KdPrint((__DRIVER_NAME " shutdown watch response = '%s'\n", response));
581 response = XenBus_AddWatch(xpdd, XBT_NIL, "device", XenPci_DeviceWatchHandler, xpdd);
582 KdPrint((__DRIVER_NAME " device watch response = '%s'\n", response));
584 #if 0
585 response = XenBus_AddWatch(xpdd, XBT_NIL, BALLOON_PATH, XenPci_BalloonHandler, Device);
586 KdPrint((__DRIVER_NAME " balloon watch response = '%s'\n", response));
587 #endif
589 status = IoSetDeviceInterfaceState(&xpdd->interface_name, TRUE);
590 if (!NT_SUCCESS(status))
591 {
592 KdPrint((__DRIVER_NAME " IoSetDeviceInterfaceState failed with status 0x%08x\n", status));
593 }
595 irp->IoStatus.Status = status;
597 IoCompleteRequest(irp, IO_NO_INCREMENT);
599 //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
600 }
602 static NTSTATUS
603 XenPci_Pnp_StartDevice(PDEVICE_OBJECT device_object, PIRP irp)
604 {
605 NTSTATUS status;
606 PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
607 PIO_STACK_LOCATION stack;
608 PCM_PARTIAL_RESOURCE_LIST res_list;
609 PCM_PARTIAL_RESOURCE_DESCRIPTOR res_descriptor;
610 ULONG i;
612 UNREFERENCED_PARAMETER(device_object);
614 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
616 stack = IoGetCurrentIrpStackLocation(irp);
618 IoMarkIrpPending(irp);
620 status = XenPci_SendAndWaitForIrp(device_object, irp);
622 res_list = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
624 for (i = 0; i < res_list->Count; i++)
625 {
626 res_descriptor = &res_list->PartialDescriptors[i];
627 switch (res_descriptor->Type)
628 {
629 case CmResourceTypeInterrupt:
630 KdPrint((__DRIVER_NAME " irq_number = %03x\n", res_descriptor->u.Interrupt.Vector));
631 xpdd->irq_number = res_descriptor->u.Interrupt.Vector;
632 //memcpy(&InterruptRaw, res_descriptor, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
633 break;
634 }
635 }
637 res_list = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
639 for (i = 0; i < res_list->Count; i++)
640 {
641 res_descriptor = &res_list->PartialDescriptors[i];
642 switch (res_descriptor->Type) {
643 case CmResourceTypePort:
644 break;
645 case CmResourceTypeMemory:
646 KdPrint((__DRIVER_NAME " Memory mapped CSR:(%x:%x) Length:(%d)\n", res_descriptor->u.Memory.Start.LowPart, res_descriptor->u.Memory.Start.HighPart, res_descriptor->u.Memory.Length));
647 KdPrint((__DRIVER_NAME " Memory flags = %04X\n", res_descriptor->Flags));
648 xpdd->platform_mmio_addr = res_descriptor->u.Memory.Start;
649 xpdd->platform_mmio_len = res_descriptor->u.Memory.Length;
650 xpdd->platform_mmio_alloc = 0;
651 xpdd->platform_mmio_flags = res_descriptor->Flags;
652 break;
653 case CmResourceTypeInterrupt:
654 KdPrint((__DRIVER_NAME " irq_vector = %03x\n", res_descriptor->u.Interrupt.Vector));
655 KdPrint((__DRIVER_NAME " irq_level = %03x\n", res_descriptor->u.Interrupt.Level));
656 xpdd->irq_level = (KIRQL)res_descriptor->u.Interrupt.Level;
657 xpdd->irq_vector = res_descriptor->u.Interrupt.Vector;
658 xpdd->irq_affinity = res_descriptor->u.Interrupt.Affinity;
659 //memcpy(&InterruptTranslated, res_descriptor, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
660 break;
661 case CmResourceTypeDevicePrivate:
662 KdPrint((__DRIVER_NAME " Private Data: 0x%02x 0x%02x 0x%02x\n", res_descriptor->u.DevicePrivate.Data[0], res_descriptor->u.DevicePrivate.Data[1], res_descriptor->u.DevicePrivate.Data[2] ));
663 break;
664 default:
665 KdPrint((__DRIVER_NAME " Unhandled resource type (0x%x)\n", res_descriptor->Type));
666 break;
667 }
668 }
670 XenPci_QueueWorkItem(device_object, XenPci_Pnp_StartDeviceCallback, irp);
672 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
674 return STATUS_PENDING;
675 }
677 static NTSTATUS
678 XenPci_Pnp_StopDevice(PDEVICE_OBJECT device_object, PIRP irp, PVOID context)
679 {
680 NTSTATUS status = STATUS_SUCCESS;
682 UNREFERENCED_PARAMETER(device_object);
683 UNREFERENCED_PARAMETER(context);
685 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
687 irp->IoStatus.Status = status;
688 IoCompleteRequest(irp, IO_NO_INCREMENT);
690 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
692 return irp->IoStatus.Status;
693 }
695 static NTSTATUS
696 XenPci_Pnp_QueryStopRemoveDevice(PDEVICE_OBJECT device_object, PIRP irp)
697 {
698 NTSTATUS status;
699 PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
701 UNREFERENCED_PARAMETER(device_object);
703 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
705 if (xpdd->common.device_usage_paging
706 || xpdd->common.device_usage_dump
707 || xpdd->common.device_usage_hibernation)
708 {
709 /* We are in the paging or hibernation path - can't remove */
710 status = irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
711 IoCompleteRequest(irp, IO_NO_INCREMENT);
712 }
713 else
714 {
715 IoSkipCurrentIrpStackLocation(irp);
716 status = IoCallDriver(xpdd->common.lower_do, irp);
717 }
719 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
721 return status;
722 }
724 static NTSTATUS
725 XenPci_Pnp_RemoveDevice(PDEVICE_OBJECT device_object, PIRP irp)
726 {
727 NTSTATUS status;
728 PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
730 UNREFERENCED_PARAMETER(device_object);
732 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
734 irp->IoStatus.Status = STATUS_SUCCESS;
735 IoSkipCurrentIrpStackLocation(irp);
736 status = IoCallDriver(xpdd->common.lower_do, irp);
737 IoDetachDevice(xpdd->common.lower_do);
739 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
741 return status;
742 }
744 static VOID
745 XenPci_Pnp_QueryBusRelationsCallback(PDEVICE_OBJECT device_object, PVOID context)
746 {
747 NTSTATUS status = STATUS_SUCCESS;
748 PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
749 PXENPCI_PDO_DEVICE_DATA xppdd;
750 PIRP irp = context;
751 int device_count = 0;
752 PDEVICE_RELATIONS dev_relations;
753 PXEN_CHILD child, old_child;
754 //char *response;
755 char *msg;
756 char **devices;
757 char **instances;
758 int i, j;
759 CHAR path[128];
760 PDEVICE_OBJECT pdo;
762 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
764 msg = XenBus_List(xpdd, XBT_NIL, "device", &devices);
765 if (!msg)
766 {
767 for (child = (PXEN_CHILD)xpdd->child_list.Flink; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
768 {
769 if (child->state == CHILD_STATE_DELETED)
770 KdPrint((__DRIVER_NAME " Found deleted child - this shouldn't happen\n" ));
771 child->state = CHILD_STATE_DELETED;
772 }
774 for (i = 0; devices[i]; i++)
775 {
776 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "device/%s", devices[i]);
777 msg = XenBus_List(xpdd, XBT_NIL, path, &instances);
778 if (!msg)
779 {
780 for (j = 0; instances[j]; j++)
781 {
782 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "device/%s/%s", devices[i], instances[j]);
784 for (child = (PXEN_CHILD)xpdd->child_list.Flink; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
785 {
786 if (strcmp(child->context->path, path) == 0)
787 {
788 KdPrint((__DRIVER_NAME " Existing device %s\n", path));
789 ASSERT(child->state == CHILD_STATE_DELETED);
790 child->state = CHILD_STATE_ADDED;
791 device_count++;
792 break;
793 }
794 }
796 if (child == (PXEN_CHILD)&xpdd->child_list)
797 {
798 KdPrint((__DRIVER_NAME " New device %s\n", path));
799 child = ExAllocatePoolWithTag(NonPagedPool, sizeof(XEN_CHILD), XENPCI_POOL_TAG);
800 child->state = CHILD_STATE_ADDED;
801 status = IoCreateDeviceSecure(
802 xpdd->common.fdo->DriverObject,
803 sizeof(XENPCI_PDO_DEVICE_DATA),
804 NULL,
805 FILE_DEVICE_UNKNOWN,
806 FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,
807 FALSE,
808 &SDDL_DEVOBJ_SYS_ALL_ADM_ALL,
809 (LPCGUID)&GUID_XENPCI_DEVCLASS,
810 &pdo);
811 if (!NT_SUCCESS(status))
812 KdPrint((__DRIVER_NAME " IoCreateDevice status = %08X\n", status));
813 RtlZeroMemory(pdo->DeviceExtension, sizeof(XENPCI_PDO_DEVICE_DATA));
814 child->context = xppdd = pdo->DeviceExtension;
815 xppdd->common.fdo = NULL;
816 xppdd->common.pdo = pdo;
817 ObReferenceObject(pdo);
818 xppdd->common.lower_do = NULL;
819 INIT_PNP_STATE(&xppdd->common);
820 xppdd->common.device_usage_paging = 0;
821 xppdd->common.device_usage_dump = 0;
822 xppdd->common.device_usage_hibernation = 0;
823 xppdd->bus_fdo = xpdd->common.fdo;
824 xppdd->bus_pdo = xpdd->common.pdo;
825 RtlStringCbCopyA(xppdd->path, ARRAY_SIZE(xppdd->path), path);
826 RtlStringCbCopyA(xppdd->device, ARRAY_SIZE(xppdd->device), devices[i]);
827 xppdd->index = atoi(instances[j]);
828 KeInitializeEvent(&xppdd->backend_state_event, SynchronizationEvent, FALSE);
829 xppdd->backend_state = XenbusStateUnknown;
830 xppdd->backend_path[0] = '\0';
831 InsertTailList(&xpdd->child_list, (PLIST_ENTRY)child);
832 device_count++;
833 }
834 XenPci_FreeMem(instances[j]);
835 }
836 XenPci_FreeMem(instances);
837 }
838 XenPci_FreeMem(devices[i]);
839 }
840 XenPci_FreeMem(devices);
841 dev_relations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (device_count - 1), XENPCI_POOL_TAG);
842 for (child = (PXEN_CHILD)xpdd->child_list.Flink, device_count = 0; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
843 {
844 if (child->state == CHILD_STATE_ADDED)
845 {
846 ObReferenceObject(child->context->common.pdo);
847 dev_relations->Objects[device_count++] = child->context->common.pdo;
848 }
849 }
850 dev_relations->Count = device_count;
852 child = (PXEN_CHILD)xpdd->child_list.Flink;
853 while (child != (PXEN_CHILD)&xpdd->child_list)
854 {
855 if (child->state == CHILD_STATE_DELETED)
856 {
857 KdPrint((__DRIVER_NAME " Removing deleted child from device list\n" ));
858 old_child = child;
859 child = (PXEN_CHILD)child->entry.Flink;
860 RemoveEntryList((PLIST_ENTRY)old_child);
861 xppdd = old_child->context;
862 xppdd->ReportedMissing = TRUE;
863 ObDereferenceObject(xppdd->common.pdo);
864 ExFreePoolWithTag(old_child, XENPCI_POOL_TAG);
865 }
866 else
867 child = (PXEN_CHILD)child->entry.Flink;
868 }
870 status = STATUS_SUCCESS;
871 }
872 else
873 {
874 /* this should probably fail in an even worse way - a failure here means we failed to do an ls in xenbus so something is really really wrong */
875 device_count = 0;
876 dev_relations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (device_count - 1), XENPCI_POOL_TAG);
877 dev_relations->Count = device_count;
878 }
880 irp->IoStatus.Status = status;
881 irp->IoStatus.Information = (ULONG_PTR)dev_relations;
883 IoCompleteRequest (irp, IO_NO_INCREMENT);
885 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
886 }
888 static NTSTATUS
889 XenPci_Pnp_QueryBusRelations(PDEVICE_OBJECT device_object, PIRP irp)
890 {
891 NTSTATUS status;
893 UNREFERENCED_PARAMETER(device_object);
895 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
897 IoMarkIrpPending(irp);
899 status = XenPci_SendAndWaitForIrp(device_object, irp);
901 XenPci_QueueWorkItem(device_object, XenPci_Pnp_QueryBusRelationsCallback, irp);
903 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
905 return STATUS_PENDING;
906 }
908 static VOID
909 XenPci_Pnp_FilterResourceRequirementsCallback(PDEVICE_OBJECT device_object, PVOID context)
910 {
911 NTSTATUS status = STATUS_SUCCESS;
912 //PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
913 PIRP irp = context;
914 PIO_RESOURCE_REQUIREMENTS_LIST irrl;
915 ULONG irl;
916 ULONG ird;
918 UNREFERENCED_PARAMETER(device_object);
920 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (status = %08X)\n", irp->IoStatus.Status));
922 irrl = (PIO_RESOURCE_REQUIREMENTS_LIST)irp->IoStatus.Information;
923 for (irl = 0; irl < irrl->AlternativeLists; irl++)
924 {
925 for (ird = 0; ird < irrl->List[irl].Count; ird++)
926 {
927 if (irrl->List[irl].Descriptors[ird].Type == CmResourceTypeMemory)
928 {
929 irrl->List[irl].Descriptors[ird].ShareDisposition = CmResourceShareShared;
930 }
931 }
932 }
933 irp->IoStatus.Status = status;
934 IoCompleteRequest (irp, IO_NO_INCREMENT);
936 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
938 return;
939 }
941 static NTSTATUS
942 XenPci_Pnp_FilterResourceRequirements(PDEVICE_OBJECT device_object, PIRP irp)
943 {
944 NTSTATUS status;
946 UNREFERENCED_PARAMETER(device_object);
948 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
950 IoMarkIrpPending(irp);
952 status = XenPci_SendAndWaitForIrp(device_object, irp);
954 XenPci_QueueWorkItem(device_object, XenPci_Pnp_FilterResourceRequirementsCallback, irp);
956 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
958 return STATUS_PENDING;
959 }
961 static NTSTATUS
962 XenPci_Pnp_DeviceUsageNotification(PDEVICE_OBJECT device_object, PIRP irp, PVOID context)
963 {
964 NTSTATUS status;
965 PXENPCI_DEVICE_DATA xpdd;
966 PIO_STACK_LOCATION stack;
968 UNREFERENCED_PARAMETER(context);
970 KdPrint((__DRIVER_NAME " --> " __FUNCTION__"\n"));
972 xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
973 stack = IoGetCurrentIrpStackLocation(irp);
974 status = irp->IoStatus.Status;
976 /* fail if we are in a stop or remove pending state */
977 if (!NT_SUCCESS(irp->IoStatus.Status))
978 {
979 switch (stack->Parameters.UsageNotification.Type)
980 {
981 case DeviceUsageTypePaging:
982 if (stack->Parameters.UsageNotification.InPath)
983 xpdd->common.device_usage_paging--;
984 else
985 xpdd->common.device_usage_paging++;
986 break;
987 case DeviceUsageTypeDumpFile:
988 if (stack->Parameters.UsageNotification.InPath)
989 xpdd->common.device_usage_dump--;
990 else
991 xpdd->common.device_usage_dump++;
992 break;
993 case DeviceUsageTypeHibernation:
994 if (stack->Parameters.UsageNotification.InPath)
995 xpdd->common.device_usage_hibernation--;
996 else
997 xpdd->common.device_usage_hibernation++;
998 break;
999 }
1000 if (xpdd->common.device_usage_paging
1001 || xpdd->common.device_usage_dump
1002 || xpdd->common.device_usage_hibernation)
1004 xpdd->common.fdo->Flags &= ~DO_POWER_PAGABLE;
1006 IoInvalidateDeviceState(xpdd->common.pdo);
1008 IoCompleteRequest(irp, IO_NO_INCREMENT);
1010 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1012 return status;
1016 NTSTATUS
1017 XenPci_Pnp_Fdo(PDEVICE_OBJECT device_object, PIRP irp)
1019 NTSTATUS status;
1020 PIO_STACK_LOCATION stack;
1021 PXENPCI_DEVICE_DATA xpdd;
1023 //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
1025 xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
1027 stack = IoGetCurrentIrpStackLocation(irp);
1029 switch (stack->MinorFunction)
1031 case IRP_MN_START_DEVICE:
1032 KdPrint((__DRIVER_NAME " IRP_MN_START_DEVICE\n"));
1033 return XenPci_Pnp_StartDevice(device_object, irp);
1035 case IRP_MN_QUERY_STOP_DEVICE:
1036 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_STOP_DEVICE\n"));
1037 status = XenPci_Pnp_QueryStopRemoveDevice(device_object, irp);
1038 if (NT_SUCCESS(status))
1039 SET_PNP_STATE(&xpdd->common, RemovePending);
1040 return status;
1042 case IRP_MN_STOP_DEVICE:
1043 KdPrint((__DRIVER_NAME " IRP_MN_STOP_DEVICE\n"));
1044 IoCopyCurrentIrpStackLocationToNext(irp);
1045 IoSetCompletionRoutine(irp, XenPci_Pnp_StopDevice, NULL, TRUE, TRUE, TRUE);
1046 break;
1048 case IRP_MN_CANCEL_STOP_DEVICE:
1049 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_STOP_DEVICE\n"));
1050 IoSkipCurrentIrpStackLocation(irp);
1051 REVERT_PNP_STATE(&xpdd->common);
1052 irp->IoStatus.Status = STATUS_SUCCESS;
1053 break;
1055 case IRP_MN_QUERY_REMOVE_DEVICE:
1056 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_REMOVE_DEVICE\n"));
1057 status = XenPci_Pnp_QueryStopRemoveDevice(device_object, irp);
1058 if (NT_SUCCESS(status))
1059 SET_PNP_STATE(&xpdd->common, RemovePending);
1060 return status;
1062 case IRP_MN_REMOVE_DEVICE:
1063 KdPrint((__DRIVER_NAME " IRP_MN_REMOVE_DEVICE\n"));
1064 return XenPci_Pnp_RemoveDevice(device_object, irp);
1065 break;
1067 case IRP_MN_CANCEL_REMOVE_DEVICE:
1068 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_REMOVE_DEVICE\n"));
1069 IoSkipCurrentIrpStackLocation(irp);
1070 REVERT_PNP_STATE(&xpdd->common);
1071 irp->IoStatus.Status = STATUS_SUCCESS;
1072 break;
1074 case IRP_MN_SURPRISE_REMOVAL:
1075 KdPrint((__DRIVER_NAME " IRP_MN_SURPRISE_REMOVAL\n"));
1076 IoSkipCurrentIrpStackLocation(irp);
1077 irp->IoStatus.Status = STATUS_SUCCESS;
1078 break;
1080 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
1081 KdPrint((__DRIVER_NAME " IRP_MN_DEVICE_USAGE_NOTIFICATION\n"));
1082 switch (stack->Parameters.UsageNotification.Type)
1084 case DeviceUsageTypePaging:
1085 KdPrint((__DRIVER_NAME " type = DeviceUsageTypePaging = %d\n", stack->Parameters.UsageNotification.InPath));
1086 if (stack->Parameters.UsageNotification.InPath)
1087 xpdd->common.device_usage_paging++;
1088 else
1089 xpdd->common.device_usage_paging--;
1090 irp->IoStatus.Status = STATUS_SUCCESS;
1091 break;
1092 case DeviceUsageTypeDumpFile:
1093 KdPrint((__DRIVER_NAME " type = DeviceUsageTypeDumpFile = %d\n", stack->Parameters.UsageNotification.InPath));
1094 if (stack->Parameters.UsageNotification.InPath)
1095 xpdd->common.device_usage_dump++;
1096 else
1097 xpdd->common.device_usage_dump--;
1098 irp->IoStatus.Status = STATUS_SUCCESS;
1099 break;
1100 case DeviceUsageTypeHibernation:
1101 KdPrint((__DRIVER_NAME " type = DeviceUsageTypeHibernation = %d\n", stack->Parameters.UsageNotification.InPath));
1102 if (stack->Parameters.UsageNotification.InPath)
1103 xpdd->common.device_usage_hibernation++;
1104 else
1105 xpdd->common.device_usage_hibernation--;
1106 irp->IoStatus.Status = STATUS_SUCCESS;
1107 break;
1108 default:
1109 KdPrint((__DRIVER_NAME " type = unsupported (%d)\n", stack->Parameters.UsageNotification.Type));
1110 irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
1111 IoCompleteRequest(irp, IO_NO_INCREMENT);
1112 return STATUS_NOT_SUPPORTED;
1114 if (!xpdd->common.device_usage_paging
1115 && !xpdd->common.device_usage_dump
1116 && !xpdd->common.device_usage_hibernation)
1118 xpdd->common.fdo->Flags |= DO_POWER_PAGABLE;
1120 IoInvalidateDeviceState(xpdd->common.pdo);
1121 IoCopyCurrentIrpStackLocationToNext(irp);
1122 IoSetCompletionRoutine(irp, XenPci_Pnp_DeviceUsageNotification, NULL, TRUE, TRUE, TRUE);
1123 break;
1125 case IRP_MN_QUERY_DEVICE_RELATIONS:
1126 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_RELATIONS\n"));
1127 switch (stack->Parameters.QueryDeviceRelations.Type)
1129 case BusRelations:
1130 KdPrint((__DRIVER_NAME " BusRelations\n"));
1131 return XenPci_Pnp_QueryBusRelations(device_object, irp);
1132 break;
1133 default:
1134 IoSkipCurrentIrpStackLocation(irp);
1135 break;
1137 break;
1139 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
1140 KdPrint((__DRIVER_NAME " IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"));
1141 return XenPci_Pnp_FilterResourceRequirements(device_object, irp);
1143 case IRP_MN_QUERY_PNP_DEVICE_STATE:
1144 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_PNP_DEVICE_STATE\n"));
1145 irp->IoStatus.Status = STATUS_SUCCESS;
1146 if (xpdd->common.device_usage_paging
1147 || xpdd->common.device_usage_dump
1148 || xpdd->common.device_usage_hibernation)
1150 irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
1152 IoSkipCurrentIrpStackLocation(irp);
1153 break;
1155 default:
1156 //KdPrint((__DRIVER_NAME " Unhandled Minor = %d\n", stack->MinorFunction));
1157 IoSkipCurrentIrpStackLocation(irp);
1158 break;
1161 status = IoCallDriver(xpdd->common.lower_do, irp);
1163 //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1165 return status;
1168 NTSTATUS
1169 XenPci_Irp_Create_Fdo(PDEVICE_OBJECT device_object, PIRP irp)
1171 PXENPCI_DEVICE_DATA xpdd;
1172 NTSTATUS status;
1174 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
1176 xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
1177 status = STATUS_SUCCESS;
1178 irp->IoStatus.Status = status;
1179 IoCompleteRequest(irp, IO_NO_INCREMENT);
1181 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1183 return status;
1186 NTSTATUS
1187 XenPci_Irp_Close_Fdo(PDEVICE_OBJECT device_object, PIRP irp)
1189 PXENPCI_DEVICE_DATA xpdd;
1190 NTSTATUS status;
1192 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
1194 // wait until pending irp's
1195 xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
1196 status = STATUS_SUCCESS;
1197 irp->IoStatus.Status = status;
1198 IoCompleteRequest(irp, IO_NO_INCREMENT);
1200 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1202 return status;
1205 NTSTATUS
1206 XenPci_Irp_Read_Fdo(PDEVICE_OBJECT device_object, PIRP irp)
1208 PXENPCI_DEVICE_DATA xpdd;
1209 NTSTATUS status;
1210 PIO_STACK_LOCATION stack;
1211 KIRQL old_irql;
1213 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
1215 xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
1216 stack = IoGetCurrentIrpStackLocation(irp);
1217 if (stack->Parameters.Read.Length == 0)
1219 irp->IoStatus.Information = 0;
1220 status = STATUS_SUCCESS;
1221 irp->IoStatus.Status = status;
1222 IoCompleteRequest(irp, IO_NO_INCREMENT);
1224 else
1226 KdPrint((__DRIVER_NAME " stack = %p\n", stack));
1227 KdPrint((__DRIVER_NAME " length = %d, buffer = %p\n", stack->Parameters.Read.Length, irp->AssociatedIrp.SystemBuffer));
1229 KeAcquireSpinLock(&xpdd->shutdown_ring_lock, &old_irql);
1230 xpdd->shutdown_irp = irp;
1231 IoSetCancelRoutine(irp, XenBus_ShutdownIoCancel);
1232 KeReleaseSpinLock(&xpdd->shutdown_ring_lock, old_irql);
1233 status = XenPci_ProcessShutdownIrp(xpdd);
1235 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1237 return status;
1241 NTSTATUS
1242 XenPci_Irp_Cleanup_Fdo(PDEVICE_OBJECT device_object, PIRP irp)
1244 NTSTATUS status;
1246 UNREFERENCED_PARAMETER(device_object);
1248 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
1250 status = STATUS_SUCCESS;
1251 irp->IoStatus.Status = status;
1252 IoCompleteRequest(irp, IO_NO_INCREMENT);
1254 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1256 return status;
1259 #if 0
1260 static VOID
1261 XenPci_BalloonHandler(char *Path, PVOID Data)
1263 WDFDEVICE Device = Data;
1264 char *value;
1265 xenbus_transaction_t xbt;
1266 int retry;
1268 UNREFERENCED_PARAMETER(Path);
1270 KdPrint((__DRIVER_NAME " --> XenBus_BalloonHandler\n"));
1272 XenBus_StartTransaction(Device, &xbt);
1274 XenBus_Read(Device, XBT_NIL, BALLOON_PATH, &value);
1276 KdPrint((__DRIVER_NAME " Balloon Value = %s\n", value));
1278 // use the memory_op(unsigned int op, void *arg) hypercall to adjust this
1279 // use XENMEM_increase_reservation and XENMEM_decrease_reservation
1281 XenBus_EndTransaction(Device, xbt, 0, &retry);
1283 XenPci_FreeMem(value);
1285 KdPrint((__DRIVER_NAME " <-- XenBus_BalloonHandler\n"));
1287 #endif