win-pvdrivers

view xenpci/xenpci_pdo.c @ 403:abdcb860cfdf

More suspend/resume updates.
author James Harper <james.harper@bendigoit.com.au>
date Mon Jul 21 11:47:29 2008 +1000 (2008-07-21)
parents 04883e1dc65c
children b9028997f48b
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 */
97 static ULONG
98 XenPci_ReadBackendState(PXENPCI_PDO_DEVICE_DATA xppdd)
99 {
100 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
101 char path[128];
102 char *value;
103 char *err;
104 ULONG backend_state;
106 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
107 err = XenBus_Read(xpdd, XBT_NIL, path, &value);
108 if (err)
109 {
110 XenPci_FreeMem(err);
111 return XenbusStateUnknown;
112 }
113 else
114 {
115 backend_state = atoi(value);
116 XenPci_FreeMem(value);
117 return backend_state;
118 }
119 }
121 static VOID
122 XenPci_BackEndStateHandler(char *path, PVOID context)
123 {
124 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)context;
125 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
126 ULONG new_backend_state;
128 // KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
130 /* check that path == device/id/state */
131 //RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
132 new_backend_state = XenPci_ReadBackendState(xppdd);
133 if (new_backend_state == XenbusStateUnknown)
134 {
135 if (xpdd->suspend_state != SUSPEND_STATE_NONE)
136 return;
137 KdPrint(("Failed to read %s, assuming closed\n", path));
138 new_backend_state = XenbusStateClosed;
139 }
141 if (xppdd->backend_state == new_backend_state)
142 {
143 KdPrint((__DRIVER_NAME " state unchanged\n"));
144 //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
145 return;
146 }
148 xppdd->backend_state = new_backend_state;
150 switch (xppdd->backend_state)
151 {
152 case XenbusStateUnknown:
153 KdPrint((__DRIVER_NAME " Backend State Changed to Unknown\n"));
154 break;
156 case XenbusStateInitialising:
157 KdPrint((__DRIVER_NAME " Backend State Changed to Initialising\n"));
158 break;
160 case XenbusStateInitWait:
161 KdPrint((__DRIVER_NAME " Backend State Changed to InitWait\n"));
162 break;
164 case XenbusStateInitialised:
165 KdPrint((__DRIVER_NAME " Backend State Changed to Initialised\n"));
166 break;
168 case XenbusStateConnected:
169 KdPrint((__DRIVER_NAME " Backend State Changed to Connected\n"));
170 break;
172 case XenbusStateClosing:
173 KdPrint((__DRIVER_NAME " Backend State Changed to Closing\n"));
174 if (xpdd->suspend_state == SUSPEND_STATE_NONE)
175 {
176 if (xppdd->common.device_usage_paging
177 || xppdd->common.device_usage_dump
178 || xppdd->common.device_usage_hibernation)
179 {
180 KdPrint((__DRIVER_NAME " Not closing device because it is in use\n"));
181 /* in use by page file, dump file, or hiber file - can't close */
182 /* we should probably re-check if the device usage changes in the future */
183 }
184 else
185 {
186 if (xppdd->common.current_pnp_state == Started)
187 {
188 KdPrint((__DRIVER_NAME " Sending RequestDeviceEject\n"));
189 xppdd->eject_requested = TRUE;
190 IoRequestDeviceEject(xppdd->common.pdo);
191 }
192 else
193 {
194 KdPrint((__DRIVER_NAME " Not closing device because it is not started\n"));
195 }
196 }
197 }
198 break;
200 case XenbusStateClosed:
201 KdPrint((__DRIVER_NAME " Backend State Changed to Closed\n"));
202 break;
204 default:
205 KdPrint((__DRIVER_NAME " Backend State Changed to Undefined = %d\n", xppdd->backend_state));
206 break;
207 }
209 KeSetEvent(&xppdd->backend_state_event, 1, FALSE);
211 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
213 return;
214 }
216 struct dummy_sring {
217 RING_IDX req_prod, req_event;
218 RING_IDX rsp_prod, rsp_event;
219 uint8_t pad[48];
220 };
222 /*
223 Called at PASSIVE_LEVEL
224 Called during restore
225 */
226 static NTSTATUS
227 XenPci_ChangeFrontendState(PXENPCI_PDO_DEVICE_DATA xppdd, ULONG frontend_state_set, ULONG backend_state_response, ULONG maximum_wait_ms)
228 {
229 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
230 LARGE_INTEGER timeout;
231 ULONG remaining;
232 ULONG thiswait;
233 char path[128];
235 //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
237 /* Tell backend we're going down */
238 //strcpy(path, xppdd->path);
239 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
240 XenBus_Printf(xpdd, XBT_NIL, path, "%d", frontend_state_set);
242 remaining = maximum_wait_ms;
243 /* we can't rely on xppdd->backend_state here - events can occasionally be missed on startup or resume! */
244 while (XenPci_ReadBackendState(xppdd) != backend_state_response)
245 {
246 thiswait = min((LONG)remaining, 1000); // 1 second or remaining time, whichever is less
247 timeout.QuadPart = (LONGLONG)-1 * thiswait * 1000 * 10;
248 if (KeWaitForSingleObject(&xppdd->backend_state_event, Executive, KernelMode, FALSE, &timeout) == STATUS_TIMEOUT)
249 {
250 remaining -= thiswait;
251 if (remaining == 0)
252 {
253 KdPrint((__DRIVER_NAME " Timed out waiting for %d!\n", backend_state_response));
254 return STATUS_UNSUCCESSFUL;
255 }
256 KdPrint((__DRIVER_NAME " Still waiting for %d (currently %d)...\n", backend_state_response, xppdd->backend_state));
257 }
258 }
259 //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
260 return STATUS_SUCCESS;
261 }
263 static VOID
264 DUMP_CURRENT_PNP_STATE(PXENPCI_PDO_DEVICE_DATA xppdd)
265 {
266 switch (xppdd->common.current_pnp_state)
267 {
268 case Unknown:
269 KdPrint((__DRIVER_NAME " pnp_state = Unknown\n"));
270 break;
271 case NotStarted:
272 KdPrint((__DRIVER_NAME " pnp_state = NotStarted\n"));
273 break;
274 case Started:
275 KdPrint((__DRIVER_NAME " pnp_state = Started\n"));
276 break;
277 case StopPending:
278 KdPrint((__DRIVER_NAME " pnp_state = StopPending\n"));
279 break;
280 case Stopped:
281 KdPrint((__DRIVER_NAME " pnp_state = Stopped\n"));
282 break;
283 case RemovePending:
284 KdPrint((__DRIVER_NAME " pnp_state = RemovePending\n"));
285 break;
286 case SurpriseRemovePending:
287 KdPrint((__DRIVER_NAME " pnp_state = SurpriseRemovePending\n"));
288 break;
289 case Removed:
290 KdPrint((__DRIVER_NAME " pnp_state = Removed\n"));
291 break;
292 default:
293 KdPrint((__DRIVER_NAME " pnp_state = ???\n"));
294 break;
295 }
296 }
298 static NTSTATUS
299 XenPci_EvtChn_Bind(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
300 {
301 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
302 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
304 return EvtChn_Bind(xpdd, Port, ServiceRoutine, ServiceContext);
305 }
307 static NTSTATUS
308 XenPci_EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
309 {
310 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
311 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
313 return EvtChn_BindDpc(xpdd, Port, ServiceRoutine, ServiceContext);
314 }
316 static NTSTATUS
317 XenPci_EvtChn_Unbind(PVOID Context, evtchn_port_t Port)
318 {
319 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
320 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
322 return EvtChn_Unbind(xpdd, Port);
323 }
325 static NTSTATUS
326 XenPci_EvtChn_Mask(PVOID Context, evtchn_port_t Port)
327 {
328 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
329 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
331 return EvtChn_Mask(xpdd, Port);
332 }
334 static NTSTATUS
335 XenPci_EvtChn_Unmask(PVOID Context, evtchn_port_t Port)
336 {
337 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
338 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
340 return EvtChn_Unmask(xpdd, Port);
341 }
343 static NTSTATUS
344 XenPci_EvtChn_Notify(PVOID Context, evtchn_port_t Port)
345 {
346 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
347 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
349 return EvtChn_Notify(xpdd, Port);
350 }
352 static grant_ref_t
353 XenPci_GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t frame, int readonly, grant_ref_t ref)
354 {
355 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
356 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
358 return GntTbl_GrantAccess(xpdd, domid, frame, readonly, ref);
359 }
361 static BOOLEAN
362 XenPci_GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref)
363 {
364 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
365 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
367 return GntTbl_EndAccess(xpdd, ref, keepref);
368 }
370 static VOID
371 XenPci_GntTbl_PutRef(PVOID Context, grant_ref_t ref)
372 {
373 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
374 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
376 GntTbl_PutRef(xpdd, ref);
377 }
379 static grant_ref_t
380 XenPci_GntTbl_GetRef(PVOID Context)
381 {
382 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
383 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
385 return GntTbl_GetRef(xpdd);
386 }
388 static NTSTATUS
389 XenPci_XenShutdownDevice(PVOID Context)
390 {
391 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
392 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
393 PUCHAR in_ptr;
394 ULONG i;
395 UCHAR type;
396 PVOID setting;
397 PVOID value;
399 FUNCTION_ENTER();
401 if (xppdd->backend_state == XenbusStateConnected)
402 {
403 XenPci_ChangeFrontendState(xppdd, XenbusStateClosing, XenbusStateClosing, 30000);
404 if (xppdd->backend_state == XenbusStateClosing)
405 XenPci_ChangeFrontendState(xppdd, XenbusStateClosed, XenbusStateClosed, 30000);
406 if (xppdd->backend_state == XenbusStateClosed)
407 XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000);
408 }
409 else
410 {
411 if (xppdd->backend_state == XenbusStateClosing)
412 XenPci_ChangeFrontendState(xppdd, XenbusStateClosed, XenbusStateClosed, 30000);
413 }
415 if (xppdd->assigned_resources_start != NULL)
416 {
417 ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL);
418 in_ptr = xppdd->assigned_resources_start;
419 while((type = GET_XEN_INIT_RSP(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
420 {
421 switch (type)
422 {
423 case XEN_INIT_TYPE_RING: /* frontend ring */
424 FreePages(value);
425 break;
426 case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
427 // don't know how to do this yet...
428 break;
429 case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
430 EvtChn_Unbind(xpdd, PtrToUlong(value));
431 break;
432 case XEN_INIT_TYPE_GRANT_ENTRIES:
433 for (i = 0; i < PtrToUlong(setting); i++)
434 GntTbl_EndAccess(xpdd, ((grant_ref_t *)value)[i], FALSE);
435 break;
436 }
437 }
438 ExFreePoolWithTag(xppdd->assigned_resources_start, XENPCI_POOL_TAG);
439 xppdd->assigned_resources_start = NULL;
440 }
442 FUNCTION_EXIT();
444 return STATUS_SUCCESS;
445 }
447 static NTSTATUS
448 XenPci_XenConfigDevice(PVOID context);
450 static NTSTATUS
451 XenPci_XenConfigDeviceSpecifyBuffers(PVOID context, PUCHAR src, PUCHAR dst)
452 {
453 PXENPCI_PDO_DEVICE_DATA xppdd = context;
454 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
455 NTSTATUS status = STATUS_SUCCESS;
456 ULONG i;
457 char path[128];
458 PCHAR setting, value;
459 PCHAR res;
460 PVOID address;
461 UCHAR type;
462 PUCHAR in_ptr; //, in_start;
463 PUCHAR out_ptr; //, out_start;
464 XENPCI_VECTORS vectors;
465 ULONG event_channel;
466 BOOLEAN run = FALSE;
467 PMDL ring;
468 grant_ref_t gref;
469 BOOLEAN done_xenbus_init = FALSE;
471 FUNCTION_ENTER();
473 in_ptr = src;
474 out_ptr = dst;
476 // always add vectors
477 vectors.magic = XEN_DATA_MAGIC;
478 vectors.length = sizeof(XENPCI_VECTORS);
479 vectors.context = xppdd;
480 vectors.EvtChn_Bind = XenPci_EvtChn_Bind;
481 vectors.EvtChn_BindDpc = XenPci_EvtChn_BindDpc;
482 vectors.EvtChn_Unbind = XenPci_EvtChn_Unbind;
483 vectors.EvtChn_Mask = XenPci_EvtChn_Mask;
484 vectors.EvtChn_Unmask = XenPci_EvtChn_Unmask;
485 vectors.EvtChn_Notify = XenPci_EvtChn_Notify;
486 vectors.GntTbl_GetRef = XenPci_GntTbl_GetRef;
487 vectors.GntTbl_PutRef = XenPci_GntTbl_PutRef;
488 vectors.GntTbl_GrantAccess = XenPci_GntTbl_GrantAccess;
489 vectors.GntTbl_EndAccess = XenPci_GntTbl_EndAccess;
490 vectors.XenPci_XenConfigDevice = XenPci_XenConfigDevice;
491 vectors.XenPci_XenShutdownDevice = XenPci_XenShutdownDevice;
492 ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_VECTORS, NULL, &vectors);
493 ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_STATE_PTR, NULL, &xppdd->device_state);
495 // first pass, possibly before state == Connected
496 while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value)) != XEN_INIT_TYPE_END)
497 {
499 if (!done_xenbus_init)
500 {
501 if (XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
502 {
503 status = STATUS_UNSUCCESSFUL;
504 goto error;
505 }
506 done_xenbus_init = TRUE;
507 }
509 ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, type, setting, value);
511 switch (type)
512 {
513 case XEN_INIT_TYPE_RUN:
514 run = TRUE;
515 case XEN_INIT_TYPE_WRITE_STRING: /* frontend setting = value */
516 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_WRITE_STRING - %s = %s\n", setting, value));
517 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
518 XenBus_Printf(xpdd, XBT_NIL, path, "%s", value);
519 break;
520 case XEN_INIT_TYPE_RING: /* frontend ring */
521 /* we only allocate and do the SHARED_RING_INIT here */
522 if ((ring = AllocatePage()) != 0)
523 {
524 address = MmGetMdlVirtualAddress(ring);
525 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, address));
526 SHARED_RING_INIT((struct dummy_sring *)address);
527 if ((gref = GntTbl_GrantAccess(
528 xpdd, 0, (ULONG)*MmGetMdlPfnArray(ring), FALSE, 0)) != 0)
529 {
530 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
531 XenBus_Printf(xpdd, XBT_NIL, path, "%d", gref);
532 ADD_XEN_INIT_RSP(&out_ptr, type, setting, address);
533 ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, ring);
534 // add the grant entry too so it gets freed automatically
535 __ADD_XEN_INIT_UCHAR(&xppdd->assigned_resources_ptr, XEN_INIT_TYPE_GRANT_ENTRIES);
536 __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, 1);
537 __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, gref);
538 }
539 else
540 {
541 FreePages(ring);
542 status = STATUS_UNSUCCESSFUL;
543 goto error;
544 }
545 }
546 else
547 {
548 status = STATUS_UNSUCCESSFUL;
549 goto error;
550 }
551 break;
552 case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
553 case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
554 if ((event_channel = EvtChn_AllocUnbound(xpdd, 0)) != 0)
555 {
556 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, event_channel));
557 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
558 XenBus_Printf(xpdd, XBT_NIL, path, "%d", event_channel);
559 ADD_XEN_INIT_RSP(&out_ptr, type, setting, UlongToPtr(event_channel));
560 ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, UlongToPtr(event_channel));
561 if (type == XEN_INIT_TYPE_EVENT_CHANNEL_IRQ)
562 EvtChn_BindIrq(xpdd, event_channel, xppdd->irq_vector);
563 }
564 else
565 {
566 status = STATUS_UNSUCCESSFUL;
567 goto error;
568 }
569 break;
570 }
571 }
572 if (!NT_SUCCESS(status))
573 {
574 goto error;
575 }
576 if (run)
577 {
578 if (XenPci_ChangeFrontendState(xppdd, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
579 {
580 status = STATUS_UNSUCCESSFUL;
581 goto error;
582 }
583 }
585 // second pass, possibly after state == Connected
586 in_ptr = src;
587 while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value)) != XEN_INIT_TYPE_END)
588 {
589 switch(type)
590 {
591 case XEN_INIT_TYPE_READ_STRING_BACK:
592 case XEN_INIT_TYPE_READ_STRING_FRONT:
593 if (type == XEN_INIT_TYPE_READ_STRING_FRONT)
594 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
595 else
596 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->backend_path, setting);
597 res = XenBus_Read(xpdd, XBT_NIL, path, &value);
598 if (res)
599 {
600 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = <failed>\n", setting));
601 XenPci_FreeMem(res);
602 ADD_XEN_INIT_RSP(&out_ptr, type, setting, NULL);
603 }
604 else
605 {
606 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
607 ADD_XEN_INIT_RSP(&out_ptr, type, setting, value);
608 XenPci_FreeMem(value);
609 }
610 break;
611 case XEN_INIT_TYPE_VECTORS:
612 // this is always done so ignore the request
613 break;
614 case XEN_INIT_TYPE_GRANT_ENTRIES:
615 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(value)));
616 __ADD_XEN_INIT_UCHAR(&out_ptr, type);
617 __ADD_XEN_INIT_UCHAR(&xppdd->assigned_resources_ptr, type);
618 __ADD_XEN_INIT_ULONG(&out_ptr, PtrToUlong(value));
619 __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, PtrToUlong(value));
620 for (i = 0; i < PtrToUlong(value); i++)
621 {
622 __ADD_XEN_INIT_ULONG(&out_ptr, GntTbl_GetRef(xpdd));
623 __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, GntTbl_GetRef(xpdd));
624 }
625 break;
626 }
627 }
628 ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_END, NULL, NULL);
630 error:
631 FUNCTION_EXIT_STATUS(status);
633 return status;
634 }
636 static NTSTATUS
637 XenPci_XenConfigDevice(PVOID context)
638 {
639 NTSTATUS status;
640 PUCHAR src, dst;
641 PXENPCI_PDO_DEVICE_DATA xppdd = context;
643 src = ExAllocatePoolWithTag(NonPagedPool, xppdd->config_page_length, XENPCI_POOL_TAG);
644 dst = MmMapIoSpace(xppdd->config_page_phys, xppdd->config_page_length, MmNonCached);
645 memcpy(src, dst, xppdd->config_page_length);
647 status = XenPci_XenConfigDeviceSpecifyBuffers(xppdd, src, dst);
649 MmUnmapIoSpace(dst, xppdd->config_page_length);
650 ExFreePoolWithTag(src, XENPCI_POOL_TAG);
652 return status;
653 }
655 static NTSTATUS
656 XenPci_GetBackendAndAddWatch(PDEVICE_OBJECT device_object)
657 {
658 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
659 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
660 char path[128];
661 PCHAR res;
662 PCHAR value;
664 if (strlen(xppdd->backend_path) != 0)
665 {
666 // this must be the restore path - remove the existing watch
667 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
668 KdPrint((__DRIVER_NAME " Removing old watch on %s\n", path));
669 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
670 }
672 /* Get backend path */
673 RtlStringCbPrintfA(path, ARRAY_SIZE(path),
674 "%s/backend", xppdd->path);
675 res = XenBus_Read(xpdd, XBT_NIL, path, &value);
676 if (res)
677 {
678 KdPrint((__DRIVER_NAME " Failed to read backend path\n"));
679 XenPci_FreeMem(res);
680 return STATUS_UNSUCCESSFUL;
681 }
682 RtlStringCbCopyA(xppdd->backend_path, ARRAY_SIZE(xppdd->backend_path), value);
683 XenPci_FreeMem(value);
685 /* Add watch on backend state */
686 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
687 XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
689 return STATUS_SUCCESS;
690 }
692 NTSTATUS
693 XenPci_Pdo_Resume(PDEVICE_OBJECT device_object)
694 {
695 NTSTATUS status;
696 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
697 //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
698 //PUCHAR in_ptr;
699 //UCHAR type;
700 //PVOID setting;
701 //PVOID value;
702 //CHAR path[256];
703 //PVOID address;
704 ULONG old_backend_state;
705 PUCHAR src, dst;
707 FUNCTION_ENTER();
709 old_backend_state = xppdd->backend_state;
710 status = XenPci_GetBackendAndAddWatch(device_object);
711 if (!NT_SUCCESS(status)) {
712 FUNCTION_ERROR_EXIT();
713 return status;
714 }
716 if (xppdd->common.current_pnp_state == Started && old_backend_state == XenbusStateClosed)
717 {
719 if (XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
720 {
721 // this is probably an unrecoverable situation...
722 FUNCTION_ERROR_EXIT();
723 return STATUS_UNSUCCESSFUL;
724 }
725 if (xppdd->assigned_resources_ptr)
726 {
727 // reset things - feed the 'requested resources' back in
728 ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL);
729 src = xppdd->requested_resources_start;
730 xppdd->requested_resources_ptr = xppdd->requested_resources_start = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);;
731 xppdd->assigned_resources_ptr = xppdd->assigned_resources_start;
733 dst = MmMapIoSpace(xppdd->config_page_phys, xppdd->config_page_length, MmNonCached);
735 status = XenPci_XenConfigDeviceSpecifyBuffers(xppdd, src, dst);
737 MmUnmapIoSpace(dst, xppdd->config_page_length);
738 ExFreePoolWithTag(src, XENPCI_POOL_TAG);
739 }
740 if (XenPci_ChangeFrontendState(xppdd, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
741 {
742 // this is definitely an unrecoverable situation...
743 FUNCTION_ERROR_EXIT();
744 return STATUS_UNSUCCESSFUL;
745 }
746 }
748 FUNCTION_EXIT();
750 return STATUS_SUCCESS;
751 }
753 /* called at DISPATCH_LEVEL */
754 NTSTATUS
755 XenPci_Pdo_Suspend(PDEVICE_OBJECT device_object)
756 {
757 NTSTATUS status = STATUS_SUCCESS;
758 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
759 LARGE_INTEGER wait_time;
761 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (%s | %s)\n", xppdd->path, xppdd->device));
763 if (xppdd->backend_state == XenbusStateConnected)
764 {
765 xppdd->device_state.resume_state_ack = RESUME_STATE_RUNNING;
766 KeMemoryBarrier();
767 xppdd->device_state.resume_state = RESUME_STATE_SUSPENDING;
768 KeMemoryBarrier();
769 KdPrint((__DRIVER_NAME " Calling interrupt\n"));
770 sw_interrupt((UCHAR)xppdd->irq_vector);
771 KdPrint((__DRIVER_NAME " Back from interrupt call\n"));
772 while(xppdd->device_state.resume_state_ack != RESUME_STATE_SUSPENDING)
773 {
774 KdPrint((__DRIVER_NAME " Starting delay - resume_state = %d, resume_state_ack = %d\n", xppdd->device_state.resume_state, xppdd->device_state.resume_state_ack));
775 wait_time.QuadPart = 100 * (-1 * 10 * 1000);
776 KeDelayExecutionThread(KernelMode, FALSE, &wait_time);
777 KdPrint((__DRIVER_NAME " Done with delay\n"));
778 }
779 KdPrint((__DRIVER_NAME " resume_state acknowledged\n"));
781 XenPci_ChangeFrontendState(xppdd, XenbusStateClosing, XenbusStateClosing, 30000);
782 XenPci_ChangeFrontendState(xppdd, XenbusStateClosed, XenbusStateClosed, 30000);
783 }
785 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
787 return status;
788 }
790 static NTSTATUS
791 XenPci_Pnp_StartDevice(PDEVICE_OBJECT device_object, PIRP irp)
792 {
793 NTSTATUS status = STATUS_SUCCESS;
794 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
795 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
796 PIO_STACK_LOCATION stack;
797 PCM_PARTIAL_RESOURCE_LIST prl;
798 PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
799 ULONG i;
800 char path[128];
802 FUNCTION_ENTER();
804 DUMP_CURRENT_PNP_STATE(xppdd);
806 stack = IoGetCurrentIrpStackLocation(irp);
808 status = XenPci_GetBackendAndAddWatch(device_object);
809 if (!NT_SUCCESS(status)) {
810 FUNCTION_ERROR_EXIT();
811 return status;
812 }
814 prl = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
815 for (i = 0; i < prl->Count; i++)
816 {
817 prd = & prl->PartialDescriptors[i];
818 switch (prd->Type)
819 {
820 case CmResourceTypeInterrupt:
821 KdPrint((__DRIVER_NAME " CmResourceTypeInterrupt\n"));
822 KdPrint((__DRIVER_NAME " irq_vector = %02x\n", prd->u.Interrupt.Vector));
823 KdPrint((__DRIVER_NAME " irq_level = %d\n", prd->u.Interrupt.Level));
824 xppdd->irq_vector = prd->u.Interrupt.Vector;
825 xppdd->irq_level = (KIRQL)prd->u.Interrupt.Level;
826 break;
827 case CmResourceTypeMemory:
828 KdPrint((__DRIVER_NAME " CmResourceTypeMemory\n"));
829 KdPrint((__DRIVER_NAME " Start = %08x, Length = %d\n", prd->u.Memory.Start.LowPart, prd->u.Memory.Length));
830 xppdd->config_page_phys = prd->u.Memory.Start;
831 xppdd->config_page_length = prd->u.Memory.Length;
832 xppdd->requested_resources_start = xppdd->requested_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
833 xppdd->assigned_resources_start = xppdd->assigned_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
835 status = XenPci_XenConfigDevice(xppdd);
836 if (!NT_SUCCESS(status))
837 {
838 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
839 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
840 FUNCTION_ERROR_EXIT();
841 return status;
842 }
843 }
844 }
845 SET_PNP_STATE(&xppdd->common, Started);
847 FUNCTION_EXIT();
849 return STATUS_SUCCESS;
850 }
852 static NTSTATUS
853 XenPci_Pnp_RemoveDevice(PDEVICE_OBJECT device_object, PIRP irp)
854 {
855 NTSTATUS status = STATUS_SUCCESS;
856 PXENPCI_PDO_DEVICE_DATA xppdd = device_object->DeviceExtension;
857 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
858 char path[128];
860 UNREFERENCED_PARAMETER(irp);
862 FUNCTION_ENTER();
864 DUMP_CURRENT_PNP_STATE(xppdd);
866 if (xppdd->common.current_pnp_state != Removed)
867 {
868 status = XenPci_XenShutdownDevice(xppdd);
869 /* Remove watch on backend state */
870 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
871 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
872 SET_PNP_STATE(&xppdd->common, Removed);
873 IoInvalidateDeviceRelations(xppdd->bus_pdo, BusRelations);
874 }
875 if (xppdd->reported_missing)
876 {
877 IoDeleteDevice(xppdd->common.pdo);
878 }
880 FUNCTION_EXIT_STATUS(status);
882 return status;
883 }
885 static NTSTATUS
886 XenPci_QueryResourceRequirements(PDEVICE_OBJECT device_object, PIRP irp)
887 {
888 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
889 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
890 PIO_RESOURCE_REQUIREMENTS_LIST irrl;
891 PIO_RESOURCE_DESCRIPTOR ird;
892 ULONG length;
893 ULONG available_interrupts[] = {3, 4, 5, 10, 11, 14};
894 int i;
896 UNREFERENCED_PARAMETER(device_object);
898 length = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List) +
899 FIELD_OFFSET(IO_RESOURCE_LIST, Descriptors) +
900 sizeof(IO_RESOURCE_DESCRIPTOR) * ARRAY_SIZE(available_interrupts);
901 irrl = ExAllocatePoolWithTag(NonPagedPool,
902 length,
903 XENPCI_POOL_TAG);
905 irrl->ListSize = length;
906 irrl->InterfaceType = Internal;
907 irrl->BusNumber = 0;
908 irrl->SlotNumber = 0;
909 irrl->AlternativeLists = 1;
910 irrl->List[0].Version = 1;
911 irrl->List[0].Revision = 1;
912 irrl->List[0].Count = 0;
914 for (i = 0; i < ARRAY_SIZE(available_interrupts); i++)
915 {
916 if (i == (int)xpdd->irq_number)
917 continue;
918 ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
919 ird->Option = i?IO_RESOURCE_ALTERNATIVE:0;
920 ird->Type = CmResourceTypeInterrupt;
921 ird->ShareDisposition = CmResourceShareShared;
922 ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
923 ird->u.Interrupt.MinimumVector = available_interrupts[i];
924 ird->u.Interrupt.MaximumVector = available_interrupts[i];
925 }
927 irp->IoStatus.Information = (ULONG_PTR)irrl;
928 return STATUS_SUCCESS;
929 }
931 static NTSTATUS
932 XenPci_Pnp_QueryTargetRelations(PDEVICE_OBJECT device_object, PIRP irp)
933 {
934 PDEVICE_RELATIONS dr;
935 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
937 dr = (PDEVICE_RELATIONS)ExAllocatePoolWithTag (PagedPool, sizeof(DEVICE_RELATIONS), XENPCI_POOL_TAG);
938 dr->Count = 1;
939 dr->Objects[0] = xppdd->common.pdo;
940 ObReferenceObject(xppdd->common.pdo);
941 irp->IoStatus.Information = (ULONG_PTR)dr;
943 return STATUS_SUCCESS;
944 }
946 static NTSTATUS
947 XenPci_Pnp_QueryCapabilities(PDEVICE_OBJECT device_object, PIRP irp)
948 {
949 PIO_STACK_LOCATION stack;
950 PDEVICE_CAPABILITIES dc;
952 UNREFERENCED_PARAMETER(device_object);
954 stack = IoGetCurrentIrpStackLocation(irp);
955 dc = stack->Parameters.DeviceCapabilities.Capabilities;
956 dc->LockSupported = FALSE;
957 dc->EjectSupported = TRUE;
958 dc->Removable = TRUE;
959 dc->DockDevice = FALSE;
960 dc->UniqueID = FALSE;
961 dc->SilentInstall = TRUE; //FALSE;
962 dc->RawDeviceOK = FALSE;
963 dc->SurpriseRemovalOK = TRUE;
964 dc->HardwareDisabled = FALSE;
965 dc->NoDisplayInUI = FALSE;
966 dc->DeviceWake = PowerDeviceUnspecified;
967 dc->D1Latency = 0;
968 dc->D2Latency = 0;
969 dc->D3Latency = 0;
970 /* we are really supposed to get the DeviceState entries from the parent... */
971 dc->DeviceState[PowerSystemWorking] = PowerDeviceD0;
972 dc->DeviceState[PowerSystemSleeping1] = PowerDeviceUnspecified;
973 dc->DeviceState[PowerSystemSleeping2] = PowerDeviceUnspecified;
974 dc->DeviceState[PowerSystemSleeping3] = PowerDeviceUnspecified;
975 dc->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
976 dc->DeviceState[PowerSystemShutdown] = PowerDeviceD3;
977 return STATUS_SUCCESS;
978 }
980 NTSTATUS
981 XenPci_Pnp_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
982 {
983 NTSTATUS status;
984 PIO_STACK_LOCATION stack;
985 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
986 LPWSTR buffer;
987 WCHAR widebuf[256];
988 unsigned int i;
989 PPNP_BUS_INFORMATION pbi;
990 ULONG *usage_type;
992 //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
994 stack = IoGetCurrentIrpStackLocation(irp);
996 switch (stack->MinorFunction)
997 {
998 case IRP_MN_START_DEVICE:
999 KdPrint((__DRIVER_NAME " IRP_MN_START_DEVICE (status = %08x)\n", irp->IoStatus.Status));
1000 status = XenPci_Pnp_StartDevice(device_object, irp);
1001 break;
1003 case IRP_MN_QUERY_STOP_DEVICE:
1004 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
1005 SET_PNP_STATE(&xppdd->common, StopPending);
1006 status = STATUS_SUCCESS;
1007 break;
1009 case IRP_MN_STOP_DEVICE:
1010 KdPrint((__DRIVER_NAME " IRP_MN_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
1011 SET_PNP_STATE(&xppdd->common, Stopped);
1012 status = STATUS_SUCCESS;
1013 break;
1015 case IRP_MN_CANCEL_STOP_DEVICE:
1016 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
1017 REVERT_PNP_STATE(&xppdd->common);
1018 status = STATUS_SUCCESS;
1019 break;
1021 case IRP_MN_QUERY_REMOVE_DEVICE:
1022 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
1023 if (xppdd->eject_requested)
1025 SET_PNP_STATE(&xppdd->common, RemovePending);
1026 status = STATUS_SUCCESS;
1028 else
1030 status = STATUS_UNSUCCESSFUL;
1032 break;
1034 case IRP_MN_REMOVE_DEVICE:
1035 KdPrint((__DRIVER_NAME " IRP_MN_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
1036 status = XenPci_Pnp_RemoveDevice(device_object, irp);
1037 break;
1039 case IRP_MN_CANCEL_REMOVE_DEVICE:
1040 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
1041 REVERT_PNP_STATE(&xppdd->common);
1042 status = STATUS_SUCCESS;
1043 break;
1045 case IRP_MN_SURPRISE_REMOVAL:
1046 KdPrint((__DRIVER_NAME " IRP_MN_SURPRISE_REMOVAL (status = %08x)\n", irp->IoStatus.Status));
1047 SET_PNP_STATE(&xppdd->common, SurpriseRemovePending);
1048 status = STATUS_SUCCESS;
1049 break;
1051 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
1052 KdPrint((__DRIVER_NAME " IRP_MN_DEVICE_USAGE_NOTIFICATION (status = %08x)\n", irp->IoStatus.Status));
1054 usage_type = NULL;
1055 switch (stack->Parameters.UsageNotification.Type)
1057 case DeviceUsageTypePaging:
1058 KdPrint((__DRIVER_NAME " type = DeviceUsageTypePaging\n"));
1059 usage_type = &xppdd->common.device_usage_paging;
1060 break;
1061 case DeviceUsageTypeDumpFile:
1062 KdPrint((__DRIVER_NAME " type = DeviceUsageTypeDumpFile\n"));
1063 usage_type = &xppdd->common.device_usage_dump;
1064 break;
1065 case DeviceUsageTypeHibernation:
1066 KdPrint((__DRIVER_NAME " type = DeviceUsageTypeHibernation\n"));
1067 usage_type = &xppdd->common.device_usage_hibernation;
1068 break;
1069 default:
1070 KdPrint((__DRIVER_NAME " Unknown usage type %x\n",
1071 stack->Parameters.UsageNotification.Type));
1072 break;
1074 KdPrint((__DRIVER_NAME " inpath = %d\n", stack->Parameters.UsageNotification.InPath));
1075 if (usage_type)
1077 if (stack->Parameters.UsageNotification.InPath)
1078 (*usage_type)++;
1079 else
1080 (*usage_type)--;
1082 status = STATUS_SUCCESS;
1083 break;
1085 case IRP_MN_QUERY_ID:
1086 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_ID (status = %08x)\n", irp->IoStatus.Status));
1087 switch (stack->Parameters.QueryId.IdType)
1089 case BusQueryDeviceID: /* REG_SZ */
1090 KdPrint((__DRIVER_NAME " BusQueryDeviceID\n"));
1091 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1092 for (i = 0; i < strlen(xppdd->device); i++)
1093 widebuf[i] = xppdd->device[i];
1094 widebuf[i] = 0;
1095 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
1096 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1097 irp->IoStatus.Information = (ULONG_PTR)buffer;
1098 status = STATUS_SUCCESS;
1099 break;
1100 case BusQueryHardwareIDs: /* REG_MULTI_SZ */
1101 KdPrint((__DRIVER_NAME " BusQueryHardwareIDs\n"));
1102 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1103 for (i = 0; i < strlen(xppdd->device); i++)
1104 widebuf[i] = xppdd->device[i];
1105 widebuf[i] = 0;
1106 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
1107 for (i = 0; buffer[i] != 0; i++);
1108 buffer[i + 1] = 0;
1109 // for (i = 0; i < 256; i++)
1110 // KdPrint((__DRIVER_NAME " %04X: %04X %wc\n", i, buffer[i], buffer[i]));
1111 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1112 irp->IoStatus.Information = (ULONG_PTR)buffer;
1113 status = STATUS_SUCCESS;
1114 break;
1115 case BusQueryCompatibleIDs: /* REG_MULTI_SZ */
1116 KdPrint((__DRIVER_NAME " BusQueryCompatibleIDs\n"));
1117 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1118 for (i = 0; i < strlen(xppdd->device); i++)
1119 widebuf[i] = xppdd->device[i];
1120 widebuf[i] = 0;
1121 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
1122 for (i = 0; buffer[i] != 0; i++);
1123 buffer[i + 1] = 0;
1124 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1125 irp->IoStatus.Information = (ULONG_PTR)buffer;
1126 status = STATUS_SUCCESS;
1127 break;
1128 case BusQueryInstanceID: /* REG_SZ */
1129 KdPrint((__DRIVER_NAME " BusQueryInstanceID\n"));
1130 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1131 RtlStringCbPrintfW(buffer, 512, L"%02d", xppdd->index);
1132 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1133 irp->IoStatus.Information = (ULONG_PTR)buffer;
1134 status = STATUS_SUCCESS;
1135 break;
1136 default:
1137 KdPrint((__DRIVER_NAME " Unhandled IdType = %d\n", stack->Parameters.QueryId.IdType));
1138 irp->IoStatus.Information = 0;
1139 status = STATUS_NOT_SUPPORTED;
1140 break;
1142 break;
1144 case IRP_MN_QUERY_DEVICE_TEXT:
1145 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_TEXT (status = %08x)\n", irp->IoStatus.Status));
1146 switch (stack->Parameters.QueryDeviceText.DeviceTextType)
1148 case DeviceTextDescription:
1149 KdPrint((__DRIVER_NAME " DeviceTextDescription\n"));
1150 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1151 for (i = 0; i < strlen(xppdd->device); i++)
1152 widebuf[i] = xppdd->device[i];
1153 widebuf[i] = 0;
1154 RtlStringCbPrintfW(buffer, 512, L"Xen %ws device #%d", widebuf, xppdd->index);
1155 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1156 irp->IoStatus.Information = (ULONG_PTR)buffer;
1157 status = STATUS_SUCCESS;
1158 break;
1159 case DeviceTextLocationInformation:
1160 KdPrint((__DRIVER_NAME " DeviceTextLocationInformation\n"));
1161 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
1162 RtlStringCbPrintfW(buffer, 512, L"Xen Bus");
1163 KdPrint((__DRIVER_NAME " %ls\n", buffer));
1164 irp->IoStatus.Information = (ULONG_PTR)buffer;
1165 status = STATUS_SUCCESS;
1166 break;
1167 default:
1168 KdPrint((__DRIVER_NAME " Unhandled IdType = %d\n", stack->Parameters.QueryDeviceText.DeviceTextType));
1169 irp->IoStatus.Information = 0;
1170 status = STATUS_NOT_SUPPORTED;
1171 break;
1173 break;
1175 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
1176 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_RESOURCE_REQUIREMENTS (status = %08x)\n", irp->IoStatus.Status));
1177 status = XenPci_QueryResourceRequirements(device_object, irp);
1178 break;
1180 case IRP_MN_QUERY_CAPABILITIES:
1181 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_CAPABILITIES (status = %08x)\n", irp->IoStatus.Status));
1182 status = XenPci_Pnp_QueryCapabilities(device_object, irp);
1183 break;
1185 case IRP_MN_QUERY_BUS_INFORMATION:
1186 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_BUS_INFORMATION (status = %08x)\n", irp->IoStatus.Status));
1187 pbi = (PPNP_BUS_INFORMATION)ExAllocatePoolWithTag(PagedPool, sizeof(PNP_BUS_INFORMATION), XENPCI_POOL_TAG);
1188 pbi->BusTypeGuid = GUID_BUS_TYPE_XEN;
1189 pbi->LegacyBusType = Internal;
1190 pbi->BusNumber = 0;
1191 irp->IoStatus.Information = (ULONG_PTR)pbi;
1192 status = STATUS_SUCCESS;
1193 break;
1195 case IRP_MN_QUERY_RESOURCES:
1196 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_RESOURCES (status = %08x)\n", irp->IoStatus.Status));
1197 status = irp->IoStatus.Status;
1198 #if 0
1199 crl = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, sizeof(CM_RESOURCE_LIST) - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR), XENPCI_POOL_TAG);
1200 crl->Count = 1;
1201 crl->List[0].InterfaceType = Internal;
1202 crl->List[0].BusNumber = 0;
1203 crl->List[0].PartialResourceList.Version = 0;
1204 crl->List[0].PartialResourceList.Revision = 0;
1205 crl->List[0].PartialResourceList.Count = 0;
1206 irp->IoStatus.Information = (ULONG_PTR)crl;
1207 status = STATUS_SUCCESS;
1208 #endif
1209 break;
1211 case IRP_MN_QUERY_PNP_DEVICE_STATE:
1212 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_PNP_DEVICE_STATE (status = %08x)\n", irp->IoStatus.Status));
1213 irp->IoStatus.Information = 0;
1214 status = STATUS_SUCCESS;
1215 break;
1217 case IRP_MN_QUERY_DEVICE_RELATIONS:
1218 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_RELATIONS (status = %08x)\n", irp->IoStatus.Status));
1219 switch (stack->Parameters.QueryDeviceRelations.Type)
1221 case TargetDeviceRelation:
1222 KdPrint((__DRIVER_NAME " BusRelations\n"));
1223 status = XenPci_Pnp_QueryTargetRelations(device_object, irp);
1224 break;
1225 default:
1226 status = irp->IoStatus.Status;
1227 break;
1229 break;
1231 case IRP_MN_EJECT:
1232 KdPrint((__DRIVER_NAME " IRP_MN_EJECT\n"));
1233 status = STATUS_SUCCESS;
1234 break;
1236 default:
1237 //KdPrint((__DRIVER_NAME " Unhandled Minor = %d, Status = %08x\n", stack->MinorFunction, irp->IoStatus.Status));
1238 status = irp->IoStatus.Status;
1239 break;
1242 irp->IoStatus.Status = status;
1243 IoCompleteRequest(irp, IO_NO_INCREMENT);
1245 //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1247 return status;
1250 NTSTATUS
1251 XenPci_Irp_Create_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1253 NTSTATUS status;
1255 UNREFERENCED_PARAMETER(device_object);
1257 FUNCTION_ENTER();
1259 status = irp->IoStatus.Status;
1260 IoCompleteRequest(irp, IO_NO_INCREMENT);
1262 FUNCTION_EXIT();
1264 return status;
1267 NTSTATUS
1268 XenPci_Irp_Close_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1270 NTSTATUS status;
1272 UNREFERENCED_PARAMETER(device_object);
1274 FUNCTION_ENTER();
1276 status = irp->IoStatus.Status;
1277 IoCompleteRequest(irp, IO_NO_INCREMENT);
1279 FUNCTION_EXIT();
1281 return status;
1284 NTSTATUS
1285 XenPci_Irp_Read_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1287 NTSTATUS status;
1289 UNREFERENCED_PARAMETER(device_object);
1291 FUNCTION_ENTER();
1293 status = irp->IoStatus.Status;
1294 IoCompleteRequest(irp, IO_NO_INCREMENT);
1296 FUNCTION_EXIT();
1298 return status;
1301 NTSTATUS
1302 XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1304 NTSTATUS status;
1306 UNREFERENCED_PARAMETER(device_object);
1308 FUNCTION_ENTER();
1310 status = irp->IoStatus.Status;
1311 IoCompleteRequest(irp, IO_NO_INCREMENT);
1313 FUNCTION_EXIT();
1315 return status;