win-pvdrivers

view xenpci/xenpci_pdo.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 b4f7d75fbe24
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 <stdlib.h>
22 #include <io/ring.h>
24 #pragma warning(disable : 4200) // zero-sized array
25 #pragma warning(disable: 4127) // conditional expression is constant
27 NTSTATUS
28 XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
29 {
30 NTSTATUS status;
31 PIO_STACK_LOCATION stack;
32 POWER_STATE_TYPE power_type;
33 POWER_STATE power_state;
34 //PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
35 //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
37 UNREFERENCED_PARAMETER(device_object);
39 //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
41 stack = IoGetCurrentIrpStackLocation(irp);
42 power_type = stack->Parameters.Power.Type;
43 power_state = stack->Parameters.Power.State;
45 switch (stack->MinorFunction)
46 {
47 case IRP_MN_POWER_SEQUENCE:
48 //KdPrint((__DRIVER_NAME " IRP_MN_POWER_SEQUENCE\n"));
49 status = STATUS_NOT_SUPPORTED;
50 break;
51 case IRP_MN_QUERY_POWER:
52 //KdPrint((__DRIVER_NAME " IRP_MN_QUERY_POWER\n"));
53 status = STATUS_SUCCESS;
54 break;
55 case IRP_MN_SET_POWER:
56 //KdPrint((__DRIVER_NAME " IRP_MN_SET_POWER\n"));
57 switch (power_type) {
58 case DevicePowerState:
59 PoSetPowerState(device_object, power_type, power_state);
60 status = STATUS_SUCCESS;
61 break;
62 case SystemPowerState:
63 status = STATUS_SUCCESS;
64 break;
65 default:
66 status = STATUS_NOT_SUPPORTED;
67 break;
68 }
69 break;
70 case IRP_MN_WAIT_WAKE:
71 //KdPrint((__DRIVER_NAME " IRP_MN_WAIT_WAKE\n"));
72 status = STATUS_NOT_SUPPORTED;
73 break;
74 default:
75 //KdPrint((__DRIVER_NAME " Unknown IRP_MN_%d\n", stack->MinorFunction));
76 status = STATUS_NOT_SUPPORTED;
77 break;
78 }
79 if (status != STATUS_NOT_SUPPORTED) {
80 irp->IoStatus.Status = status;
81 }
83 PoStartNextPowerIrp(irp);
84 status = irp->IoStatus.Status;
85 IoCompleteRequest(irp, IO_NO_INCREMENT);
87 //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
89 return status;
90 }
92 static VOID
93 XenPci_BackEndStateHandler(char *Path, PVOID Context)
94 {
95 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)Context;
96 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
97 char *value;
98 char *err;
99 ULONG new_backend_state;
100 char path[128];
102 // KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
104 /* check that path == device/id/state */
105 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
106 err = XenBus_Read(xpdd, XBT_NIL, Path, &value);
107 if (err)
108 {
109 KdPrint(("Failed to read %s, assuming closed\n", path, err));
110 new_backend_state = XenbusStateClosed;
111 XenPci_FreeMem(err);
112 }
113 else
114 {
115 new_backend_state = atoi(value);
116 XenPci_FreeMem(value);
117 }
119 if (xppdd->backend_state == new_backend_state)
120 {
121 KdPrint((__DRIVER_NAME " state unchanged\n"));
122 //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
123 return;
124 }
126 xppdd->backend_state = new_backend_state;
128 switch (xppdd->backend_state)
129 {
130 case XenbusStateUnknown:
131 KdPrint((__DRIVER_NAME " Backend State Changed to Unknown\n"));
132 break;
134 case XenbusStateInitialising:
135 KdPrint((__DRIVER_NAME " Backend State Changed to Initialising\n"));
136 break;
138 case XenbusStateInitWait:
139 KdPrint((__DRIVER_NAME " Backend State Changed to InitWait\n"));
140 break;
142 case XenbusStateInitialised:
143 KdPrint((__DRIVER_NAME " Backend State Changed to Initialised\n"));
144 break;
146 case XenbusStateConnected:
147 KdPrint((__DRIVER_NAME " Backend State Changed to Connected\n"));
148 break;
150 case XenbusStateClosing:
151 KdPrint((__DRIVER_NAME " Backend State Changed to Closing\n"));
152 if (xppdd->common.device_usage_paging
153 || xppdd->common.device_usage_dump
154 || xppdd->common.device_usage_hibernation)
155 {
156 KdPrint((__DRIVER_NAME " Not closing device because it is in use\n"));
157 /* in use by page file, dump file, or hiber file - can't close */
158 /* we should probably re-check if the device usage changes in the future */
159 }
160 else
161 {
162 if (xppdd->common.current_pnp_state == Started)
163 {
164 KdPrint((__DRIVER_NAME " Sending RequestDeviceEject\n"));
165 IoRequestDeviceEject(xppdd->common.pdo);
166 }
167 else
168 {
169 KdPrint((__DRIVER_NAME " Not closing device because it is not started\n"));
170 }
171 }
172 break;
174 case XenbusStateClosed:
175 KdPrint((__DRIVER_NAME " Backend State Changed to Closed\n"));
176 break;
178 default:
179 KdPrint((__DRIVER_NAME " Backend State Changed to Undefined = %d\n", xppdd->backend_state));
180 break;
181 }
183 KeSetEvent(&xppdd->backend_state_event, 1, FALSE);
185 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
187 return;
188 }
190 struct dummy_sring {
191 RING_IDX req_prod, req_event;
192 RING_IDX rsp_prod, rsp_event;
193 uint8_t pad[48];
194 };
196 static NTSTATUS
197 XenPci_ChangeFrontendState(PXENPCI_PDO_DEVICE_DATA xppdd, ULONG frontend_state_set, ULONG backend_state_response, ULONG maximum_wait_ms)
198 {
199 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
200 LARGE_INTEGER timeout;
201 ULONG remaining;
202 ULONG thiswait;
203 char path[128];
205 /* Tell backend we're going down */
206 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
207 XenBus_Printf(xpdd, XBT_NIL, path, "%d", frontend_state_set);
209 remaining = maximum_wait_ms;
210 while (xppdd->backend_state != backend_state_response)
211 {
212 thiswait = min((LONG)remaining, 1000); // 1 second or remaining time, whichever is less
213 timeout.QuadPart = (LONGLONG)-1 * thiswait * 1000 * 10;
214 if (KeWaitForSingleObject(&xppdd->backend_state_event, Executive, KernelMode, FALSE, &timeout) == STATUS_TIMEOUT)
215 {
216 remaining -= thiswait;
217 if (remaining == 0)
218 {
219 KdPrint((__DRIVER_NAME " Timed out waiting for %d!\n", backend_state_response));
220 return STATUS_UNSUCCESSFUL;
221 }
222 KdPrint((__DRIVER_NAME " Still waiting for %d (currently %d)...\n", backend_state_response, xppdd->backend_state));
223 }
224 }
225 return STATUS_SUCCESS;
226 }
228 static VOID
229 DUMP_CURRENT_PNP_STATE(PXENPCI_PDO_DEVICE_DATA xppdd)
230 {
231 switch (xppdd->common.current_pnp_state)
232 {
233 case Unknown:
234 KdPrint((__DRIVER_NAME " pnp_state = Unknown\n"));
235 break;
236 case NotStarted:
237 KdPrint((__DRIVER_NAME " pnp_state = NotStarted\n"));
238 break;
239 case Started:
240 KdPrint((__DRIVER_NAME " pnp_state = Started\n"));
241 break;
242 case StopPending:
243 KdPrint((__DRIVER_NAME " pnp_state = StopPending\n"));
244 break;
245 case Stopped:
246 KdPrint((__DRIVER_NAME " pnp_state = Stopped\n"));
247 break;
248 case RemovePending:
249 KdPrint((__DRIVER_NAME " pnp_state = RemovePending\n"));
250 break;
251 case SurpriseRemovePending:
252 KdPrint((__DRIVER_NAME " pnp_state = SurpriseRemovePending\n"));
253 break;
254 case Removed:
255 KdPrint((__DRIVER_NAME " pnp_state = Removed\n"));
256 break;
257 default:
258 KdPrint((__DRIVER_NAME " pnp_state = ???\n"));
259 break;
260 }
261 }
263 static NTSTATUS
264 XenPci_EvtChn_Bind(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
265 {
266 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
267 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
269 return EvtChn_Bind(xpdd, Port, ServiceRoutine, ServiceContext);
270 }
272 static NTSTATUS
273 XenPci_EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
274 {
275 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
276 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
278 return EvtChn_BindDpc(xpdd, Port, ServiceRoutine, ServiceContext);
279 }
281 static NTSTATUS
282 XenPci_EvtChn_Unbind(PVOID Context, evtchn_port_t Port)
283 {
284 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
285 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
287 return EvtChn_Unbind(xpdd, Port);
288 }
290 static NTSTATUS
291 XenPci_EvtChn_Mask(PVOID Context, evtchn_port_t Port)
292 {
293 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
294 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
296 return EvtChn_Mask(xpdd, Port);
297 }
299 static NTSTATUS
300 XenPci_EvtChn_Unmask(PVOID Context, evtchn_port_t Port)
301 {
302 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
303 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
305 return EvtChn_Unmask(xpdd, Port);
306 }
308 static NTSTATUS
309 XenPci_EvtChn_Notify(PVOID Context, evtchn_port_t Port)
310 {
311 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
312 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
314 return EvtChn_Notify(xpdd, Port);
315 }
317 static grant_ref_t
318 XenPci_GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t frame, int readonly, grant_ref_t ref)
319 {
320 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
321 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
323 return GntTbl_GrantAccess(xpdd, domid, frame, readonly, ref);
324 }
326 static BOOLEAN
327 XenPci_GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref)
328 {
329 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
330 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
332 return GntTbl_EndAccess(xpdd, ref, keepref);
333 }
335 static VOID
336 XenPci_GntTbl_PutRef(PVOID Context, grant_ref_t ref)
337 {
338 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
339 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
341 GntTbl_PutRef(xpdd, ref);
342 }
344 static grant_ref_t
345 XenPci_GntTbl_GetRef(PVOID Context)
346 {
347 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
348 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
350 return GntTbl_GetRef(xpdd);
351 }
353 static NTSTATUS
354 XenPci_ShutdownDevice(PVOID Context)
355 {
356 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
358 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
360 if (xppdd->backend_state == XenbusStateConnected)
361 {
362 XenPci_ChangeFrontendState(xppdd, XenbusStateClosing, XenbusStateClosing, 30000);
363 if (xppdd->backend_state == XenbusStateClosing)
364 XenPci_ChangeFrontendState(xppdd, XenbusStateClosed, XenbusStateClosed, 30000);
365 if (xppdd->backend_state == XenbusStateClosed)
366 XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000);
367 }
368 else
369 {
370 if (xppdd->backend_state == XenbusStateClosing)
371 XenPci_ChangeFrontendState(xppdd, XenbusStateClosed, XenbusStateClosed, 30000);
372 }
373 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
375 return STATUS_SUCCESS;
376 }
378 // this may work in future versions of xen...
379 #if 0
380 static NTSTATUS
381 XenPci_Remap_Page(PXENPCI_DEVICE_DATA xpdd, PFN_NUMBER src, PFN_NUMBER dst)
382 {
383 xen_memory_exchange_t xme;
384 //xen_pfn_t *pfns;
385 int ret;
387 xme.in.domid = DOMID_SELF;
388 set_xen_guest_handle(xme.in.extent_start, src);
389 xme.in.nr_extents = 1;
390 xme.in.extent_order = 0;
391 xme.in.address_bits = 64;
393 xme.out.domid = DOMID_SELF;
394 set_xen_guest_handle(xme.out.extent_start, dst);
395 xme.out.nr_extents = 1;
396 xme.out.extent_order = 0;
397 xme.out.address_bits = 64;
399 xme.nr_exchanged = 0;
401 ret = HYPERVISOR_memory_op(xpdd, XENMEM_exchange, &xme);
402 KdPrint((__DRIVER_NAME " hypervisor memory op ret = %d\n", ret));
403 }
404 #endif
406 static NTSTATUS
407 XenPci_Pnp_StartDevice(PDEVICE_OBJECT device_object, PIRP irp)
408 {
409 NTSTATUS status = STATUS_SUCCESS;
410 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
411 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
412 PIO_STACK_LOCATION stack;
413 PCM_PARTIAL_RESOURCE_LIST res_list;
414 PCM_PARTIAL_RESOURCE_DESCRIPTOR res_descriptor;
415 ULONG i;
416 char path[128];
417 PCHAR setting, value;
418 PCHAR res;
419 PVOID address;
420 UCHAR type;
421 PUCHAR in_ptr = NULL;
422 PUCHAR out_ptr, out_start = NULL;
423 XENPCI_VECTORS vectors;
424 ULONG rings = 0;
425 ULONG event_channels = 0;
426 BOOLEAN has_config_page = FALSE;
427 PMDL mdl;
428 PCM_RESOURCE_LIST old_crl, new_crl;
429 PCM_PARTIAL_RESOURCE_LIST prl;
430 PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
431 ULONG old_length, new_length;
433 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
435 DUMP_CURRENT_PNP_STATE(xppdd);
437 xppdd->xenbus_request = NULL;
439 stack = IoGetCurrentIrpStackLocation(irp);
441 /* Get backend path */
442 RtlStringCbPrintfA(path, ARRAY_SIZE(path),
443 "%s/backend", xppdd->path);
444 res = XenBus_Read(xpdd, XBT_NIL, path, &value);
445 if (res)
446 {
447 KdPrint((__DRIVER_NAME " Failed to read backend path\n"));
448 XenPci_FreeMem(res);
449 return STATUS_UNSUCCESSFUL;
450 }
451 RtlStringCbCopyA(xppdd->backend_path, ARRAY_SIZE(xppdd->backend_path), value);
452 XenPci_FreeMem(value);
454 /* Add watch on backend state */
455 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
456 XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
458 #if 0
459 has_config_page = FALSE;
460 res_list = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
461 for (i = 0; i < res_list->Count; i++)
462 {
463 res_descriptor = &res_list->PartialDescriptors[i];
464 if (res_descriptor->Type == CmResourceTypeMemory)
465 {
466 has_config_page = TRUE;
467 break;
468 }
469 }
470 #endif
472 res_list = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
473 for (i = 0; i < res_list->Count; i++)
474 {
475 res_descriptor = &res_list->PartialDescriptors[i];
476 switch (res_descriptor->Type)
477 {
478 case CmResourceTypeInterrupt:
479 KdPrint((__DRIVER_NAME " irq_number = %d\n", res_descriptor->u.Interrupt.Vector));
480 KdPrint((__DRIVER_NAME " irq_level = %03x\n", res_descriptor->u.Interrupt.Level));
481 break;
482 }
483 }
485 res_list = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
486 for (i = 0; i < res_list->Count; i++)
487 {
488 res_descriptor = &res_list->PartialDescriptors[i];
489 switch (res_descriptor->Type)
490 {
491 case CmResourceTypeInterrupt:
492 KdPrint((__DRIVER_NAME " CmResourceTypeInterrupt\n"));
493 KdPrint((__DRIVER_NAME " irq_vector = %03x\n", res_descriptor->u.Interrupt.Vector));
494 KdPrint((__DRIVER_NAME " irq_level = %d\n", res_descriptor->u.Interrupt.Level));
495 xppdd->irq_vector = res_descriptor->u.Interrupt.Vector;
496 xppdd->irq_level = (KIRQL)res_descriptor->u.Interrupt.Level;
497 break;
498 case CmResourceTypeMemory:
499 KdPrint((__DRIVER_NAME " CmResourceTypeMemory\n"));
500 KdPrint((__DRIVER_NAME " Start = %08x, Length = %d\n", res_descriptor->u.Memory.Start.LowPart, res_descriptor->u.Memory.Length));
501 if (XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
502 {
503 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
504 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
505 return STATUS_UNSUCCESSFUL;
506 }
507 out_ptr = out_start = MmMapIoSpace(res_descriptor->u.Memory.Start, res_descriptor->u.Memory.Length, MmNonCached);
508 in_ptr = xppdd->xenbus_request = ExAllocatePoolWithTag(PagedPool, res_descriptor->u.Memory.Length, XENPCI_POOL_TAG);
509 KdPrint((__DRIVER_NAME " out_ptr = %p, in_ptr = %p\n", out_ptr, in_ptr));
510 memcpy(in_ptr, out_ptr, res_descriptor->u.Memory.Length);
512 while((type = GET_XEN_INIT_REQ(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
513 {
514 switch (type)
515 {
516 case XEN_INIT_TYPE_WRITE_STRING: /* frontend setting = value */
517 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_WRITE_STRING - %s = %s\n", setting, value));
518 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
519 XenBus_Printf(xpdd, XBT_NIL, path, "%s", value);
520 break;
521 case XEN_INIT_TYPE_RING: /* frontend ring */
522 /* we only allocate and do the SHARED_RING_INIT here */
523 if ((xppdd->mdls[rings] = AllocatePage()) != 0)
524 {
525 address = MmGetMdlVirtualAddress(xppdd->mdls[rings]);
526 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, address));
527 SHARED_RING_INIT((struct dummy_sring *)address);
528 if ((xppdd->grant_refs[rings] = GntTbl_GrantAccess(
529 xpdd, 0, (ULONG)*MmGetMdlPfnArray(xppdd->mdls[rings]), FALSE, 0)) != 0)
530 {
531 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
532 XenBus_Printf(xpdd, XBT_NIL, path, "%d", xppdd->grant_refs[rings]);
533 ADD_XEN_INIT_RSP(&out_ptr, type, setting, address);
534 }
535 else
536 {
537 status = STATUS_UNSUCCESSFUL;
538 }
539 }
540 else
541 {
542 xppdd->grant_refs[rings] = 0;
543 status = STATUS_UNSUCCESSFUL;
544 }
545 rings++;
546 break;
547 case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
548 case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
549 if ((xppdd->event_channels[event_channels] = EvtChn_AllocUnbound(xpdd, 0)) != 0)
550 {
551 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, xppdd->event_channels[event_channels]));
552 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
553 XenBus_Printf(xpdd, XBT_NIL, path, "%d", xppdd->event_channels[event_channels]);
554 ADD_XEN_INIT_RSP(&out_ptr, type, setting, UlongToPtr(xppdd->event_channels[event_channels]));
555 if (type == XEN_INIT_TYPE_EVENT_CHANNEL_IRQ)
556 EvtChn_BindIrq(xpdd, xppdd->event_channels[event_channels], xppdd->irq_vector);
557 }
558 else
559 {
560 status = STATUS_UNSUCCESSFUL;
561 }
562 event_channels++;
563 break;
564 case XEN_INIT_TYPE_COPY_PTR:
565 ADD_XEN_INIT_RSP(&out_ptr, type, setting, value);
566 break;
567 }
568 }
569 if (!NT_SUCCESS(status))
570 {
571 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
572 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
573 return status;
574 }
575 if (XenPci_ChangeFrontendState(xppdd, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
576 {
577 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
578 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
579 return STATUS_UNSUCCESSFUL;
580 }
581 }
582 }
584 res_list = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
585 for (i = 0; i < res_list->Count; i++)
586 {
587 res_descriptor = &res_list->PartialDescriptors[i];
588 switch (res_descriptor->Type) {
589 case CmResourceTypeMemory:
590 in_ptr = xppdd->xenbus_request;
591 while((type = GET_XEN_INIT_REQ(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
592 {
593 switch(type)
594 {
595 case XEN_INIT_TYPE_READ_STRING_BACK:
596 case XEN_INIT_TYPE_READ_STRING_FRONT:
597 if (type == XEN_INIT_TYPE_READ_STRING_FRONT)
598 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
599 else
600 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->backend_path, setting);
601 res = XenBus_Read(xpdd, XBT_NIL, path, &value);
602 if (res)
603 {
604 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = <failed>\n", setting));
605 XenPci_FreeMem(res);
606 ADD_XEN_INIT_RSP(&out_ptr, type, setting, NULL);
607 }
608 else
609 {
610 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
611 ADD_XEN_INIT_RSP(&out_ptr, type, setting, value);
612 XenPci_FreeMem(value);
613 }
614 break;
615 case XEN_INIT_TYPE_VECTORS:
616 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n"));
617 vectors.magic = XEN_DATA_MAGIC;
618 vectors.length = sizeof(XENPCI_VECTORS);
619 vectors.context = xppdd;
620 vectors.EvtChn_Bind = XenPci_EvtChn_Bind;
621 vectors.EvtChn_BindDpc = XenPci_EvtChn_BindDpc;
622 vectors.EvtChn_Unbind = XenPci_EvtChn_Unbind;
623 vectors.EvtChn_Mask = XenPci_EvtChn_Mask;
624 vectors.EvtChn_Unmask = XenPci_EvtChn_Unmask;
625 vectors.EvtChn_Notify = XenPci_EvtChn_Notify;
626 vectors.GntTbl_GetRef = XenPci_GntTbl_GetRef;
627 vectors.GntTbl_PutRef = XenPci_GntTbl_PutRef;
628 vectors.GntTbl_GrantAccess = XenPci_GntTbl_GrantAccess;
629 vectors.GntTbl_EndAccess = XenPci_GntTbl_EndAccess;
630 vectors.XenPci_ShutdownDevice = XenPci_ShutdownDevice;
631 ADD_XEN_INIT_RSP(&out_ptr, type, NULL, &vectors);
632 break;
633 case XEN_INIT_TYPE_GRANT_ENTRIES:
634 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(value)));
635 __ADD_XEN_INIT_UCHAR(&out_ptr, type);
636 __ADD_XEN_INIT_ULONG(&out_ptr, PtrToUlong(value));
637 for (i = 0; i < PtrToUlong(value); i++)
638 __ADD_XEN_INIT_ULONG(&out_ptr, GntTbl_GetRef(xpdd));
639 break;
640 }
641 }
642 ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_END, NULL, NULL);
643 MmUnmapIoSpace(out_start, res_descriptor->u.Memory.Length);
644 //ExFreePoolWithTag(in_start, XENPCI_POOL_TAG);
645 }
646 }
648 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
650 SET_PNP_STATE(&xppdd->common, Started);
652 return STATUS_SUCCESS;
653 }
655 static NTSTATUS
656 XenPci_Pnp_RemoveDevice(PDEVICE_OBJECT device_object, PIRP irp)
657 {
658 NTSTATUS status = STATUS_SUCCESS;
659 PXENPCI_PDO_DEVICE_DATA xppdd = device_object->DeviceExtension;
660 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
661 char path[128];
662 PCHAR setting, value;
663 UCHAR type;
664 PUCHAR in_ptr = NULL;
665 ULONG rings = 0;
666 ULONG event_channels = 0;
668 UNREFERENCED_PARAMETER(irp);
670 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
672 DUMP_CURRENT_PNP_STATE(xppdd);
674 if (xppdd->common.current_pnp_state != Removed)
675 {
676 status = XenPci_ShutdownDevice(xppdd);
678 if (xppdd->xenbus_request != NULL)
679 {
680 in_ptr = xppdd->xenbus_request;
681 while((type = GET_XEN_INIT_REQ(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
682 {
683 switch (type)
684 {
685 case XEN_INIT_TYPE_RING: /* frontend ring */
686 GntTbl_EndAccess(xpdd, xppdd->grant_refs[rings], FALSE);
687 FreePages(xppdd->mdls[rings]);
688 xppdd->mdls[rings] = NULL;
689 rings++;
690 break;
691 case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
692 case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
693 EvtChn_Unbind(xpdd, xppdd->event_channels[event_channels++]);
694 break;
695 }
696 }
697 ExFreePoolWithTag(xppdd->xenbus_request, XENPCI_POOL_TAG);
698 xppdd->xenbus_request = NULL;
699 }
700 /* Remove watch on backend state */
701 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
702 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
703 SET_PNP_STATE(&xppdd->common, Removed);
704 IoInvalidateDeviceRelations(xppdd->bus_pdo, BusRelations);
705 }
706 if (xppdd->ReportedMissing)
707 {
708 IoDeleteDevice(xppdd->common.pdo);
709 }
711 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (status = %08x)\n", status));
713 return status;
714 }
716 static NTSTATUS
717 XenPci_QueryResourceRequirements(PDEVICE_OBJECT device_object, PIRP irp)
718 {
719 //PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
720 //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
721 PIO_RESOURCE_REQUIREMENTS_LIST irrl;
722 PIO_RESOURCE_DESCRIPTOR ird;
723 ULONG length;
725 UNREFERENCED_PARAMETER(device_object);
727 length = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List) +
728 FIELD_OFFSET(IO_RESOURCE_LIST, Descriptors) +
729 sizeof(IO_RESOURCE_DESCRIPTOR) * 2;
730 irrl = ExAllocatePoolWithTag(PagedPool,
731 length,
732 XENPCI_POOL_TAG);
734 irrl->ListSize = length;
735 irrl->InterfaceType = Internal;
736 irrl->BusNumber = 0;
737 irrl->SlotNumber = 0;
738 irrl->AlternativeLists = 1;
739 irrl->List[0].Version = 1;
740 irrl->List[0].Revision = 1;
741 irrl->List[0].Count = 0;
743 ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
744 ird->Option = 0;
745 ird->Type = CmResourceTypeInterrupt;
746 ird->ShareDisposition = CmResourceShareShared;
747 ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
748 ird->u.Interrupt.MinimumVector = 1;
749 ird->u.Interrupt.MaximumVector = 6;
751 ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
752 ird->Option = IO_RESOURCE_ALTERNATIVE;
753 ird->Type = CmResourceTypeInterrupt;
754 ird->ShareDisposition = CmResourceShareShared;
755 ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
756 ird->u.Interrupt.MinimumVector = 10;
757 ird->u.Interrupt.MaximumVector = 14;
759 #if 0
760 ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
761 ird->Option = 0;
762 ird->Type = CmResourceTypeMemory;
763 ird->ShareDisposition = CmResourceShareDeviceExclusive;
764 ird->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
765 ird->u.Memory.Length = PAGE_SIZE;
766 ird->u.Memory.Alignment = PAGE_SIZE;
767 ird->u.Memory.MinimumAddress.QuadPart = 0; //MmGetMdlPfnArray(xppdd->config_mdl)[0] << PAGE_SHIFT;
768 ird->u.Memory.MaximumAddress.QuadPart = 0xFFFFFFFFFFFFFFFF; //ird->u.Memory.MinimumAddress.QuadPart + PAGE_SIZE - 1;
769 #endif
771 irp->IoStatus.Information = (ULONG_PTR)irrl;
772 return STATUS_SUCCESS;
773 }
775 static NTSTATUS
776 XenPci_Pnp_QueryTargetRelations(PDEVICE_OBJECT device_object, PIRP irp)
777 {
778 PDEVICE_RELATIONS dr;
779 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
781 dr = (PDEVICE_RELATIONS)ExAllocatePoolWithTag (PagedPool, sizeof(DEVICE_RELATIONS), XENPCI_POOL_TAG);
782 dr->Count = 1;
783 dr->Objects[0] = xppdd->common.pdo;
784 ObReferenceObject(xppdd->common.pdo);
785 irp->IoStatus.Information = (ULONG_PTR)dr;
787 return STATUS_SUCCESS;
788 }
790 static NTSTATUS
791 XenPci_Pnp_QueryCapabilities(PDEVICE_OBJECT device_object, PIRP irp)
792 {
793 PIO_STACK_LOCATION stack;
794 PDEVICE_CAPABILITIES dc;
796 UNREFERENCED_PARAMETER(device_object);
798 stack = IoGetCurrentIrpStackLocation(irp);
799 dc = stack->Parameters.DeviceCapabilities.Capabilities;
800 dc->LockSupported = FALSE;
801 dc->EjectSupported = FALSE; //TRUE;
802 dc->Removable = TRUE;
803 dc->DockDevice = FALSE;
804 dc->UniqueID = FALSE;
805 dc->SilentInstall = TRUE; //FALSE;
806 dc->RawDeviceOK = FALSE;
807 dc->SurpriseRemovalOK = TRUE;
808 dc->HardwareDisabled = FALSE;
809 dc->NoDisplayInUI = FALSE;
810 dc->DeviceWake = PowerDeviceUnspecified;
811 dc->D1Latency = 0;
812 dc->D2Latency = 0;
813 dc->D3Latency = 0;
814 /* we are really supposed to get the DeviceState entries from the parent... */
815 dc->DeviceState[PowerSystemWorking] = PowerDeviceD0;
816 dc->DeviceState[PowerSystemSleeping1] = PowerDeviceUnspecified;
817 dc->DeviceState[PowerSystemSleeping2] = PowerDeviceUnspecified;
818 dc->DeviceState[PowerSystemSleeping3] = PowerDeviceUnspecified;
819 dc->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
820 dc->DeviceState[PowerSystemShutdown] = PowerDeviceD3;
821 return STATUS_SUCCESS;
822 }
824 NTSTATUS
825 XenPci_Pnp_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
826 {
827 NTSTATUS status;
828 PIO_STACK_LOCATION stack;
829 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
830 LPWSTR buffer;
831 WCHAR widebuf[256];
832 unsigned int i;
833 PPNP_BUS_INFORMATION pbi;
834 ULONG *usage_type;
836 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
838 stack = IoGetCurrentIrpStackLocation(irp);
840 switch (stack->MinorFunction)
841 {
842 case IRP_MN_START_DEVICE:
843 KdPrint((__DRIVER_NAME " IRP_MN_START_DEVICE (status = %08x)\n", irp->IoStatus.Status));
844 status = XenPci_Pnp_StartDevice(device_object, irp);
845 break;
847 case IRP_MN_QUERY_STOP_DEVICE:
848 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
849 SET_PNP_STATE(&xppdd->common, StopPending);
850 status = STATUS_SUCCESS;
851 break;
853 case IRP_MN_STOP_DEVICE:
854 KdPrint((__DRIVER_NAME " IRP_MN_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
855 SET_PNP_STATE(&xppdd->common, Stopped);
856 status = STATUS_SUCCESS;
857 break;
859 case IRP_MN_CANCEL_STOP_DEVICE:
860 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
861 REVERT_PNP_STATE(&xppdd->common);
862 status = STATUS_SUCCESS;
863 break;
865 case IRP_MN_QUERY_REMOVE_DEVICE:
866 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
867 SET_PNP_STATE(&xppdd->common, RemovePending);
868 status = STATUS_SUCCESS;
869 break;
871 case IRP_MN_REMOVE_DEVICE:
872 KdPrint((__DRIVER_NAME " IRP_MN_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
873 status = XenPci_Pnp_RemoveDevice(device_object, irp);
874 break;
876 case IRP_MN_CANCEL_REMOVE_DEVICE:
877 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
878 REVERT_PNP_STATE(&xppdd->common);
879 status = STATUS_SUCCESS;
880 break;
882 case IRP_MN_SURPRISE_REMOVAL:
883 KdPrint((__DRIVER_NAME " IRP_MN_SURPRISE_REMOVAL (status = %08x)\n", irp->IoStatus.Status));
884 SET_PNP_STATE(&xppdd->common, SurpriseRemovePending);
885 status = STATUS_SUCCESS;
886 break;
888 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
889 KdPrint((__DRIVER_NAME " IRP_MN_DEVICE_USAGE_NOTIFICATION (status = %08x)\n", irp->IoStatus.Status));
891 usage_type = NULL;
892 switch (stack->Parameters.UsageNotification.Type)
893 {
894 case DeviceUsageTypePaging:
895 KdPrint((__DRIVER_NAME " type = DeviceUsageTypePaging\n"));
896 usage_type = &xppdd->common.device_usage_paging;
897 break;
898 case DeviceUsageTypeDumpFile:
899 KdPrint((__DRIVER_NAME " type = DeviceUsageTypeDumpFile\n"));
900 usage_type = &xppdd->common.device_usage_dump;
901 break;
902 case DeviceUsageTypeHibernation:
903 KdPrint((__DRIVER_NAME " type = DeviceUsageTypeHibernation\n"));
904 usage_type = &xppdd->common.device_usage_hibernation;
905 break;
906 }
907 KdPrint((__DRIVER_NAME " inpath = %d\n", stack->Parameters.UsageNotification.InPath));
908 if (usage_type)
909 {
910 if (stack->Parameters.UsageNotification.InPath)
911 (*usage_type)++;
912 else
913 (*usage_type)--;
914 }
915 status = STATUS_SUCCESS;
916 break;
918 case IRP_MN_QUERY_ID:
919 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_ID (status = %08x)\n", irp->IoStatus.Status));
920 switch (stack->Parameters.QueryId.IdType)
921 {
922 case BusQueryDeviceID: /* REG_SZ */
923 KdPrint((__DRIVER_NAME " BusQueryDeviceID\n"));
924 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
925 for (i = 0; i < strlen(xppdd->device); i++)
926 widebuf[i] = xppdd->device[i];
927 widebuf[i] = 0;
928 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
929 KdPrint((__DRIVER_NAME " %ls\n", buffer));
930 irp->IoStatus.Information = (ULONG_PTR)buffer;
931 status = STATUS_SUCCESS;
932 break;
933 case BusQueryHardwareIDs: /* REG_MULTI_SZ */
934 KdPrint((__DRIVER_NAME " BusQueryHardwareIDs\n"));
935 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
936 for (i = 0; i < strlen(xppdd->device); i++)
937 widebuf[i] = xppdd->device[i];
938 widebuf[i] = 0;
939 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
940 for (i = 0; buffer[i] != 0; i++);
941 buffer[i + 1] = 0;
942 // for (i = 0; i < 256; i++)
943 // KdPrint((__DRIVER_NAME " %04X: %04X %wc\n", i, buffer[i], buffer[i]));
944 KdPrint((__DRIVER_NAME " %ls\n", buffer));
945 irp->IoStatus.Information = (ULONG_PTR)buffer;
946 status = STATUS_SUCCESS;
947 break;
948 case BusQueryCompatibleIDs: /* REG_MULTI_SZ */
949 KdPrint((__DRIVER_NAME " BusQueryCompatibleIDs\n"));
950 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
951 for (i = 0; i < strlen(xppdd->device); i++)
952 widebuf[i] = xppdd->device[i];
953 widebuf[i] = 0;
954 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
955 for (i = 0; buffer[i] != 0; i++);
956 buffer[i + 1] = 0;
957 KdPrint((__DRIVER_NAME " %ls\n", buffer));
958 irp->IoStatus.Information = (ULONG_PTR)buffer;
959 status = STATUS_SUCCESS;
960 break;
961 case BusQueryInstanceID: /* REG_SZ */
962 KdPrint((__DRIVER_NAME " BusQueryInstanceID\n"));
963 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
964 RtlStringCbPrintfW(buffer, 512, L"%02d", xppdd->index);
965 KdPrint((__DRIVER_NAME " %ls\n", buffer));
966 irp->IoStatus.Information = (ULONG_PTR)buffer;
967 status = STATUS_SUCCESS;
968 break;
969 default:
970 KdPrint((__DRIVER_NAME " Unhandled IdType = %d\n", stack->Parameters.QueryId.IdType));
971 irp->IoStatus.Information = 0;
972 status = STATUS_NOT_SUPPORTED;
973 break;
974 }
975 break;
977 case IRP_MN_QUERY_DEVICE_TEXT:
978 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_TEXT (status = %08x)\n", irp->IoStatus.Status));
979 switch (stack->Parameters.QueryDeviceText.DeviceTextType)
980 {
981 case DeviceTextDescription:
982 KdPrint((__DRIVER_NAME " DeviceTextDescription\n"));
983 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
984 for (i = 0; i < strlen(xppdd->device); i++)
985 widebuf[i] = xppdd->device[i];
986 widebuf[i] = 0;
987 RtlStringCbPrintfW(buffer, 512, L"Xen %ws device #%d", widebuf, xppdd->index);
988 KdPrint((__DRIVER_NAME " %ls\n", buffer));
989 irp->IoStatus.Information = (ULONG_PTR)buffer;
990 status = STATUS_SUCCESS;
991 break;
992 case DeviceTextLocationInformation:
993 KdPrint((__DRIVER_NAME " DeviceTextLocationInformation\n"));
994 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
995 RtlStringCbPrintfW(buffer, 512, L"Xen Bus");
996 KdPrint((__DRIVER_NAME " %ls\n", buffer));
997 irp->IoStatus.Information = (ULONG_PTR)buffer;
998 status = STATUS_SUCCESS;
999 break;
1000 default:
1001 KdPrint((__DRIVER_NAME " Unhandled IdType = %d\n", stack->Parameters.QueryDeviceText.DeviceTextType));
1002 irp->IoStatus.Information = 0;
1003 status = STATUS_NOT_SUPPORTED;
1004 break;
1006 break;
1008 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
1009 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_RESOURCE_REQUIREMENTS (status = %08x)\n", irp->IoStatus.Status));
1010 status = XenPci_QueryResourceRequirements(device_object, irp);
1011 break;
1013 case IRP_MN_QUERY_CAPABILITIES:
1014 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_CAPABILITIES (status = %08x)\n", irp->IoStatus.Status));
1015 status = XenPci_Pnp_QueryCapabilities(device_object, irp);
1016 break;
1018 case IRP_MN_QUERY_BUS_INFORMATION:
1019 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_BUS_INFORMATION (status = %08x)\n", irp->IoStatus.Status));
1020 pbi = (PPNP_BUS_INFORMATION)ExAllocatePoolWithTag(PagedPool, sizeof(PNP_BUS_INFORMATION), XENPCI_POOL_TAG);
1021 pbi->BusTypeGuid = GUID_BUS_TYPE_XEN;
1022 pbi->LegacyBusType = Internal;
1023 pbi->BusNumber = 0;
1024 irp->IoStatus.Information = (ULONG_PTR)pbi;
1025 status = STATUS_SUCCESS;
1026 break;
1028 case IRP_MN_QUERY_RESOURCES:
1029 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_RESOURCES (status = %08x)\n", irp->IoStatus.Status));
1030 status = irp->IoStatus.Status;
1031 #if 0
1032 crl = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, sizeof(CM_RESOURCE_LIST) - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR), XENPCI_POOL_TAG);
1033 crl->Count = 1;
1034 crl->List[0].InterfaceType = Internal;
1035 crl->List[0].BusNumber = 0;
1036 crl->List[0].PartialResourceList.Version = 0;
1037 crl->List[0].PartialResourceList.Revision = 0;
1038 crl->List[0].PartialResourceList.Count = 0;
1039 irp->IoStatus.Information = (ULONG_PTR)crl;
1040 status = STATUS_SUCCESS;
1041 #endif
1042 break;
1044 case IRP_MN_QUERY_PNP_DEVICE_STATE:
1045 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_PNP_DEVICE_STATE (status = %08x)\n", irp->IoStatus.Status));
1046 irp->IoStatus.Information = 0;
1047 status = STATUS_SUCCESS;
1048 break;
1050 case IRP_MN_QUERY_DEVICE_RELATIONS:
1051 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_RELATIONS (status = %08x)\n", irp->IoStatus.Status));
1052 switch (stack->Parameters.QueryDeviceRelations.Type)
1054 case TargetDeviceRelation:
1055 KdPrint((__DRIVER_NAME " BusRelations\n"));
1056 status = XenPci_Pnp_QueryTargetRelations(device_object, irp);
1057 break;
1058 default:
1059 status = irp->IoStatus.Status;
1060 break;
1062 break;
1064 default:
1065 KdPrint((__DRIVER_NAME " Unhandled Minor = %d, Status = %08x\n", stack->MinorFunction, irp->IoStatus.Status));
1066 status = irp->IoStatus.Status;
1067 break;
1070 irp->IoStatus.Status = status;
1071 IoCompleteRequest(irp, IO_NO_INCREMENT);
1073 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1075 return status;
1078 NTSTATUS
1079 XenPci_Irp_Create_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1081 NTSTATUS status;
1083 UNREFERENCED_PARAMETER(device_object);
1085 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
1087 status = irp->IoStatus.Status;
1088 IoCompleteRequest(irp, IO_NO_INCREMENT);
1090 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1092 return status;
1095 NTSTATUS
1096 XenPci_Irp_Close_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1098 NTSTATUS status;
1100 UNREFERENCED_PARAMETER(device_object);
1102 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
1104 status = irp->IoStatus.Status;
1105 IoCompleteRequest(irp, IO_NO_INCREMENT);
1107 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1109 return status;
1112 NTSTATUS
1113 XenPci_Irp_Read_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1115 NTSTATUS status;
1117 UNREFERENCED_PARAMETER(device_object);
1119 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
1121 status = irp->IoStatus.Status;
1122 IoCompleteRequest(irp, IO_NO_INCREMENT);
1124 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1126 return status;
1129 NTSTATUS
1130 XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1132 NTSTATUS status;
1134 UNREFERENCED_PARAMETER(device_object);
1136 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
1138 status = irp->IoStatus.Status;
1139 IoCompleteRequest(irp, IO_NO_INCREMENT);
1141 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1143 return status;