win-pvdrivers

view xenpci/xenpci_pdo.c @ 364:2ff96a909c28

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