win-pvdrivers

view xenpci/xenpci_pdo.c @ 353:a7c4b65e754a

Bugfixes for save/restore
author James Harper <james.harper@bendigoit.com.au>
date Wed Jul 02 09:54:40 2008 +1000 (2008-07-02)
parents 6cfd70daada3
children d2ebc66da34c
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 xppdd->eject_requested = TRUE;
166 IoRequestDeviceEject(xppdd->common.pdo);
167 }
168 else
169 {
170 KdPrint((__DRIVER_NAME " Not closing device because it is not started\n"));
171 }
172 }
173 break;
175 case XenbusStateClosed:
176 KdPrint((__DRIVER_NAME " Backend State Changed to Closed\n"));
177 break;
179 default:
180 KdPrint((__DRIVER_NAME " Backend State Changed to Undefined = %d\n", xppdd->backend_state));
181 break;
182 }
184 KeSetEvent(&xppdd->backend_state_event, 1, FALSE);
186 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
188 return;
189 }
191 struct dummy_sring {
192 RING_IDX req_prod, req_event;
193 RING_IDX rsp_prod, rsp_event;
194 uint8_t pad[48];
195 };
197 static NTSTATUS
198 XenPci_ChangeFrontendState(PXENPCI_PDO_DEVICE_DATA xppdd, ULONG frontend_state_set, ULONG backend_state_response, ULONG maximum_wait_ms)
199 {
200 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
201 LARGE_INTEGER timeout;
202 ULONG remaining;
203 ULONG thiswait;
204 char path[128];
206 /* Tell backend we're going down */
207 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
208 XenBus_Printf(xpdd, XBT_NIL, path, "%d", frontend_state_set);
210 remaining = maximum_wait_ms;
211 while (xppdd->backend_state != backend_state_response)
212 {
213 thiswait = min((LONG)remaining, 1000); // 1 second or remaining time, whichever is less
214 timeout.QuadPart = (LONGLONG)-1 * thiswait * 1000 * 10;
215 if (KeWaitForSingleObject(&xppdd->backend_state_event, Executive, KernelMode, FALSE, &timeout) == STATUS_TIMEOUT)
216 {
217 remaining -= thiswait;
218 if (remaining == 0)
219 {
220 KdPrint((__DRIVER_NAME " Timed out waiting for %d!\n", backend_state_response));
221 return STATUS_UNSUCCESSFUL;
222 }
223 KdPrint((__DRIVER_NAME " Still waiting for %d (currently %d)...\n", backend_state_response, xppdd->backend_state));
224 }
225 }
226 return STATUS_SUCCESS;
227 }
229 static VOID
230 DUMP_CURRENT_PNP_STATE(PXENPCI_PDO_DEVICE_DATA xppdd)
231 {
232 switch (xppdd->common.current_pnp_state)
233 {
234 case Unknown:
235 KdPrint((__DRIVER_NAME " pnp_state = Unknown\n"));
236 break;
237 case NotStarted:
238 KdPrint((__DRIVER_NAME " pnp_state = NotStarted\n"));
239 break;
240 case Started:
241 KdPrint((__DRIVER_NAME " pnp_state = Started\n"));
242 break;
243 case StopPending:
244 KdPrint((__DRIVER_NAME " pnp_state = StopPending\n"));
245 break;
246 case Stopped:
247 KdPrint((__DRIVER_NAME " pnp_state = Stopped\n"));
248 break;
249 case RemovePending:
250 KdPrint((__DRIVER_NAME " pnp_state = RemovePending\n"));
251 break;
252 case SurpriseRemovePending:
253 KdPrint((__DRIVER_NAME " pnp_state = SurpriseRemovePending\n"));
254 break;
255 case Removed:
256 KdPrint((__DRIVER_NAME " pnp_state = Removed\n"));
257 break;
258 default:
259 KdPrint((__DRIVER_NAME " pnp_state = ???\n"));
260 break;
261 }
262 }
264 static NTSTATUS
265 XenPci_EvtChn_Bind(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
266 {
267 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
268 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
270 return EvtChn_Bind(xpdd, Port, ServiceRoutine, ServiceContext);
271 }
273 static NTSTATUS
274 XenPci_EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
275 {
276 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
277 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
279 return EvtChn_BindDpc(xpdd, Port, ServiceRoutine, ServiceContext);
280 }
282 static NTSTATUS
283 XenPci_EvtChn_Unbind(PVOID Context, evtchn_port_t Port)
284 {
285 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
286 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
288 return EvtChn_Unbind(xpdd, Port);
289 }
291 static NTSTATUS
292 XenPci_EvtChn_Mask(PVOID Context, evtchn_port_t Port)
293 {
294 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
295 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
297 return EvtChn_Mask(xpdd, Port);
298 }
300 static NTSTATUS
301 XenPci_EvtChn_Unmask(PVOID Context, evtchn_port_t Port)
302 {
303 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
304 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
306 return EvtChn_Unmask(xpdd, Port);
307 }
309 static NTSTATUS
310 XenPci_EvtChn_Notify(PVOID Context, evtchn_port_t Port)
311 {
312 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
313 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
315 return EvtChn_Notify(xpdd, Port);
316 }
318 static grant_ref_t
319 XenPci_GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t frame, int readonly, grant_ref_t ref)
320 {
321 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
322 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
324 return GntTbl_GrantAccess(xpdd, domid, frame, readonly, ref);
325 }
327 static BOOLEAN
328 XenPci_GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref)
329 {
330 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
331 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
333 return GntTbl_EndAccess(xpdd, ref, keepref);
334 }
336 static VOID
337 XenPci_GntTbl_PutRef(PVOID Context, grant_ref_t ref)
338 {
339 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
340 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
342 GntTbl_PutRef(xpdd, ref);
343 }
345 static grant_ref_t
346 XenPci_GntTbl_GetRef(PVOID Context)
347 {
348 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
349 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
351 return GntTbl_GetRef(xpdd);
352 }
354 static NTSTATUS
355 XenPci_XenShutdownDevice(PVOID Context)
356 {
357 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
358 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
359 PUCHAR in_ptr;
360 ULONG i;
361 UCHAR type;
362 PVOID setting;
363 PVOID value;
365 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
367 if (xppdd->backend_state == XenbusStateConnected)
368 {
369 XenPci_ChangeFrontendState(xppdd, XenbusStateClosing, XenbusStateClosing, 30000);
370 if (xppdd->backend_state == XenbusStateClosing)
371 XenPci_ChangeFrontendState(xppdd, XenbusStateClosed, XenbusStateClosed, 30000);
372 if (xppdd->backend_state == XenbusStateClosed)
373 XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000);
374 }
375 else
376 {
377 if (xppdd->backend_state == XenbusStateClosing)
378 XenPci_ChangeFrontendState(xppdd, XenbusStateClosed, XenbusStateClosed, 30000);
379 }
381 if (xppdd->assigned_resources_start != NULL)
382 {
383 ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL);
384 in_ptr = xppdd->assigned_resources_start;
385 while((type = GET_XEN_INIT_RSP(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
386 {
387 switch (type)
388 {
389 case XEN_INIT_TYPE_RING: /* frontend ring */
390 FreePages(value);
391 break;
392 case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
393 // don't know how to do this yet...
394 break;
395 case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
396 EvtChn_Unbind(xpdd, PtrToUlong(value));
397 break;
398 case XEN_INIT_TYPE_GRANT_ENTRIES:
399 for (i = 0; i < PtrToUlong(setting); i++)
400 GntTbl_EndAccess(xpdd, ((grant_ref_t *)value)[i], FALSE);
401 break;
402 }
403 }
404 ExFreePoolWithTag(xppdd->assigned_resources_start, XENPCI_POOL_TAG);
405 xppdd->assigned_resources_start = NULL;
406 }
408 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
410 return STATUS_SUCCESS;
411 }
413 static NTSTATUS
414 XenPci_XenConfigDevice(PVOID context);
416 static NTSTATUS
417 XenPci_XenConfigDeviceSpecifyBuffers(PVOID context, PUCHAR src, PUCHAR dst)
418 {
419 PXENPCI_PDO_DEVICE_DATA xppdd = context;
420 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
421 NTSTATUS status = STATUS_SUCCESS;
422 ULONG i;
423 char path[128];
424 PCHAR setting, value;
425 PCHAR res;
426 PVOID address;
427 UCHAR type;
428 PUCHAR in_ptr; //, in_start;
429 PUCHAR out_ptr; //, out_start;
430 XENPCI_VECTORS vectors;
431 ULONG event_channel;
432 BOOLEAN run = FALSE;
433 PMDL ring;
434 grant_ref_t gref;
435 BOOLEAN done_xenbus_init = FALSE;
437 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
439 in_ptr = src;
440 out_ptr = dst;
442 // always add vectors
443 vectors.magic = XEN_DATA_MAGIC;
444 vectors.length = sizeof(XENPCI_VECTORS);
445 vectors.context = xppdd;
446 vectors.EvtChn_Bind = XenPci_EvtChn_Bind;
447 vectors.EvtChn_BindDpc = XenPci_EvtChn_BindDpc;
448 vectors.EvtChn_Unbind = XenPci_EvtChn_Unbind;
449 vectors.EvtChn_Mask = XenPci_EvtChn_Mask;
450 vectors.EvtChn_Unmask = XenPci_EvtChn_Unmask;
451 vectors.EvtChn_Notify = XenPci_EvtChn_Notify;
452 vectors.GntTbl_GetRef = XenPci_GntTbl_GetRef;
453 vectors.GntTbl_PutRef = XenPci_GntTbl_PutRef;
454 vectors.GntTbl_GrantAccess = XenPci_GntTbl_GrantAccess;
455 vectors.GntTbl_EndAccess = XenPci_GntTbl_EndAccess;
456 vectors.XenPci_XenConfigDevice = XenPci_XenConfigDevice;
457 vectors.XenPci_XenShutdownDevice = XenPci_XenShutdownDevice;
458 ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_VECTORS, NULL, &vectors);
459 ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_STATE_PTR, NULL, &xppdd->device_state);
461 // first pass, possibly before state == Connected
462 while((type = GET_XEN_INIT_REQ(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
463 {
464 if (!done_xenbus_init)
465 {
466 if (XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
467 {
468 status = STATUS_UNSUCCESSFUL;
469 goto error;
470 }
471 done_xenbus_init = TRUE;
472 }
474 ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, type, setting, value);
476 switch (type)
477 {
478 case XEN_INIT_TYPE_RUN:
479 run = TRUE;
480 case XEN_INIT_TYPE_WRITE_STRING: /* frontend setting = value */
481 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_WRITE_STRING - %s = %s\n", setting, value));
482 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
483 XenBus_Printf(xpdd, XBT_NIL, path, "%s", value);
484 break;
485 case XEN_INIT_TYPE_RING: /* frontend ring */
486 /* we only allocate and do the SHARED_RING_INIT here */
487 if ((ring = AllocatePage()) != 0)
488 {
489 address = MmGetMdlVirtualAddress(ring);
490 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, address));
491 SHARED_RING_INIT((struct dummy_sring *)address);
492 if ((gref = GntTbl_GrantAccess(
493 xpdd, 0, (ULONG)*MmGetMdlPfnArray(ring), FALSE, 0)) != 0)
494 {
495 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
496 XenBus_Printf(xpdd, XBT_NIL, path, "%d", gref);
497 ADD_XEN_INIT_RSP(&out_ptr, type, setting, address);
498 ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, ring);
499 // add the grant entry too so it gets freed automatically
500 __ADD_XEN_INIT_UCHAR(&xppdd->assigned_resources_ptr, XEN_INIT_TYPE_GRANT_ENTRIES);
501 __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, PtrToUlong(1));
502 __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, gref);
503 }
504 else
505 {
506 FreePages(ring);
507 status = STATUS_UNSUCCESSFUL;
508 goto error;
509 }
510 }
511 else
512 {
513 status = STATUS_UNSUCCESSFUL;
514 goto error;
515 }
516 break;
517 case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
518 case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
519 if ((event_channel = EvtChn_AllocUnbound(xpdd, 0)) != 0)
520 {
521 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, event_channel));
522 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
523 XenBus_Printf(xpdd, XBT_NIL, path, "%d", event_channel);
524 ADD_XEN_INIT_RSP(&out_ptr, type, setting, UlongToPtr(event_channel));
525 ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, UlongToPtr(event_channel));
526 if (type == XEN_INIT_TYPE_EVENT_CHANNEL_IRQ)
527 EvtChn_BindIrq(xpdd, event_channel, xppdd->irq_vector);
528 }
529 else
530 {
531 status = STATUS_UNSUCCESSFUL;
532 goto error;
533 }
534 break;
535 }
536 }
537 if (!NT_SUCCESS(status))
538 {
539 goto error;
540 }
541 if (run)
542 {
543 if (XenPci_ChangeFrontendState(xppdd, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
544 {
545 status = STATUS_UNSUCCESSFUL;
546 goto error;
547 }
548 }
550 // second pass, possibly after state == Connected
551 in_ptr = src;
552 while((type = GET_XEN_INIT_REQ(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
553 {
554 switch(type)
555 {
556 case XEN_INIT_TYPE_READ_STRING_BACK:
557 case XEN_INIT_TYPE_READ_STRING_FRONT:
558 if (type == XEN_INIT_TYPE_READ_STRING_FRONT)
559 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
560 else
561 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->backend_path, setting);
562 res = XenBus_Read(xpdd, XBT_NIL, path, &value);
563 if (res)
564 {
565 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = <failed>\n", setting));
566 XenPci_FreeMem(res);
567 ADD_XEN_INIT_RSP(&out_ptr, type, setting, NULL);
568 }
569 else
570 {
571 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
572 ADD_XEN_INIT_RSP(&out_ptr, type, setting, value);
573 XenPci_FreeMem(value);
574 }
575 break;
576 case XEN_INIT_TYPE_VECTORS:
577 // this is always done so ignore the request
578 break;
579 case XEN_INIT_TYPE_GRANT_ENTRIES:
580 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(value)));
581 __ADD_XEN_INIT_UCHAR(&out_ptr, type);
582 __ADD_XEN_INIT_UCHAR(&xppdd->assigned_resources_ptr, type);
583 __ADD_XEN_INIT_ULONG(&out_ptr, PtrToUlong(value));
584 __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, PtrToUlong(value));
585 for (i = 0; i < PtrToUlong(value); i++)
586 {
587 __ADD_XEN_INIT_ULONG(&out_ptr, GntTbl_GetRef(xpdd));
588 __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, GntTbl_GetRef(xpdd));
589 }
590 break;
591 }
592 }
593 ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_END, NULL, NULL);
595 error:
596 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (%08x\n", status));
598 return status;
599 }
601 static NTSTATUS
602 XenPci_XenConfigDevice(PVOID context)
603 {
604 NTSTATUS status;
605 PUCHAR src, dst;
606 PXENPCI_PDO_DEVICE_DATA xppdd = context;
608 src = ExAllocatePoolWithTag(PagedPool, xppdd->config_page_length, XENPCI_POOL_TAG);
609 dst = MmMapIoSpace(xppdd->config_page_phys, xppdd->config_page_length, MmNonCached);
610 memcpy(src, dst, xppdd->config_page_length);
612 status = XenPci_XenConfigDeviceSpecifyBuffers(xppdd, src, dst);
614 MmUnmapIoSpace(dst, xppdd->config_page_length);
615 ExFreePoolWithTag(src, XENPCI_POOL_TAG);
617 return status;
618 }
620 static NTSTATUS
621 XenPci_GetBackendAndAddWatch(PDEVICE_OBJECT device_object)
622 {
623 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
624 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
625 char path[128];
626 PCHAR res;
627 PCHAR value;
629 if (strlen(xppdd->backend_path) != 0)
630 {
631 // this must be the restore path - remove the existing watch
632 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
633 KdPrint((__DRIVER_NAME " Removing old watch on %s\n", path));
634 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
635 }
637 /* Get backend path */
638 RtlStringCbPrintfA(path, ARRAY_SIZE(path),
639 "%s/backend", xppdd->path);
640 res = XenBus_Read(xpdd, XBT_NIL, path, &value);
641 if (res)
642 {
643 KdPrint((__DRIVER_NAME " Failed to read backend path\n"));
644 XenPci_FreeMem(res);
645 return STATUS_UNSUCCESSFUL;
646 }
647 RtlStringCbCopyA(xppdd->backend_path, ARRAY_SIZE(xppdd->backend_path), value);
648 XenPci_FreeMem(value);
650 /* Add watch on backend state */
651 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
652 XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
654 return STATUS_SUCCESS;
655 }
657 NTSTATUS
658 XenPci_Resume(PDEVICE_OBJECT device_object)
659 {
660 NTSTATUS status;
661 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
662 //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
663 //PUCHAR in_ptr;
664 //UCHAR type;
665 //PVOID setting;
666 //PVOID value;
667 //CHAR path[256];
668 //PVOID address;
669 ULONG old_backend_state;
670 PUCHAR src, dst;
672 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
674 old_backend_state = xppdd->backend_state;
675 status = XenPci_GetBackendAndAddWatch(device_object);
676 if (!NT_SUCCESS(status))
677 return status;
679 if (xppdd->common.current_pnp_state == Started && old_backend_state == XenbusStateConnected)
680 {
682 if (XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
683 {
684 // this is probably an unrecoverable situation...
685 return STATUS_UNSUCCESSFUL;
686 }
687 if (xppdd->assigned_resources_ptr)
688 {
689 // reset things - feed the 'requested resources' back in
690 ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL);
691 src = xppdd->requested_resources_start;
692 xppdd->requested_resources_ptr = xppdd->requested_resources_start = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, XENPCI_POOL_TAG);;
693 xppdd->assigned_resources_ptr = xppdd->assigned_resources_start;
695 dst = MmMapIoSpace(xppdd->config_page_phys, xppdd->config_page_length, MmNonCached);
697 status = XenPci_XenConfigDeviceSpecifyBuffers(xppdd, src, dst);
699 MmUnmapIoSpace(dst, xppdd->config_page_length);
700 ExFreePoolWithTag(src, XENPCI_POOL_TAG);
701 }
702 if (XenPci_ChangeFrontendState(xppdd, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
703 {
704 // this is definitely an unrecoverable situation...
705 return STATUS_UNSUCCESSFUL;
706 }
707 }
708 return STATUS_SUCCESS;
709 }
711 static NTSTATUS
712 XenPci_Pnp_StartDevice(PDEVICE_OBJECT device_object, PIRP irp)
713 {
714 NTSTATUS status = STATUS_SUCCESS;
715 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
716 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
717 PIO_STACK_LOCATION stack;
718 PCM_PARTIAL_RESOURCE_LIST prl;
719 PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
720 ULONG i;
721 char path[128];
723 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
725 DUMP_CURRENT_PNP_STATE(xppdd);
727 stack = IoGetCurrentIrpStackLocation(irp);
729 status = XenPci_GetBackendAndAddWatch(device_object);
730 if (!NT_SUCCESS(status))
731 return status;
733 prl = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
734 for (i = 0; i < prl->Count; i++)
735 {
736 prd = & prl->PartialDescriptors[i];
737 switch (prd->Type)
738 {
739 case CmResourceTypeInterrupt:
740 KdPrint((__DRIVER_NAME " CmResourceTypeInterrupt\n"));
741 KdPrint((__DRIVER_NAME " irq_vector = %03x\n", prd->u.Interrupt.Vector));
742 KdPrint((__DRIVER_NAME " irq_level = %d\n", prd->u.Interrupt.Level));
743 xppdd->irq_vector = prd->u.Interrupt.Vector;
744 xppdd->irq_level = (KIRQL)prd->u.Interrupt.Level;
745 break;
746 case CmResourceTypeMemory:
747 KdPrint((__DRIVER_NAME " CmResourceTypeMemory\n"));
748 KdPrint((__DRIVER_NAME " Start = %08x, Length = %d\n", prd->u.Memory.Start.LowPart, prd->u.Memory.Length));
749 xppdd->config_page_phys = prd->u.Memory.Start;
750 xppdd->config_page_length = prd->u.Memory.Length;
751 xppdd->requested_resources_start = xppdd->requested_resources_ptr = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
752 xppdd->assigned_resources_start = xppdd->assigned_resources_ptr = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
754 status = XenPci_XenConfigDevice(xppdd);
756 if (!NT_SUCCESS(status))
757 {
758 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
759 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
760 return status;
761 }
762 }
763 }
764 SET_PNP_STATE(&xppdd->common, Started);
766 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
768 return STATUS_SUCCESS;
769 }
771 static NTSTATUS
772 XenPci_Pnp_RemoveDevice(PDEVICE_OBJECT device_object, PIRP irp)
773 {
774 NTSTATUS status = STATUS_SUCCESS;
775 PXENPCI_PDO_DEVICE_DATA xppdd = device_object->DeviceExtension;
776 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
777 char path[128];
779 UNREFERENCED_PARAMETER(irp);
781 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
783 DUMP_CURRENT_PNP_STATE(xppdd);
785 if (xppdd->common.current_pnp_state != Removed)
786 {
787 status = XenPci_XenShutdownDevice(xppdd);
788 /* Remove watch on backend state */
789 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
790 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
791 SET_PNP_STATE(&xppdd->common, Removed);
792 IoInvalidateDeviceRelations(xppdd->bus_pdo, BusRelations);
793 }
794 if (xppdd->reported_missing)
795 {
796 IoDeleteDevice(xppdd->common.pdo);
797 }
799 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (status = %08x)\n", status));
801 return status;
802 }
804 static NTSTATUS
805 XenPci_QueryResourceRequirements(PDEVICE_OBJECT device_object, PIRP irp)
806 {
807 //PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
808 //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
809 PIO_RESOURCE_REQUIREMENTS_LIST irrl;
810 PIO_RESOURCE_DESCRIPTOR ird;
811 ULONG length;
813 UNREFERENCED_PARAMETER(device_object);
815 length = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List) +
816 FIELD_OFFSET(IO_RESOURCE_LIST, Descriptors) +
817 sizeof(IO_RESOURCE_DESCRIPTOR) * 2;
818 irrl = ExAllocatePoolWithTag(PagedPool,
819 length,
820 XENPCI_POOL_TAG);
822 irrl->ListSize = length;
823 irrl->InterfaceType = Internal;
824 irrl->BusNumber = 0;
825 irrl->SlotNumber = 0;
826 irrl->AlternativeLists = 1;
827 irrl->List[0].Version = 1;
828 irrl->List[0].Revision = 1;
829 irrl->List[0].Count = 0;
831 ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
832 ird->Option = 0;
833 ird->Type = CmResourceTypeInterrupt;
834 ird->ShareDisposition = CmResourceShareShared;
835 ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
836 ird->u.Interrupt.MinimumVector = 1;
837 ird->u.Interrupt.MaximumVector = 6;
839 ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
840 ird->Option = IO_RESOURCE_ALTERNATIVE;
841 ird->Type = CmResourceTypeInterrupt;
842 ird->ShareDisposition = CmResourceShareShared;
843 ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
844 ird->u.Interrupt.MinimumVector = 10;
845 ird->u.Interrupt.MaximumVector = 14;
847 #if 0
848 ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
849 ird->Option = 0;
850 ird->Type = CmResourceTypeMemory;
851 ird->ShareDisposition = CmResourceShareDeviceExclusive;
852 ird->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
853 ird->u.Memory.Length = PAGE_SIZE;
854 ird->u.Memory.Alignment = PAGE_SIZE;
855 ird->u.Memory.MinimumAddress.QuadPart = 0; //MmGetMdlPfnArray(xppdd->config_mdl)[0] << PAGE_SHIFT;
856 ird->u.Memory.MaximumAddress.QuadPart = 0xFFFFFFFFFFFFFFFF; //ird->u.Memory.MinimumAddress.QuadPart + PAGE_SIZE - 1;
857 #endif
859 irp->IoStatus.Information = (ULONG_PTR)irrl;
860 return STATUS_SUCCESS;
861 }
863 static NTSTATUS
864 XenPci_Pnp_QueryTargetRelations(PDEVICE_OBJECT device_object, PIRP irp)
865 {
866 PDEVICE_RELATIONS dr;
867 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
869 dr = (PDEVICE_RELATIONS)ExAllocatePoolWithTag (PagedPool, sizeof(DEVICE_RELATIONS), XENPCI_POOL_TAG);
870 dr->Count = 1;
871 dr->Objects[0] = xppdd->common.pdo;
872 ObReferenceObject(xppdd->common.pdo);
873 irp->IoStatus.Information = (ULONG_PTR)dr;
875 return STATUS_SUCCESS;
876 }
878 static NTSTATUS
879 XenPci_Pnp_QueryCapabilities(PDEVICE_OBJECT device_object, PIRP irp)
880 {
881 PIO_STACK_LOCATION stack;
882 PDEVICE_CAPABILITIES dc;
884 UNREFERENCED_PARAMETER(device_object);
886 stack = IoGetCurrentIrpStackLocation(irp);
887 dc = stack->Parameters.DeviceCapabilities.Capabilities;
888 dc->LockSupported = FALSE;
889 dc->EjectSupported = TRUE;
890 dc->Removable = TRUE;
891 dc->DockDevice = FALSE;
892 dc->UniqueID = FALSE;
893 dc->SilentInstall = TRUE; //FALSE;
894 dc->RawDeviceOK = FALSE;
895 dc->SurpriseRemovalOK = TRUE;
896 dc->HardwareDisabled = FALSE;
897 dc->NoDisplayInUI = FALSE;
898 dc->DeviceWake = PowerDeviceUnspecified;
899 dc->D1Latency = 0;
900 dc->D2Latency = 0;
901 dc->D3Latency = 0;
902 /* we are really supposed to get the DeviceState entries from the parent... */
903 dc->DeviceState[PowerSystemWorking] = PowerDeviceD0;
904 dc->DeviceState[PowerSystemSleeping1] = PowerDeviceUnspecified;
905 dc->DeviceState[PowerSystemSleeping2] = PowerDeviceUnspecified;
906 dc->DeviceState[PowerSystemSleeping3] = PowerDeviceUnspecified;
907 dc->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
908 dc->DeviceState[PowerSystemShutdown] = PowerDeviceD3;
909 return STATUS_SUCCESS;
910 }
912 NTSTATUS
913 XenPci_Pnp_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
914 {
915 NTSTATUS status;
916 PIO_STACK_LOCATION stack;
917 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
918 LPWSTR buffer;
919 WCHAR widebuf[256];
920 unsigned int i;
921 PPNP_BUS_INFORMATION pbi;
922 ULONG *usage_type;
924 //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
926 stack = IoGetCurrentIrpStackLocation(irp);
928 switch (stack->MinorFunction)
929 {
930 case IRP_MN_START_DEVICE:
931 KdPrint((__DRIVER_NAME " IRP_MN_START_DEVICE (status = %08x)\n", irp->IoStatus.Status));
932 status = XenPci_Pnp_StartDevice(device_object, irp);
933 break;
935 case IRP_MN_QUERY_STOP_DEVICE:
936 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
937 SET_PNP_STATE(&xppdd->common, StopPending);
938 status = STATUS_SUCCESS;
939 break;
941 case IRP_MN_STOP_DEVICE:
942 KdPrint((__DRIVER_NAME " IRP_MN_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
943 SET_PNP_STATE(&xppdd->common, Stopped);
944 status = STATUS_SUCCESS;
945 break;
947 case IRP_MN_CANCEL_STOP_DEVICE:
948 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
949 REVERT_PNP_STATE(&xppdd->common);
950 status = STATUS_SUCCESS;
951 break;
953 case IRP_MN_QUERY_REMOVE_DEVICE:
954 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
955 if (xppdd->eject_requested)
956 {
957 SET_PNP_STATE(&xppdd->common, RemovePending);
958 status = STATUS_SUCCESS;
959 }
960 else
961 {
962 status = STATUS_UNSUCCESSFUL;
963 }
964 break;
966 case IRP_MN_REMOVE_DEVICE:
967 KdPrint((__DRIVER_NAME " IRP_MN_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
968 status = XenPci_Pnp_RemoveDevice(device_object, irp);
969 break;
971 case IRP_MN_CANCEL_REMOVE_DEVICE:
972 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
973 REVERT_PNP_STATE(&xppdd->common);
974 status = STATUS_SUCCESS;
975 break;
977 case IRP_MN_SURPRISE_REMOVAL:
978 KdPrint((__DRIVER_NAME " IRP_MN_SURPRISE_REMOVAL (status = %08x)\n", irp->IoStatus.Status));
979 SET_PNP_STATE(&xppdd->common, SurpriseRemovePending);
980 status = STATUS_SUCCESS;
981 break;
983 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
984 KdPrint((__DRIVER_NAME " IRP_MN_DEVICE_USAGE_NOTIFICATION (status = %08x)\n", irp->IoStatus.Status));
986 usage_type = NULL;
987 switch (stack->Parameters.UsageNotification.Type)
988 {
989 case DeviceUsageTypePaging:
990 KdPrint((__DRIVER_NAME " type = DeviceUsageTypePaging\n"));
991 usage_type = &xppdd->common.device_usage_paging;
992 break;
993 case DeviceUsageTypeDumpFile:
994 KdPrint((__DRIVER_NAME " type = DeviceUsageTypeDumpFile\n"));
995 usage_type = &xppdd->common.device_usage_dump;
996 break;
997 case DeviceUsageTypeHibernation:
998 KdPrint((__DRIVER_NAME " type = DeviceUsageTypeHibernation\n"));
999 usage_type = &xppdd->common.device_usage_hibernation;
1000 break;
1002 KdPrint((__DRIVER_NAME " inpath = %d\n", stack->Parameters.UsageNotification.InPath));
1003 if (usage_type)
1005 if (stack->Parameters.UsageNotification.InPath)
1006 (*usage_type)++;
1007 else
1008 (*usage_type)--;
1010 status = STATUS_SUCCESS;
1011 break;
1013 case IRP_MN_QUERY_ID:
1014 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_ID (status = %08x)\n", irp->IoStatus.Status));
1015 switch (stack->Parameters.QueryId.IdType)
1017 case BusQueryDeviceID: /* REG_SZ */
1018 KdPrint((__DRIVER_NAME " BusQueryDeviceID\n"));
1019 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1020 for (i = 0; i < strlen(xppdd->device); i++)
1021 widebuf[i] = xppdd->device[i];
1022 widebuf[i] = 0;
1023 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
1024 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1025 irp->IoStatus.Information = (ULONG_PTR)buffer;
1026 status = STATUS_SUCCESS;
1027 break;
1028 case BusQueryHardwareIDs: /* REG_MULTI_SZ */
1029 KdPrint((__DRIVER_NAME " BusQueryHardwareIDs\n"));
1030 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1031 for (i = 0; i < strlen(xppdd->device); i++)
1032 widebuf[i] = xppdd->device[i];
1033 widebuf[i] = 0;
1034 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
1035 for (i = 0; buffer[i] != 0; i++);
1036 buffer[i + 1] = 0;
1037 // for (i = 0; i < 256; i++)
1038 // KdPrint((__DRIVER_NAME " %04X: %04X %wc\n", i, buffer[i], buffer[i]));
1039 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1040 irp->IoStatus.Information = (ULONG_PTR)buffer;
1041 status = STATUS_SUCCESS;
1042 break;
1043 case BusQueryCompatibleIDs: /* REG_MULTI_SZ */
1044 KdPrint((__DRIVER_NAME " BusQueryCompatibleIDs\n"));
1045 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1046 for (i = 0; i < strlen(xppdd->device); i++)
1047 widebuf[i] = xppdd->device[i];
1048 widebuf[i] = 0;
1049 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
1050 for (i = 0; buffer[i] != 0; i++);
1051 buffer[i + 1] = 0;
1052 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1053 irp->IoStatus.Information = (ULONG_PTR)buffer;
1054 status = STATUS_SUCCESS;
1055 break;
1056 case BusQueryInstanceID: /* REG_SZ */
1057 KdPrint((__DRIVER_NAME " BusQueryInstanceID\n"));
1058 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1059 RtlStringCbPrintfW(buffer, 512, L"%02d", xppdd->index);
1060 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1061 irp->IoStatus.Information = (ULONG_PTR)buffer;
1062 status = STATUS_SUCCESS;
1063 break;
1064 default:
1065 KdPrint((__DRIVER_NAME " Unhandled IdType = %d\n", stack->Parameters.QueryId.IdType));
1066 irp->IoStatus.Information = 0;
1067 status = STATUS_NOT_SUPPORTED;
1068 break;
1070 break;
1072 case IRP_MN_QUERY_DEVICE_TEXT:
1073 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_TEXT (status = %08x)\n", irp->IoStatus.Status));
1074 switch (stack->Parameters.QueryDeviceText.DeviceTextType)
1076 case DeviceTextDescription:
1077 KdPrint((__DRIVER_NAME " DeviceTextDescription\n"));
1078 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1079 for (i = 0; i < strlen(xppdd->device); i++)
1080 widebuf[i] = xppdd->device[i];
1081 widebuf[i] = 0;
1082 RtlStringCbPrintfW(buffer, 512, L"Xen %ws device #%d", widebuf, xppdd->index);
1083 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1084 irp->IoStatus.Information = (ULONG_PTR)buffer;
1085 status = STATUS_SUCCESS;
1086 break;
1087 case DeviceTextLocationInformation:
1088 KdPrint((__DRIVER_NAME " DeviceTextLocationInformation\n"));
1089 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1090 RtlStringCbPrintfW(buffer, 512, L"Xen Bus");
1091 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1092 irp->IoStatus.Information = (ULONG_PTR)buffer;
1093 status = STATUS_SUCCESS;
1094 break;
1095 default:
1096 KdPrint((__DRIVER_NAME " Unhandled IdType = %d\n", stack->Parameters.QueryDeviceText.DeviceTextType));
1097 irp->IoStatus.Information = 0;
1098 status = STATUS_NOT_SUPPORTED;
1099 break;
1101 break;
1103 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
1104 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_RESOURCE_REQUIREMENTS (status = %08x)\n", irp->IoStatus.Status));
1105 status = XenPci_QueryResourceRequirements(device_object, irp);
1106 break;
1108 case IRP_MN_QUERY_CAPABILITIES:
1109 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_CAPABILITIES (status = %08x)\n", irp->IoStatus.Status));
1110 status = XenPci_Pnp_QueryCapabilities(device_object, irp);
1111 break;
1113 case IRP_MN_QUERY_BUS_INFORMATION:
1114 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_BUS_INFORMATION (status = %08x)\n", irp->IoStatus.Status));
1115 pbi = (PPNP_BUS_INFORMATION)ExAllocatePoolWithTag(PagedPool, sizeof(PNP_BUS_INFORMATION), XENPCI_POOL_TAG);
1116 pbi->BusTypeGuid = GUID_BUS_TYPE_XEN;
1117 pbi->LegacyBusType = Internal;
1118 pbi->BusNumber = 0;
1119 irp->IoStatus.Information = (ULONG_PTR)pbi;
1120 status = STATUS_SUCCESS;
1121 break;
1123 case IRP_MN_QUERY_RESOURCES:
1124 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_RESOURCES (status = %08x)\n", irp->IoStatus.Status));
1125 status = irp->IoStatus.Status;
1126 #if 0
1127 crl = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, sizeof(CM_RESOURCE_LIST) - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR), XENPCI_POOL_TAG);
1128 crl->Count = 1;
1129 crl->List[0].InterfaceType = Internal;
1130 crl->List[0].BusNumber = 0;
1131 crl->List[0].PartialResourceList.Version = 0;
1132 crl->List[0].PartialResourceList.Revision = 0;
1133 crl->List[0].PartialResourceList.Count = 0;
1134 irp->IoStatus.Information = (ULONG_PTR)crl;
1135 status = STATUS_SUCCESS;
1136 #endif
1137 break;
1139 case IRP_MN_QUERY_PNP_DEVICE_STATE:
1140 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_PNP_DEVICE_STATE (status = %08x)\n", irp->IoStatus.Status));
1141 irp->IoStatus.Information = 0;
1142 status = STATUS_SUCCESS;
1143 break;
1145 case IRP_MN_QUERY_DEVICE_RELATIONS:
1146 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_RELATIONS (status = %08x)\n", irp->IoStatus.Status));
1147 switch (stack->Parameters.QueryDeviceRelations.Type)
1149 case TargetDeviceRelation:
1150 KdPrint((__DRIVER_NAME " BusRelations\n"));
1151 status = XenPci_Pnp_QueryTargetRelations(device_object, irp);
1152 break;
1153 default:
1154 status = irp->IoStatus.Status;
1155 break;
1157 break;
1159 case IRP_MN_EJECT:
1160 KdPrint((__DRIVER_NAME " IRP_MN_EJECT\n"));
1161 status = STATUS_SUCCESS;
1162 break;
1164 default:
1165 //KdPrint((__DRIVER_NAME " Unhandled Minor = %d, Status = %08x\n", stack->MinorFunction, irp->IoStatus.Status));
1166 status = irp->IoStatus.Status;
1167 break;
1170 irp->IoStatus.Status = status;
1171 IoCompleteRequest(irp, IO_NO_INCREMENT);
1173 //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1175 return status;
1178 NTSTATUS
1179 XenPci_Irp_Create_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1181 NTSTATUS status;
1183 UNREFERENCED_PARAMETER(device_object);
1185 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
1187 status = irp->IoStatus.Status;
1188 IoCompleteRequest(irp, IO_NO_INCREMENT);
1190 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1192 return status;
1195 NTSTATUS
1196 XenPci_Irp_Close_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1198 NTSTATUS status;
1200 UNREFERENCED_PARAMETER(device_object);
1202 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
1204 status = irp->IoStatus.Status;
1205 IoCompleteRequest(irp, IO_NO_INCREMENT);
1207 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1209 return status;
1212 NTSTATUS
1213 XenPci_Irp_Read_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1215 NTSTATUS status;
1217 UNREFERENCED_PARAMETER(device_object);
1219 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
1221 status = irp->IoStatus.Status;
1222 IoCompleteRequest(irp, IO_NO_INCREMENT);
1224 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1226 return status;
1229 NTSTATUS
1230 XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1232 NTSTATUS status;
1234 UNREFERENCED_PARAMETER(device_object);
1236 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
1238 status = irp->IoStatus.Status;
1239 IoCompleteRequest(irp, IO_NO_INCREMENT);
1241 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1243 return status;