win-pvdrivers

view xenpci/xenpci_pdo.c @ 398:e7292fd9e55a

Fixup xenpci for mingw build with DBG enabled.

add FUNCTION_EXIT_STATUS macro
run unix2dos to fix line endings
update mingw makefiles
use FUNCTION_* macros in xenpci
author Andy Grover <andy.grover@oracle.com>
date Thu Jul 17 10:33:40 2008 -0700 (2008-07-17)
parents 099b6e3f3909
children 04883e1dc65c
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 /*
93 Called at PASSIVE_LEVEL(?)
94 Called during restore
95 */
96 static VOID
97 XenPci_BackEndStateHandler(char *Path, PVOID Context)
98 {
99 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)Context;
100 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
101 char *value;
102 char *err;
103 ULONG new_backend_state;
104 char path[128];
106 // KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
108 /* check that path == device/id/state */
109 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
110 err = XenBus_Read(xpdd, XBT_NIL, Path, &value);
111 if (err)
112 {
113 if (xpdd->suspend_state != SUSPEND_STATE_NONE)
114 return;
115 KdPrint(("Failed to read %s, assuming closed\n", path, err));
116 new_backend_state = XenbusStateClosed;
117 XenPci_FreeMem(err);
118 }
119 else
120 {
121 new_backend_state = atoi(value);
122 XenPci_FreeMem(value);
123 }
125 if (xppdd->backend_state == new_backend_state)
126 {
127 KdPrint((__DRIVER_NAME " state unchanged\n"));
128 //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
129 return;
130 }
132 xppdd->backend_state = new_backend_state;
134 switch (xppdd->backend_state)
135 {
136 case XenbusStateUnknown:
137 KdPrint((__DRIVER_NAME " Backend State Changed to Unknown\n"));
138 break;
140 case XenbusStateInitialising:
141 KdPrint((__DRIVER_NAME " Backend State Changed to Initialising\n"));
142 break;
144 case XenbusStateInitWait:
145 KdPrint((__DRIVER_NAME " Backend State Changed to InitWait\n"));
146 break;
148 case XenbusStateInitialised:
149 KdPrint((__DRIVER_NAME " Backend State Changed to Initialised\n"));
150 break;
152 case XenbusStateConnected:
153 KdPrint((__DRIVER_NAME " Backend State Changed to Connected\n"));
154 break;
156 case XenbusStateClosing:
157 KdPrint((__DRIVER_NAME " Backend State Changed to Closing\n"));
158 if (xppdd->common.device_usage_paging
159 || xppdd->common.device_usage_dump
160 || xppdd->common.device_usage_hibernation)
161 {
162 KdPrint((__DRIVER_NAME " Not closing device because it is in use\n"));
163 /* in use by page file, dump file, or hiber file - can't close */
164 /* we should probably re-check if the device usage changes in the future */
165 }
166 else
167 {
168 if (xppdd->common.current_pnp_state == Started)
169 {
170 KdPrint((__DRIVER_NAME " Sending RequestDeviceEject\n"));
171 xppdd->eject_requested = TRUE;
172 IoRequestDeviceEject(xppdd->common.pdo);
173 }
174 else
175 {
176 KdPrint((__DRIVER_NAME " Not closing device because it is not started\n"));
177 }
178 }
179 break;
181 case XenbusStateClosed:
182 KdPrint((__DRIVER_NAME " Backend State Changed to Closed\n"));
183 break;
185 default:
186 KdPrint((__DRIVER_NAME " Backend State Changed to Undefined = %d\n", xppdd->backend_state));
187 break;
188 }
190 KeSetEvent(&xppdd->backend_state_event, 1, FALSE);
192 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
194 return;
195 }
197 struct dummy_sring {
198 RING_IDX req_prod, req_event;
199 RING_IDX rsp_prod, rsp_event;
200 uint8_t pad[48];
201 };
203 /*
204 Called at PASSIVE_LEVEL
205 Called during restore
206 */
207 static NTSTATUS
208 XenPci_ChangeFrontendState(PXENPCI_PDO_DEVICE_DATA xppdd, ULONG frontend_state_set, ULONG backend_state_response, ULONG maximum_wait_ms)
209 {
210 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
211 LARGE_INTEGER timeout;
212 ULONG remaining;
213 ULONG thiswait;
214 char path[128];
216 /* Tell backend we're going down */
217 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
218 XenBus_Printf(xpdd, XBT_NIL, path, "%d", frontend_state_set);
220 remaining = maximum_wait_ms;
221 while (xppdd->backend_state != backend_state_response)
222 {
223 thiswait = min((LONG)remaining, 1000); // 1 second or remaining time, whichever is less
224 timeout.QuadPart = (LONGLONG)-1 * thiswait * 1000 * 10;
225 if (KeWaitForSingleObject(&xppdd->backend_state_event, Executive, KernelMode, FALSE, &timeout) == STATUS_TIMEOUT)
226 {
227 remaining -= thiswait;
228 if (remaining == 0)
229 {
230 KdPrint((__DRIVER_NAME " Timed out waiting for %d!\n", backend_state_response));
231 return STATUS_UNSUCCESSFUL;
232 }
233 KdPrint((__DRIVER_NAME " Still waiting for %d (currently %d)...\n", backend_state_response, xppdd->backend_state));
234 }
235 }
236 return STATUS_SUCCESS;
237 }
239 static VOID
240 DUMP_CURRENT_PNP_STATE(PXENPCI_PDO_DEVICE_DATA xppdd)
241 {
242 switch (xppdd->common.current_pnp_state)
243 {
244 case Unknown:
245 KdPrint((__DRIVER_NAME " pnp_state = Unknown\n"));
246 break;
247 case NotStarted:
248 KdPrint((__DRIVER_NAME " pnp_state = NotStarted\n"));
249 break;
250 case Started:
251 KdPrint((__DRIVER_NAME " pnp_state = Started\n"));
252 break;
253 case StopPending:
254 KdPrint((__DRIVER_NAME " pnp_state = StopPending\n"));
255 break;
256 case Stopped:
257 KdPrint((__DRIVER_NAME " pnp_state = Stopped\n"));
258 break;
259 case RemovePending:
260 KdPrint((__DRIVER_NAME " pnp_state = RemovePending\n"));
261 break;
262 case SurpriseRemovePending:
263 KdPrint((__DRIVER_NAME " pnp_state = SurpriseRemovePending\n"));
264 break;
265 case Removed:
266 KdPrint((__DRIVER_NAME " pnp_state = Removed\n"));
267 break;
268 default:
269 KdPrint((__DRIVER_NAME " pnp_state = ???\n"));
270 break;
271 }
272 }
274 static NTSTATUS
275 XenPci_EvtChn_Bind(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
276 {
277 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
278 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
280 return EvtChn_Bind(xpdd, Port, ServiceRoutine, ServiceContext);
281 }
283 static NTSTATUS
284 XenPci_EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
285 {
286 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
287 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
289 return EvtChn_BindDpc(xpdd, Port, ServiceRoutine, ServiceContext);
290 }
292 static NTSTATUS
293 XenPci_EvtChn_Unbind(PVOID Context, evtchn_port_t Port)
294 {
295 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
296 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
298 return EvtChn_Unbind(xpdd, Port);
299 }
301 static NTSTATUS
302 XenPci_EvtChn_Mask(PVOID Context, evtchn_port_t Port)
303 {
304 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
305 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
307 return EvtChn_Mask(xpdd, Port);
308 }
310 static NTSTATUS
311 XenPci_EvtChn_Unmask(PVOID Context, evtchn_port_t Port)
312 {
313 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
314 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
316 return EvtChn_Unmask(xpdd, Port);
317 }
319 static NTSTATUS
320 XenPci_EvtChn_Notify(PVOID Context, evtchn_port_t Port)
321 {
322 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
323 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
325 return EvtChn_Notify(xpdd, Port);
326 }
328 static grant_ref_t
329 XenPci_GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t frame, int readonly, grant_ref_t ref)
330 {
331 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
332 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
334 return GntTbl_GrantAccess(xpdd, domid, frame, readonly, ref);
335 }
337 static BOOLEAN
338 XenPci_GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref)
339 {
340 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
341 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
343 return GntTbl_EndAccess(xpdd, ref, keepref);
344 }
346 static VOID
347 XenPci_GntTbl_PutRef(PVOID Context, grant_ref_t ref)
348 {
349 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
350 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
352 GntTbl_PutRef(xpdd, ref);
353 }
355 static grant_ref_t
356 XenPci_GntTbl_GetRef(PVOID Context)
357 {
358 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
359 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
361 return GntTbl_GetRef(xpdd);
362 }
364 static NTSTATUS
365 XenPci_XenShutdownDevice(PVOID Context)
366 {
367 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
368 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
369 PUCHAR in_ptr;
370 ULONG i;
371 UCHAR type;
372 PVOID setting;
373 PVOID value;
375 FUNCTION_ENTER();
377 if (xppdd->backend_state == XenbusStateConnected)
378 {
379 XenPci_ChangeFrontendState(xppdd, XenbusStateClosing, XenbusStateClosing, 30000);
380 if (xppdd->backend_state == XenbusStateClosing)
381 XenPci_ChangeFrontendState(xppdd, XenbusStateClosed, XenbusStateClosed, 30000);
382 if (xppdd->backend_state == XenbusStateClosed)
383 XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000);
384 }
385 else
386 {
387 if (xppdd->backend_state == XenbusStateClosing)
388 XenPci_ChangeFrontendState(xppdd, XenbusStateClosed, XenbusStateClosed, 30000);
389 }
391 if (xppdd->assigned_resources_start != NULL)
392 {
393 ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL);
394 in_ptr = xppdd->assigned_resources_start;
395 while((type = GET_XEN_INIT_RSP(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
396 {
397 switch (type)
398 {
399 case XEN_INIT_TYPE_RING: /* frontend ring */
400 FreePages(value);
401 break;
402 case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
403 // don't know how to do this yet...
404 break;
405 case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
406 EvtChn_Unbind(xpdd, PtrToUlong(value));
407 break;
408 case XEN_INIT_TYPE_GRANT_ENTRIES:
409 for (i = 0; i < PtrToUlong(setting); i++)
410 GntTbl_EndAccess(xpdd, ((grant_ref_t *)value)[i], FALSE);
411 break;
412 }
413 }
414 ExFreePoolWithTag(xppdd->assigned_resources_start, XENPCI_POOL_TAG);
415 xppdd->assigned_resources_start = NULL;
416 }
418 FUNCTION_EXIT();
420 return STATUS_SUCCESS;
421 }
423 static NTSTATUS
424 XenPci_XenConfigDevice(PVOID context);
426 static NTSTATUS
427 XenPci_XenConfigDeviceSpecifyBuffers(PVOID context, PUCHAR src, PUCHAR dst)
428 {
429 PXENPCI_PDO_DEVICE_DATA xppdd = context;
430 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
431 NTSTATUS status = STATUS_SUCCESS;
432 ULONG i;
433 char path[128];
434 PCHAR setting, value;
435 PCHAR res;
436 PVOID address;
437 UCHAR type;
438 PUCHAR in_ptr; //, in_start;
439 PUCHAR out_ptr; //, out_start;
440 XENPCI_VECTORS vectors;
441 ULONG event_channel;
442 BOOLEAN run = FALSE;
443 PMDL ring;
444 grant_ref_t gref;
445 BOOLEAN done_xenbus_init = FALSE;
447 FUNCTION_ENTER();
449 in_ptr = src;
450 out_ptr = dst;
452 // always add vectors
453 vectors.magic = XEN_DATA_MAGIC;
454 vectors.length = sizeof(XENPCI_VECTORS);
455 vectors.context = xppdd;
456 vectors.EvtChn_Bind = XenPci_EvtChn_Bind;
457 vectors.EvtChn_BindDpc = XenPci_EvtChn_BindDpc;
458 vectors.EvtChn_Unbind = XenPci_EvtChn_Unbind;
459 vectors.EvtChn_Mask = XenPci_EvtChn_Mask;
460 vectors.EvtChn_Unmask = XenPci_EvtChn_Unmask;
461 vectors.EvtChn_Notify = XenPci_EvtChn_Notify;
462 vectors.GntTbl_GetRef = XenPci_GntTbl_GetRef;
463 vectors.GntTbl_PutRef = XenPci_GntTbl_PutRef;
464 vectors.GntTbl_GrantAccess = XenPci_GntTbl_GrantAccess;
465 vectors.GntTbl_EndAccess = XenPci_GntTbl_EndAccess;
466 vectors.XenPci_XenConfigDevice = XenPci_XenConfigDevice;
467 vectors.XenPci_XenShutdownDevice = XenPci_XenShutdownDevice;
468 ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_VECTORS, NULL, &vectors);
469 ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_STATE_PTR, NULL, &xppdd->device_state);
471 // first pass, possibly before state == Connected
472 while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value)) != XEN_INIT_TYPE_END)
473 {
475 if (!done_xenbus_init)
476 {
477 if (XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
478 {
479 status = STATUS_UNSUCCESSFUL;
480 goto error;
481 }
482 done_xenbus_init = TRUE;
483 }
485 ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, type, setting, value);
487 switch (type)
488 {
489 case XEN_INIT_TYPE_RUN:
490 run = TRUE;
491 case XEN_INIT_TYPE_WRITE_STRING: /* frontend setting = value */
492 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_WRITE_STRING - %s = %s\n", setting, value));
493 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
494 XenBus_Printf(xpdd, XBT_NIL, path, "%s", value);
495 break;
496 case XEN_INIT_TYPE_RING: /* frontend ring */
497 /* we only allocate and do the SHARED_RING_INIT here */
498 if ((ring = AllocatePage()) != 0)
499 {
500 address = MmGetMdlVirtualAddress(ring);
501 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, address));
502 SHARED_RING_INIT((struct dummy_sring *)address);
503 if ((gref = GntTbl_GrantAccess(
504 xpdd, 0, (ULONG)*MmGetMdlPfnArray(ring), FALSE, 0)) != 0)
505 {
506 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
507 XenBus_Printf(xpdd, XBT_NIL, path, "%d", gref);
508 ADD_XEN_INIT_RSP(&out_ptr, type, setting, address);
509 ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, ring);
510 // add the grant entry too so it gets freed automatically
511 __ADD_XEN_INIT_UCHAR(&xppdd->assigned_resources_ptr, XEN_INIT_TYPE_GRANT_ENTRIES);
512 __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, 1);
513 __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, gref);
514 }
515 else
516 {
517 FreePages(ring);
518 status = STATUS_UNSUCCESSFUL;
519 goto error;
520 }
521 }
522 else
523 {
524 status = STATUS_UNSUCCESSFUL;
525 goto error;
526 }
527 break;
528 case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
529 case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
530 if ((event_channel = EvtChn_AllocUnbound(xpdd, 0)) != 0)
531 {
532 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, event_channel));
533 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
534 XenBus_Printf(xpdd, XBT_NIL, path, "%d", event_channel);
535 ADD_XEN_INIT_RSP(&out_ptr, type, setting, UlongToPtr(event_channel));
536 ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, UlongToPtr(event_channel));
537 if (type == XEN_INIT_TYPE_EVENT_CHANNEL_IRQ)
538 EvtChn_BindIrq(xpdd, event_channel, xppdd->irq_vector);
539 }
540 else
541 {
542 status = STATUS_UNSUCCESSFUL;
543 goto error;
544 }
545 break;
546 }
547 }
548 if (!NT_SUCCESS(status))
549 {
550 goto error;
551 }
552 if (run)
553 {
554 if (XenPci_ChangeFrontendState(xppdd, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
555 {
556 status = STATUS_UNSUCCESSFUL;
557 goto error;
558 }
559 }
561 // second pass, possibly after state == Connected
562 in_ptr = src;
563 while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value)) != XEN_INIT_TYPE_END)
564 {
565 switch(type)
566 {
567 case XEN_INIT_TYPE_READ_STRING_BACK:
568 case XEN_INIT_TYPE_READ_STRING_FRONT:
569 if (type == XEN_INIT_TYPE_READ_STRING_FRONT)
570 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
571 else
572 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->backend_path, setting);
573 res = XenBus_Read(xpdd, XBT_NIL, path, &value);
574 if (res)
575 {
576 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = <failed>\n", setting));
577 XenPci_FreeMem(res);
578 ADD_XEN_INIT_RSP(&out_ptr, type, setting, NULL);
579 }
580 else
581 {
582 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
583 ADD_XEN_INIT_RSP(&out_ptr, type, setting, value);
584 XenPci_FreeMem(value);
585 }
586 break;
587 case XEN_INIT_TYPE_VECTORS:
588 // this is always done so ignore the request
589 break;
590 case XEN_INIT_TYPE_GRANT_ENTRIES:
591 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(value)));
592 __ADD_XEN_INIT_UCHAR(&out_ptr, type);
593 __ADD_XEN_INIT_UCHAR(&xppdd->assigned_resources_ptr, type);
594 __ADD_XEN_INIT_ULONG(&out_ptr, PtrToUlong(value));
595 __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, PtrToUlong(value));
596 for (i = 0; i < PtrToUlong(value); i++)
597 {
598 __ADD_XEN_INIT_ULONG(&out_ptr, GntTbl_GetRef(xpdd));
599 __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, GntTbl_GetRef(xpdd));
600 }
601 break;
602 }
603 }
604 ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_END, NULL, NULL);
606 error:
607 FUNCTION_EXIT_STATUS(status);
609 return status;
610 }
612 static NTSTATUS
613 XenPci_XenConfigDevice(PVOID context)
614 {
615 NTSTATUS status;
616 PUCHAR src, dst;
617 PXENPCI_PDO_DEVICE_DATA xppdd = context;
619 src = ExAllocatePoolWithTag(NonPagedPool, xppdd->config_page_length, XENPCI_POOL_TAG);
620 dst = MmMapIoSpace(xppdd->config_page_phys, xppdd->config_page_length, MmNonCached);
621 memcpy(src, dst, xppdd->config_page_length);
623 status = XenPci_XenConfigDeviceSpecifyBuffers(xppdd, src, dst);
625 MmUnmapIoSpace(dst, xppdd->config_page_length);
626 ExFreePoolWithTag(src, XENPCI_POOL_TAG);
628 return status;
629 }
631 static NTSTATUS
632 XenPci_GetBackendAndAddWatch(PDEVICE_OBJECT device_object)
633 {
634 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
635 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
636 char path[128];
637 PCHAR res;
638 PCHAR value;
640 if (strlen(xppdd->backend_path) != 0)
641 {
642 // this must be the restore path - remove the existing watch
643 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
644 KdPrint((__DRIVER_NAME " Removing old watch on %s\n", path));
645 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
646 }
648 /* Get backend path */
649 RtlStringCbPrintfA(path, ARRAY_SIZE(path),
650 "%s/backend", xppdd->path);
651 res = XenBus_Read(xpdd, XBT_NIL, path, &value);
652 if (res)
653 {
654 KdPrint((__DRIVER_NAME " Failed to read backend path\n"));
655 XenPci_FreeMem(res);
656 return STATUS_UNSUCCESSFUL;
657 }
658 RtlStringCbCopyA(xppdd->backend_path, ARRAY_SIZE(xppdd->backend_path), value);
659 XenPci_FreeMem(value);
661 /* Add watch on backend state */
662 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
663 XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
665 return STATUS_SUCCESS;
666 }
668 NTSTATUS
669 XenPci_Resume(PDEVICE_OBJECT device_object)
670 {
671 NTSTATUS status;
672 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
673 //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
674 //PUCHAR in_ptr;
675 //UCHAR type;
676 //PVOID setting;
677 //PVOID value;
678 //CHAR path[256];
679 //PVOID address;
680 ULONG old_backend_state;
681 PUCHAR src, dst;
683 FUNCTION_ENTER();
685 old_backend_state = xppdd->backend_state;
686 status = XenPci_GetBackendAndAddWatch(device_object);
687 if (!NT_SUCCESS(status)) {
688 FUNCTION_ERROR_EXIT();
689 return status;
690 }
692 if (xppdd->common.current_pnp_state == Started && old_backend_state == XenbusStateConnected)
693 {
695 if (XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
696 {
697 // this is probably an unrecoverable situation...
698 FUNCTION_ERROR_EXIT();
699 return STATUS_UNSUCCESSFUL;
700 }
701 if (xppdd->assigned_resources_ptr)
702 {
703 // reset things - feed the 'requested resources' back in
704 ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL);
705 src = xppdd->requested_resources_start;
706 xppdd->requested_resources_ptr = xppdd->requested_resources_start = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);;
707 xppdd->assigned_resources_ptr = xppdd->assigned_resources_start;
709 dst = MmMapIoSpace(xppdd->config_page_phys, xppdd->config_page_length, MmNonCached);
711 status = XenPci_XenConfigDeviceSpecifyBuffers(xppdd, src, dst);
713 MmUnmapIoSpace(dst, xppdd->config_page_length);
714 ExFreePoolWithTag(src, XENPCI_POOL_TAG);
715 }
716 if (XenPci_ChangeFrontendState(xppdd, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
717 {
718 // this is definitely an unrecoverable situation...
719 FUNCTION_ERROR_EXIT();
720 return STATUS_UNSUCCESSFUL;
721 }
722 }
724 FUNCTION_EXIT();
726 return STATUS_SUCCESS;
727 }
729 static NTSTATUS
730 XenPci_Pnp_StartDevice(PDEVICE_OBJECT device_object, PIRP irp)
731 {
732 NTSTATUS status = STATUS_SUCCESS;
733 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
734 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
735 PIO_STACK_LOCATION stack;
736 PCM_PARTIAL_RESOURCE_LIST prl;
737 PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
738 ULONG i;
739 char path[128];
741 FUNCTION_ENTER();
743 DUMP_CURRENT_PNP_STATE(xppdd);
745 stack = IoGetCurrentIrpStackLocation(irp);
747 status = XenPci_GetBackendAndAddWatch(device_object);
748 if (!NT_SUCCESS(status)) {
749 FUNCTION_ERROR_EXIT();
750 return status;
751 }
753 prl = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
754 for (i = 0; i < prl->Count; i++)
755 {
756 prd = & prl->PartialDescriptors[i];
757 switch (prd->Type)
758 {
759 case CmResourceTypeInterrupt:
760 KdPrint((__DRIVER_NAME " CmResourceTypeInterrupt\n"));
761 KdPrint((__DRIVER_NAME " irq_vector = %02x\n", prd->u.Interrupt.Vector));
762 KdPrint((__DRIVER_NAME " irq_level = %d\n", prd->u.Interrupt.Level));
763 xppdd->irq_vector = prd->u.Interrupt.Vector;
764 xppdd->irq_level = (KIRQL)prd->u.Interrupt.Level;
765 break;
766 case CmResourceTypeMemory:
767 KdPrint((__DRIVER_NAME " CmResourceTypeMemory\n"));
768 KdPrint((__DRIVER_NAME " Start = %08x, Length = %d\n", prd->u.Memory.Start.LowPart, prd->u.Memory.Length));
769 xppdd->config_page_phys = prd->u.Memory.Start;
770 xppdd->config_page_length = prd->u.Memory.Length;
771 xppdd->requested_resources_start = xppdd->requested_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
772 xppdd->assigned_resources_start = xppdd->assigned_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
774 status = XenPci_XenConfigDevice(xppdd);
775 if (!NT_SUCCESS(status))
776 {
777 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
778 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
779 FUNCTION_ERROR_EXIT();
780 return status;
781 }
782 }
783 }
784 SET_PNP_STATE(&xppdd->common, Started);
786 FUNCTION_EXIT();
788 return STATUS_SUCCESS;
789 }
791 static NTSTATUS
792 XenPci_Pnp_RemoveDevice(PDEVICE_OBJECT device_object, PIRP irp)
793 {
794 NTSTATUS status = STATUS_SUCCESS;
795 PXENPCI_PDO_DEVICE_DATA xppdd = device_object->DeviceExtension;
796 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
797 char path[128];
799 UNREFERENCED_PARAMETER(irp);
801 FUNCTION_ENTER();
803 DUMP_CURRENT_PNP_STATE(xppdd);
805 if (xppdd->common.current_pnp_state != Removed)
806 {
807 status = XenPci_XenShutdownDevice(xppdd);
808 /* Remove watch on backend state */
809 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
810 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
811 SET_PNP_STATE(&xppdd->common, Removed);
812 IoInvalidateDeviceRelations(xppdd->bus_pdo, BusRelations);
813 }
814 if (xppdd->reported_missing)
815 {
816 IoDeleteDevice(xppdd->common.pdo);
817 }
819 FUNCTION_EXIT_STATUS(status);
821 return status;
822 }
824 static NTSTATUS
825 XenPci_QueryResourceRequirements(PDEVICE_OBJECT device_object, PIRP irp)
826 {
827 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
828 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
829 PIO_RESOURCE_REQUIREMENTS_LIST irrl;
830 PIO_RESOURCE_DESCRIPTOR ird;
831 ULONG length;
832 ULONG available_interrupts[] = {2, 3, 4, 5, 7, 10, 11, 14, 15};
833 int i;
835 UNREFERENCED_PARAMETER(device_object);
837 length = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List) +
838 FIELD_OFFSET(IO_RESOURCE_LIST, Descriptors) +
839 sizeof(IO_RESOURCE_DESCRIPTOR) * ARRAY_SIZE(available_interrupts);
840 irrl = ExAllocatePoolWithTag(NonPagedPool,
841 length,
842 XENPCI_POOL_TAG);
844 irrl->ListSize = length;
845 irrl->InterfaceType = Internal;
846 irrl->BusNumber = 0;
847 irrl->SlotNumber = 0;
848 irrl->AlternativeLists = 1;
849 irrl->List[0].Version = 1;
850 irrl->List[0].Revision = 1;
851 irrl->List[0].Count = 0;
853 for (i = 0; i < ARRAY_SIZE(available_interrupts); i++)
854 {
855 if (i == (int)xpdd->irq_number)
856 continue;
857 ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
858 ird->Option = i?IO_RESOURCE_ALTERNATIVE:0;
859 ird->Type = CmResourceTypeInterrupt;
860 ird->ShareDisposition = CmResourceShareShared;
861 ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
862 ird->u.Interrupt.MinimumVector = available_interrupts[i];
863 ird->u.Interrupt.MaximumVector = available_interrupts[i];
864 }
866 irp->IoStatus.Information = (ULONG_PTR)irrl;
867 return STATUS_SUCCESS;
868 }
870 static NTSTATUS
871 XenPci_Pnp_QueryTargetRelations(PDEVICE_OBJECT device_object, PIRP irp)
872 {
873 PDEVICE_RELATIONS dr;
874 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
876 dr = (PDEVICE_RELATIONS)ExAllocatePoolWithTag (PagedPool, sizeof(DEVICE_RELATIONS), XENPCI_POOL_TAG);
877 dr->Count = 1;
878 dr->Objects[0] = xppdd->common.pdo;
879 ObReferenceObject(xppdd->common.pdo);
880 irp->IoStatus.Information = (ULONG_PTR)dr;
882 return STATUS_SUCCESS;
883 }
885 static NTSTATUS
886 XenPci_Pnp_QueryCapabilities(PDEVICE_OBJECT device_object, PIRP irp)
887 {
888 PIO_STACK_LOCATION stack;
889 PDEVICE_CAPABILITIES dc;
891 UNREFERENCED_PARAMETER(device_object);
893 stack = IoGetCurrentIrpStackLocation(irp);
894 dc = stack->Parameters.DeviceCapabilities.Capabilities;
895 dc->LockSupported = FALSE;
896 dc->EjectSupported = TRUE;
897 dc->Removable = TRUE;
898 dc->DockDevice = FALSE;
899 dc->UniqueID = FALSE;
900 dc->SilentInstall = TRUE; //FALSE;
901 dc->RawDeviceOK = FALSE;
902 dc->SurpriseRemovalOK = TRUE;
903 dc->HardwareDisabled = FALSE;
904 dc->NoDisplayInUI = FALSE;
905 dc->DeviceWake = PowerDeviceUnspecified;
906 dc->D1Latency = 0;
907 dc->D2Latency = 0;
908 dc->D3Latency = 0;
909 /* we are really supposed to get the DeviceState entries from the parent... */
910 dc->DeviceState[PowerSystemWorking] = PowerDeviceD0;
911 dc->DeviceState[PowerSystemSleeping1] = PowerDeviceUnspecified;
912 dc->DeviceState[PowerSystemSleeping2] = PowerDeviceUnspecified;
913 dc->DeviceState[PowerSystemSleeping3] = PowerDeviceUnspecified;
914 dc->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
915 dc->DeviceState[PowerSystemShutdown] = PowerDeviceD3;
916 return STATUS_SUCCESS;
917 }
919 NTSTATUS
920 XenPci_Pnp_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
921 {
922 NTSTATUS status;
923 PIO_STACK_LOCATION stack;
924 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
925 LPWSTR buffer;
926 WCHAR widebuf[256];
927 unsigned int i;
928 PPNP_BUS_INFORMATION pbi;
929 ULONG *usage_type;
931 //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
933 stack = IoGetCurrentIrpStackLocation(irp);
935 switch (stack->MinorFunction)
936 {
937 case IRP_MN_START_DEVICE:
938 KdPrint((__DRIVER_NAME " IRP_MN_START_DEVICE (status = %08x)\n", irp->IoStatus.Status));
939 status = XenPci_Pnp_StartDevice(device_object, irp);
940 break;
942 case IRP_MN_QUERY_STOP_DEVICE:
943 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
944 SET_PNP_STATE(&xppdd->common, StopPending);
945 status = STATUS_SUCCESS;
946 break;
948 case IRP_MN_STOP_DEVICE:
949 KdPrint((__DRIVER_NAME " IRP_MN_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
950 SET_PNP_STATE(&xppdd->common, Stopped);
951 status = STATUS_SUCCESS;
952 break;
954 case IRP_MN_CANCEL_STOP_DEVICE:
955 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
956 REVERT_PNP_STATE(&xppdd->common);
957 status = STATUS_SUCCESS;
958 break;
960 case IRP_MN_QUERY_REMOVE_DEVICE:
961 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
962 if (xppdd->eject_requested)
963 {
964 SET_PNP_STATE(&xppdd->common, RemovePending);
965 status = STATUS_SUCCESS;
966 }
967 else
968 {
969 status = STATUS_UNSUCCESSFUL;
970 }
971 break;
973 case IRP_MN_REMOVE_DEVICE:
974 KdPrint((__DRIVER_NAME " IRP_MN_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
975 status = XenPci_Pnp_RemoveDevice(device_object, irp);
976 break;
978 case IRP_MN_CANCEL_REMOVE_DEVICE:
979 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
980 REVERT_PNP_STATE(&xppdd->common);
981 status = STATUS_SUCCESS;
982 break;
984 case IRP_MN_SURPRISE_REMOVAL:
985 KdPrint((__DRIVER_NAME " IRP_MN_SURPRISE_REMOVAL (status = %08x)\n", irp->IoStatus.Status));
986 SET_PNP_STATE(&xppdd->common, SurpriseRemovePending);
987 status = STATUS_SUCCESS;
988 break;
990 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
991 KdPrint((__DRIVER_NAME " IRP_MN_DEVICE_USAGE_NOTIFICATION (status = %08x)\n", irp->IoStatus.Status));
993 usage_type = NULL;
994 switch (stack->Parameters.UsageNotification.Type)
995 {
996 case DeviceUsageTypePaging:
997 KdPrint((__DRIVER_NAME " type = DeviceUsageTypePaging\n"));
998 usage_type = &xppdd->common.device_usage_paging;
999 break;
1000 case DeviceUsageTypeDumpFile:
1001 KdPrint((__DRIVER_NAME " type = DeviceUsageTypeDumpFile\n"));
1002 usage_type = &xppdd->common.device_usage_dump;
1003 break;
1004 case DeviceUsageTypeHibernation:
1005 KdPrint((__DRIVER_NAME " type = DeviceUsageTypeHibernation\n"));
1006 usage_type = &xppdd->common.device_usage_hibernation;
1007 break;
1008 default:
1009 KdPrint((__DRIVER_NAME " Unknown usage type %x\n",
1010 stack->Parameters.UsageNotification.Type));
1011 break;
1013 KdPrint((__DRIVER_NAME " inpath = %d\n", stack->Parameters.UsageNotification.InPath));
1014 if (usage_type)
1016 if (stack->Parameters.UsageNotification.InPath)
1017 (*usage_type)++;
1018 else
1019 (*usage_type)--;
1021 status = STATUS_SUCCESS;
1022 break;
1024 case IRP_MN_QUERY_ID:
1025 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_ID (status = %08x)\n", irp->IoStatus.Status));
1026 switch (stack->Parameters.QueryId.IdType)
1028 case BusQueryDeviceID: /* REG_SZ */
1029 KdPrint((__DRIVER_NAME " BusQueryDeviceID\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 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1036 irp->IoStatus.Information = (ULONG_PTR)buffer;
1037 status = STATUS_SUCCESS;
1038 break;
1039 case BusQueryHardwareIDs: /* REG_MULTI_SZ */
1040 KdPrint((__DRIVER_NAME " BusQueryHardwareIDs\n"));
1041 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1042 for (i = 0; i < strlen(xppdd->device); i++)
1043 widebuf[i] = xppdd->device[i];
1044 widebuf[i] = 0;
1045 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
1046 for (i = 0; buffer[i] != 0; i++);
1047 buffer[i + 1] = 0;
1048 // for (i = 0; i < 256; i++)
1049 // KdPrint((__DRIVER_NAME " %04X: %04X %wc\n", i, buffer[i], buffer[i]));
1050 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1051 irp->IoStatus.Information = (ULONG_PTR)buffer;
1052 status = STATUS_SUCCESS;
1053 break;
1054 case BusQueryCompatibleIDs: /* REG_MULTI_SZ */
1055 KdPrint((__DRIVER_NAME " BusQueryCompatibleIDs\n"));
1056 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1057 for (i = 0; i < strlen(xppdd->device); i++)
1058 widebuf[i] = xppdd->device[i];
1059 widebuf[i] = 0;
1060 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
1061 for (i = 0; buffer[i] != 0; i++);
1062 buffer[i + 1] = 0;
1063 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1064 irp->IoStatus.Information = (ULONG_PTR)buffer;
1065 status = STATUS_SUCCESS;
1066 break;
1067 case BusQueryInstanceID: /* REG_SZ */
1068 KdPrint((__DRIVER_NAME " BusQueryInstanceID\n"));
1069 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1070 RtlStringCbPrintfW(buffer, 512, L"%02d", xppdd->index);
1071 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1072 irp->IoStatus.Information = (ULONG_PTR)buffer;
1073 status = STATUS_SUCCESS;
1074 break;
1075 default:
1076 KdPrint((__DRIVER_NAME " Unhandled IdType = %d\n", stack->Parameters.QueryId.IdType));
1077 irp->IoStatus.Information = 0;
1078 status = STATUS_NOT_SUPPORTED;
1079 break;
1081 break;
1083 case IRP_MN_QUERY_DEVICE_TEXT:
1084 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_TEXT (status = %08x)\n", irp->IoStatus.Status));
1085 switch (stack->Parameters.QueryDeviceText.DeviceTextType)
1087 case DeviceTextDescription:
1088 KdPrint((__DRIVER_NAME " DeviceTextDescription\n"));
1089 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1090 for (i = 0; i < strlen(xppdd->device); i++)
1091 widebuf[i] = xppdd->device[i];
1092 widebuf[i] = 0;
1093 RtlStringCbPrintfW(buffer, 512, L"Xen %ws device #%d", widebuf, xppdd->index);
1094 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1095 irp->IoStatus.Information = (ULONG_PTR)buffer;
1096 status = STATUS_SUCCESS;
1097 break;
1098 case DeviceTextLocationInformation:
1099 KdPrint((__DRIVER_NAME " DeviceTextLocationInformation\n"));
1100 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1101 RtlStringCbPrintfW(buffer, 512, L"Xen Bus");
1102 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1103 irp->IoStatus.Information = (ULONG_PTR)buffer;
1104 status = STATUS_SUCCESS;
1105 break;
1106 default:
1107 KdPrint((__DRIVER_NAME " Unhandled IdType = %d\n", stack->Parameters.QueryDeviceText.DeviceTextType));
1108 irp->IoStatus.Information = 0;
1109 status = STATUS_NOT_SUPPORTED;
1110 break;
1112 break;
1114 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
1115 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_RESOURCE_REQUIREMENTS (status = %08x)\n", irp->IoStatus.Status));
1116 status = XenPci_QueryResourceRequirements(device_object, irp);
1117 break;
1119 case IRP_MN_QUERY_CAPABILITIES:
1120 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_CAPABILITIES (status = %08x)\n", irp->IoStatus.Status));
1121 status = XenPci_Pnp_QueryCapabilities(device_object, irp);
1122 break;
1124 case IRP_MN_QUERY_BUS_INFORMATION:
1125 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_BUS_INFORMATION (status = %08x)\n", irp->IoStatus.Status));
1126 pbi = (PPNP_BUS_INFORMATION)ExAllocatePoolWithTag(PagedPool, sizeof(PNP_BUS_INFORMATION), XENPCI_POOL_TAG);
1127 pbi->BusTypeGuid = GUID_BUS_TYPE_XEN;
1128 pbi->LegacyBusType = Internal;
1129 pbi->BusNumber = 0;
1130 irp->IoStatus.Information = (ULONG_PTR)pbi;
1131 status = STATUS_SUCCESS;
1132 break;
1134 case IRP_MN_QUERY_RESOURCES:
1135 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_RESOURCES (status = %08x)\n", irp->IoStatus.Status));
1136 status = irp->IoStatus.Status;
1137 #if 0
1138 crl = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, sizeof(CM_RESOURCE_LIST) - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR), XENPCI_POOL_TAG);
1139 crl->Count = 1;
1140 crl->List[0].InterfaceType = Internal;
1141 crl->List[0].BusNumber = 0;
1142 crl->List[0].PartialResourceList.Version = 0;
1143 crl->List[0].PartialResourceList.Revision = 0;
1144 crl->List[0].PartialResourceList.Count = 0;
1145 irp->IoStatus.Information = (ULONG_PTR)crl;
1146 status = STATUS_SUCCESS;
1147 #endif
1148 break;
1150 case IRP_MN_QUERY_PNP_DEVICE_STATE:
1151 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_PNP_DEVICE_STATE (status = %08x)\n", irp->IoStatus.Status));
1152 irp->IoStatus.Information = 0;
1153 status = STATUS_SUCCESS;
1154 break;
1156 case IRP_MN_QUERY_DEVICE_RELATIONS:
1157 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_RELATIONS (status = %08x)\n", irp->IoStatus.Status));
1158 switch (stack->Parameters.QueryDeviceRelations.Type)
1160 case TargetDeviceRelation:
1161 KdPrint((__DRIVER_NAME " BusRelations\n"));
1162 status = XenPci_Pnp_QueryTargetRelations(device_object, irp);
1163 break;
1164 default:
1165 status = irp->IoStatus.Status;
1166 break;
1168 break;
1170 case IRP_MN_EJECT:
1171 KdPrint((__DRIVER_NAME " IRP_MN_EJECT\n"));
1172 status = STATUS_SUCCESS;
1173 break;
1175 default:
1176 //KdPrint((__DRIVER_NAME " Unhandled Minor = %d, Status = %08x\n", stack->MinorFunction, irp->IoStatus.Status));
1177 status = irp->IoStatus.Status;
1178 break;
1181 irp->IoStatus.Status = status;
1182 IoCompleteRequest(irp, IO_NO_INCREMENT);
1184 //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1186 return status;
1189 NTSTATUS
1190 XenPci_Irp_Create_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1192 NTSTATUS status;
1194 UNREFERENCED_PARAMETER(device_object);
1196 FUNCTION_ENTER();
1198 status = irp->IoStatus.Status;
1199 IoCompleteRequest(irp, IO_NO_INCREMENT);
1201 FUNCTION_EXIT();
1203 return status;
1206 NTSTATUS
1207 XenPci_Irp_Close_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1209 NTSTATUS status;
1211 UNREFERENCED_PARAMETER(device_object);
1213 FUNCTION_ENTER();
1215 status = irp->IoStatus.Status;
1216 IoCompleteRequest(irp, IO_NO_INCREMENT);
1218 FUNCTION_EXIT();
1220 return status;
1223 NTSTATUS
1224 XenPci_Irp_Read_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1226 NTSTATUS status;
1228 UNREFERENCED_PARAMETER(device_object);
1230 FUNCTION_ENTER();
1232 status = irp->IoStatus.Status;
1233 IoCompleteRequest(irp, IO_NO_INCREMENT);
1235 FUNCTION_EXIT();
1237 return status;
1240 NTSTATUS
1241 XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1243 NTSTATUS status;
1245 UNREFERENCED_PARAMETER(device_object);
1247 FUNCTION_ENTER();
1249 status = irp->IoStatus.Status;
1250 IoCompleteRequest(irp, IO_NO_INCREMENT);
1252 FUNCTION_EXIT();
1254 return status;