win-pvdrivers

view xenpci/xenpci_pdo.c @ 283:3c65d6c6453f

Fixed a sense problem with xenscsi. scsi passthrough now working properly.
author James Harper <james.harper@bendigoit.com.au>
date Tue May 27 22:46:06 2008 +1000 (2008-05-27)
parents 0401d8062ede
children 4954c15a4921
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
3 Copyright (C) 2007 James Harper
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
20 #include "xenpci.h"
21 #include <stdlib.h>
22 #include <io/ring.h>
24 #pragma warning(disable : 4200) // zero-sized array
25 #pragma warning(disable: 4127) // conditional expression is constant
27 NTSTATUS
28 XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
29 {
30 NTSTATUS status;
31 PIO_STACK_LOCATION stack;
32 POWER_STATE_TYPE power_type;
33 POWER_STATE power_state;
34 //PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
35 //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
37 UNREFERENCED_PARAMETER(device_object);
39 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
41 stack = IoGetCurrentIrpStackLocation(irp);
42 power_type = stack->Parameters.Power.Type;
43 power_state = stack->Parameters.Power.State;
45 switch (stack->MinorFunction)
46 {
47 case IRP_MN_POWER_SEQUENCE:
48 KdPrint((__DRIVER_NAME " IRP_MN_POWER_SEQUENCE\n"));
49 status = STATUS_NOT_SUPPORTED;
50 break;
51 case IRP_MN_QUERY_POWER:
52 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_POWER\n"));
53 status = STATUS_SUCCESS;
54 break;
55 case IRP_MN_SET_POWER:
56 KdPrint((__DRIVER_NAME " IRP_MN_SET_POWER\n"));
57 switch (power_type) {
58 case DevicePowerState:
59 PoSetPowerState(device_object, power_type, power_state);
60 status = STATUS_SUCCESS;
61 break;
62 case SystemPowerState:
63 status = STATUS_SUCCESS;
64 break;
65 default:
66 status = STATUS_NOT_SUPPORTED;
67 break;
68 }
69 break;
70 case IRP_MN_WAIT_WAKE:
71 KdPrint((__DRIVER_NAME " IRP_MN_WAIT_WAKE\n"));
72 status = STATUS_NOT_SUPPORTED;
73 break;
74 default:
75 //KdPrint((__DRIVER_NAME " Unknown IRP_MN_%d\n", stack->MinorFunction));
76 status = STATUS_NOT_SUPPORTED;
77 break;
78 }
79 if (status != STATUS_NOT_SUPPORTED) {
80 irp->IoStatus.Status = status;
81 }
83 PoStartNextPowerIrp(irp);
84 status = irp->IoStatus.Status;
85 IoCompleteRequest(irp, IO_NO_INCREMENT);
87 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
89 return status;
90 }
92 static VOID
93 XenPci_BackEndStateHandler(char *Path, PVOID Context)
94 {
95 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)Context;
96 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
97 char *value;
98 char *err;
99 ULONG new_backend_state;
100 char path[128];
102 // KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
104 /* check that path == device/id/state */
105 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
106 err = XenBus_Read(xpdd, XBT_NIL, Path, &value);
107 if (err)
108 {
109 KdPrint(("Failed to read %s\n", path, err));
110 return;
111 }
112 new_backend_state = atoi(value);
113 XenPci_FreeMem(value);
115 if (xppdd->backend_state == new_backend_state)
116 {
117 KdPrint((__DRIVER_NAME " state unchanged\n"));
118 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
119 return;
120 }
122 xppdd->backend_state = new_backend_state;
124 switch (xppdd->backend_state)
125 {
126 case XenbusStateUnknown:
127 KdPrint((__DRIVER_NAME " Backend State Changed to Unknown\n"));
128 break;
130 case XenbusStateInitialising:
131 KdPrint((__DRIVER_NAME " Backend State Changed to Initialising\n"));
132 break;
134 case XenbusStateInitWait:
135 KdPrint((__DRIVER_NAME " Backend State Changed to InitWait\n"));
136 break;
138 case XenbusStateInitialised:
139 KdPrint((__DRIVER_NAME " Backend State Changed to Initialised\n"));
140 break;
142 case XenbusStateConnected:
143 KdPrint((__DRIVER_NAME " Backend State Changed to Connected\n"));
144 break;
146 case XenbusStateClosing:
147 KdPrint((__DRIVER_NAME " Backend State Changed to Closing\n"));
148 /* check our current PNP statue - this may be a surprise removal... */
149 break;
151 case XenbusStateClosed:
152 KdPrint((__DRIVER_NAME " Backend State Changed to Closed\n"));
153 break;
155 default:
156 KdPrint((__DRIVER_NAME " Backend State Changed to Undefined = %d\n", xppdd->backend_state));
157 break;
158 }
160 KeSetEvent(&xppdd->backend_state_event, 1, FALSE);
162 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
164 return;
165 }
167 struct dummy_sring {
168 RING_IDX req_prod, req_event;
169 RING_IDX rsp_prod, rsp_event;
170 uint8_t pad[48];
171 };
173 static NTSTATUS
174 XenPci_ChangeFrontendState(PXENPCI_PDO_DEVICE_DATA xppdd, ULONG frontend_state_set, ULONG backend_state_response, ULONG maximum_wait_ms)
175 {
176 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
177 LARGE_INTEGER timeout;
178 ULONG remaining;
179 ULONG thiswait;
180 char path[128];
182 /* Tell backend we're going down */
183 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
184 XenBus_Printf(xpdd, XBT_NIL, path, "%d", frontend_state_set);
186 remaining = maximum_wait_ms;
187 while (xppdd->backend_state != backend_state_response)
188 {
189 thiswait = min((LONG)remaining, 1000); // 1 second or remaining time, whichever is less
190 timeout.QuadPart = (LONGLONG)-1 * thiswait * 1000 * 10;
191 if (KeWaitForSingleObject(&xppdd->backend_state_event, Executive, KernelMode, FALSE, &timeout) == STATUS_TIMEOUT)
192 {
193 remaining -= thiswait;
194 if (remaining == 0)
195 {
196 KdPrint((__DRIVER_NAME " Timed out waiting for %d!\n", backend_state_response));
197 return STATUS_UNSUCCESSFUL;
198 }
199 KdPrint((__DRIVER_NAME " Still waiting for %d (currently %d)...\n", backend_state_response, xppdd->backend_state));
200 }
201 }
202 return STATUS_SUCCESS;
203 }
205 static VOID
206 DUMP_CURRENT_PNP_STATE(PXENPCI_PDO_DEVICE_DATA xppdd)
207 {
208 switch (xppdd->common.device_pnp_state)
209 {
210 case Unknown:
211 KdPrint((__DRIVER_NAME " pnp_state = Unknown\n"));
212 break;
213 case NotStarted:
214 KdPrint((__DRIVER_NAME " pnp_state = NotStarted\n"));
215 break;
216 case Started:
217 KdPrint((__DRIVER_NAME " pnp_state = Started\n"));
218 break;
219 case StopPending:
220 KdPrint((__DRIVER_NAME " pnp_state = StopPending\n"));
221 break;
222 case Stopped:
223 KdPrint((__DRIVER_NAME " pnp_state = Stopped\n"));
224 break;
225 case RemovePending:
226 KdPrint((__DRIVER_NAME " pnp_state = RemovePending\n"));
227 break;
228 case SurpriseRemovePending:
229 KdPrint((__DRIVER_NAME " pnp_state = SurpriseRemovePending\n"));
230 break;
231 case Removed:
232 KdPrint((__DRIVER_NAME " pnp_state = Removed\n"));
233 break;
234 default:
235 KdPrint((__DRIVER_NAME " pnp_state = ???\n"));
236 break;
237 }
238 }
240 static NTSTATUS
241 XenPci_EvtChn_Bind(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
242 {
243 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
244 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
246 return EvtChn_Bind(xpdd, Port, ServiceRoutine, ServiceContext);
247 }
249 static NTSTATUS
250 XenPci_EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
251 {
252 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
253 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
255 return EvtChn_BindDpc(xpdd, Port, ServiceRoutine, ServiceContext);
256 }
258 static NTSTATUS
259 XenPci_EvtChn_Unbind(PVOID Context, evtchn_port_t Port)
260 {
261 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
262 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
264 return EvtChn_Unbind(xpdd, Port);
265 }
267 static NTSTATUS
268 XenPci_EvtChn_Mask(PVOID Context, evtchn_port_t Port)
269 {
270 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
271 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
273 return EvtChn_Mask(xpdd, Port);
274 }
276 static NTSTATUS
277 XenPci_EvtChn_Unmask(PVOID Context, evtchn_port_t Port)
278 {
279 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
280 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
282 return EvtChn_Unmask(xpdd, Port);
283 }
285 static NTSTATUS
286 XenPci_EvtChn_Notify(PVOID Context, evtchn_port_t Port)
287 {
288 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
289 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
291 return EvtChn_Notify(xpdd, Port);
292 }
294 static grant_ref_t
295 XenPci_GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t frame, int readonly, grant_ref_t ref)
296 {
297 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
298 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
300 return GntTbl_GrantAccess(xpdd, domid, frame, readonly, ref);
301 }
303 static BOOLEAN
304 XenPci_GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref)
305 {
306 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
307 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
309 return GntTbl_EndAccess(xpdd, ref, keepref);
310 }
312 static VOID
313 XenPci_GntTbl_PutRef(PVOID Context, grant_ref_t ref)
314 {
315 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
316 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
318 GntTbl_PutRef(xpdd, ref);
319 }
321 static grant_ref_t
322 XenPci_GntTbl_GetRef(PVOID Context)
323 {
324 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
325 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
327 return GntTbl_GetRef(xpdd);
328 }
330 static NTSTATUS
331 XenPci_ShutdownDevice(PVOID Context)
332 {
333 PXENPCI_PDO_DEVICE_DATA xppdd = Context;
335 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
337 if (xppdd->backend_state == XenbusStateConnected)
338 XenPci_ChangeFrontendState(xppdd, XenbusStateClosing, XenbusStateClosing, 30000);
339 if (xppdd->backend_state == XenbusStateClosing)
340 XenPci_ChangeFrontendState(xppdd, XenbusStateClosed, XenbusStateClosed, 30000);
341 if (xppdd->backend_state == XenbusStateClosed)
342 XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000);
344 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
346 return STATUS_SUCCESS;
347 }
349 static NTSTATUS
350 XenPci_Pnp_StartDevice(PDEVICE_OBJECT device_object, PIRP irp)
351 {
352 NTSTATUS status = STATUS_SUCCESS;
353 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
354 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
355 PIO_STACK_LOCATION stack;
356 PCM_PARTIAL_RESOURCE_LIST res_list;
357 PCM_PARTIAL_RESOURCE_DESCRIPTOR res_descriptor;
358 ULONG i;
359 char path[128];
360 PCHAR setting, value;
361 PCHAR res;
362 PVOID address;
363 UCHAR type;
364 PUCHAR in_ptr = NULL;
365 PUCHAR out_ptr, out_start = NULL;
366 XENPCI_VECTORS vectors;
367 ULONG rings = 0;
368 ULONG event_channels = 0;
370 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
372 DUMP_CURRENT_PNP_STATE(xppdd);
374 xppdd->xenbus_request = NULL;
376 stack = IoGetCurrentIrpStackLocation(irp);
378 /* Get backend path */
379 RtlStringCbPrintfA(path, ARRAY_SIZE(path),
380 "%s/backend", xppdd->path);
381 res = XenBus_Read(xpdd, XBT_NIL, path, &value);
382 if (res)
383 {
384 KdPrint((__DRIVER_NAME " Failed to read backend path\n"));
385 XenPci_FreeMem(res);
386 return STATUS_UNSUCCESSFUL;
387 }
388 RtlStringCbCopyA(xppdd->backend_path, ARRAY_SIZE(xppdd->backend_path), value);
389 XenPci_FreeMem(value);
391 /* Add watch on backend state */
392 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
393 XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
395 res_list = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
396 for (i = 0; i < res_list->Count; i++)
397 {
398 res_descriptor = &res_list->PartialDescriptors[i];
399 switch (res_descriptor->Type)
400 {
401 case CmResourceTypeInterrupt:
402 KdPrint((__DRIVER_NAME " irq_number = %d\n", res_descriptor->u.Interrupt.Vector));
403 KdPrint((__DRIVER_NAME " irq_level = %03x\n", res_descriptor->u.Interrupt.Level));
404 break;
405 }
406 }
408 res_list = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
409 for (i = 0; i < res_list->Count; i++)
410 {
411 res_descriptor = &res_list->PartialDescriptors[i];
412 switch (res_descriptor->Type) {
413 case CmResourceTypeInterrupt:
414 KdPrint((__DRIVER_NAME " CmResourceTypeInterrupt\n"));
415 KdPrint((__DRIVER_NAME " irq_vector = %03x\n", res_descriptor->u.Interrupt.Vector));
416 KdPrint((__DRIVER_NAME " irq_level = %d\n", res_descriptor->u.Interrupt.Level));
417 xppdd->irq_vector = res_descriptor->u.Interrupt.Vector;
418 xppdd->irq_level = (KIRQL)res_descriptor->u.Interrupt.Level;
419 break;
420 case CmResourceTypeMemory:
421 KdPrint((__DRIVER_NAME " CmResourceTypeMemory\n"));
422 KdPrint((__DRIVER_NAME " Start = %08x, Length = %d\n", res_descriptor->u.Memory.Start.LowPart, res_descriptor->u.Memory.Length));
423 if (XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
424 {
425 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
426 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
427 return STATUS_UNSUCCESSFUL;
428 }
429 out_ptr = out_start = MmMapIoSpace(res_descriptor->u.Memory.Start, res_descriptor->u.Memory.Length, MmNonCached);
430 in_ptr = xppdd->xenbus_request = ExAllocatePoolWithTag(PagedPool, res_descriptor->u.Memory.Length, XENPCI_POOL_TAG);
431 KdPrint((__DRIVER_NAME " out_ptr = %p, in_ptr = %p\n", out_ptr, in_ptr));
432 memcpy(in_ptr, out_ptr, res_descriptor->u.Memory.Length);
434 while((type = GET_XEN_INIT_REQ(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
435 {
436 switch (type)
437 {
438 case XEN_INIT_TYPE_WRITE_STRING: /* frontend setting = value */
439 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_WRITE_STRING - %s = %s\n", setting, value));
440 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
441 XenBus_Printf(xpdd, XBT_NIL, path, "%s", value);
442 break;
443 case XEN_INIT_TYPE_RING: /* frontend ring */
444 /* we only allocate and do the SHARED_RING_INIT here */
445 if ((xppdd->mdls[rings] = AllocatePage()) != 0)
446 {
447 address = MmGetMdlVirtualAddress(xppdd->mdls[rings]);
448 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, address));
449 SHARED_RING_INIT((struct dummy_sring *)address);
450 if ((xppdd->grant_refs[rings] = GntTbl_GrantAccess(
451 xpdd, 0, (ULONG)*MmGetMdlPfnArray(xppdd->mdls[rings]), FALSE, 0)) != 0)
452 {
453 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
454 XenBus_Printf(xpdd, XBT_NIL, path, "%d", xppdd->grant_refs[rings]);
455 ADD_XEN_INIT_RSP(&out_ptr, type, setting, address);
456 }
457 else
458 {
459 status = STATUS_UNSUCCESSFUL;
460 }
461 }
462 else
463 {
464 xppdd->grant_refs[rings] = 0;
465 status = STATUS_UNSUCCESSFUL;
466 }
467 rings++;
468 break;
469 case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
470 case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
471 if ((xppdd->event_channels[event_channels] = EvtChn_AllocUnbound(xpdd, 0)) != 0)
472 {
473 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, xppdd->event_channels[event_channels]));
474 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
475 XenBus_Printf(xpdd, XBT_NIL, path, "%d", xppdd->event_channels[event_channels]);
476 ADD_XEN_INIT_RSP(&out_ptr, type, setting, UlongToPtr(xppdd->event_channels[event_channels]));
477 if (type == XEN_INIT_TYPE_EVENT_CHANNEL_IRQ)
478 EvtChn_BindIrq(xpdd, xppdd->event_channels[event_channels], xppdd->irq_vector);
479 }
480 else
481 {
482 status = STATUS_UNSUCCESSFUL;
483 }
484 event_channels++;
485 break;
486 case XEN_INIT_TYPE_COPY_PTR:
487 ADD_XEN_INIT_RSP(&out_ptr, type, setting, value);
488 break;
489 }
490 }
491 if (!NT_SUCCESS(status))
492 {
493 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
494 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
495 return status;
496 }
497 if (XenPci_ChangeFrontendState(xppdd, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
498 {
499 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
500 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
501 return STATUS_UNSUCCESSFUL;
502 }
503 }
504 }
506 res_list = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
507 for (i = 0; i < res_list->Count; i++)
508 {
509 res_descriptor = &res_list->PartialDescriptors[i];
510 switch (res_descriptor->Type) {
511 case CmResourceTypeMemory:
512 in_ptr = xppdd->xenbus_request;
513 while((type = GET_XEN_INIT_REQ(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
514 {
515 switch(type)
516 {
517 case XEN_INIT_TYPE_READ_STRING_BACK:
518 case XEN_INIT_TYPE_READ_STRING_FRONT:
519 if (type == XEN_INIT_TYPE_READ_STRING_FRONT)
520 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
521 else
522 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->backend_path, setting);
523 res = XenBus_Read(xpdd, XBT_NIL, path, &value);
524 if (res)
525 {
526 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = <failed>\n", setting));
527 XenPci_FreeMem(res);
528 ADD_XEN_INIT_RSP(&out_ptr, type, setting, NULL);
529 }
530 else
531 {
532 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
533 ADD_XEN_INIT_RSP(&out_ptr, type, setting, value);
534 XenPci_FreeMem(value);
535 }
536 break;
537 case XEN_INIT_TYPE_VECTORS:
538 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n"));
539 vectors.magic = XEN_DATA_MAGIC;
540 vectors.length = sizeof(XENPCI_VECTORS);
541 vectors.context = xppdd;
542 vectors.EvtChn_Bind = XenPci_EvtChn_Bind;
543 vectors.EvtChn_BindDpc = XenPci_EvtChn_BindDpc;
544 vectors.EvtChn_Unbind = XenPci_EvtChn_Unbind;
545 vectors.EvtChn_Mask = XenPci_EvtChn_Mask;
546 vectors.EvtChn_Unmask = XenPci_EvtChn_Unmask;
547 vectors.EvtChn_Notify = XenPci_EvtChn_Notify;
548 vectors.GntTbl_GetRef = XenPci_GntTbl_GetRef;
549 vectors.GntTbl_PutRef = XenPci_GntTbl_PutRef;
550 vectors.GntTbl_GrantAccess = XenPci_GntTbl_GrantAccess;
551 vectors.GntTbl_EndAccess = XenPci_GntTbl_EndAccess;
552 vectors.XenPci_ShutdownDevice = XenPci_ShutdownDevice;
553 ADD_XEN_INIT_RSP(&out_ptr, type, NULL, &vectors);
554 break;
555 case XEN_INIT_TYPE_GRANT_ENTRIES:
556 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(setting)));
557 __ADD_XEN_INIT_UCHAR(&out_ptr, type);
558 __ADD_XEN_INIT_ULONG(&out_ptr, PtrToUlong(setting));
559 for (i = 0; i < PtrToUlong(setting); i++)
560 __ADD_XEN_INIT_ULONG(&out_ptr, GntTbl_GetRef(xpdd));
561 break;
562 }
563 }
564 ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_END, NULL, NULL);
565 MmUnmapIoSpace(out_start, res_descriptor->u.Memory.Length);
566 //ExFreePoolWithTag(in_start, XENPCI_POOL_TAG);
567 }
568 }
570 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
572 xpdd->common.device_pnp_state = Started;
574 return STATUS_SUCCESS;
575 }
577 static NTSTATUS
578 XenPci_Pnp_RemoveDevice(PDEVICE_OBJECT device_object, PIRP irp)
579 {
580 NTSTATUS status;
581 PXENPCI_PDO_DEVICE_DATA xppdd = device_object->DeviceExtension;
582 PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
583 char path[128];
584 PCHAR setting, value;
585 UCHAR type;
586 PUCHAR in_ptr = NULL;
587 ULONG rings = 0;
588 ULONG event_channels = 0;
590 UNREFERENCED_PARAMETER(irp);
592 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
594 DUMP_CURRENT_PNP_STATE(xppdd);
596 status = XenPci_ShutdownDevice(xppdd);
598 if (xppdd->xenbus_request != NULL)
599 {
600 in_ptr = xppdd->xenbus_request;
601 while((type = GET_XEN_INIT_REQ(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
602 {
603 switch (type)
604 {
605 case XEN_INIT_TYPE_RING: /* frontend ring */
606 GntTbl_EndAccess(xpdd, xppdd->grant_refs[rings], FALSE);
607 FreePages(xppdd->mdls[rings]);
608 xppdd->mdls[rings] = NULL;
609 rings++;
610 break;
611 case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
612 case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
613 EvtChn_Unbind(xpdd, xppdd->event_channels[event_channels++]);
614 break;
615 }
616 }
617 }
618 /* Remove watch on backend state */
619 RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
620 XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
622 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (status = %08x)\n", status));
624 return status;
625 }
627 static NTSTATUS
628 XenPci_QueryResourceRequirements(PDEVICE_OBJECT device_object, PIRP irp)
629 {
630 //PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
631 //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
632 PIO_RESOURCE_REQUIREMENTS_LIST irrl;
633 PIO_RESOURCE_DESCRIPTOR ird;
634 ULONG length;
636 UNREFERENCED_PARAMETER(device_object);
638 length = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List) +
639 FIELD_OFFSET(IO_RESOURCE_LIST, Descriptors) +
640 sizeof(IO_RESOURCE_DESCRIPTOR) * 3;
641 irrl = ExAllocatePoolWithTag(PagedPool,
642 length,
643 XENPCI_POOL_TAG);
645 irrl->ListSize = length;
646 irrl->InterfaceType = Internal;
647 irrl->BusNumber = 0;
648 irrl->SlotNumber = 0;
649 irrl->AlternativeLists = 1;
650 irrl->List[0].Version = 1;
651 irrl->List[0].Revision = 1;
652 irrl->List[0].Count = 0;
654 ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
655 ird->Option = 0;
656 ird->Type = CmResourceTypeInterrupt;
657 ird->ShareDisposition = CmResourceShareShared; //CmResourceShareDeviceExclusive;
658 ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
659 ird->u.Interrupt.MinimumVector = 1;
660 ird->u.Interrupt.MaximumVector = 6;
662 ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
663 ird->Option = IO_RESOURCE_ALTERNATIVE;
664 ird->Type = CmResourceTypeInterrupt;
665 ird->ShareDisposition = CmResourceShareShared; //CmResourceShareDeviceExclusive;
666 ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
667 ird->u.Interrupt.MinimumVector = 10;
668 ird->u.Interrupt.MaximumVector = 14;
670 irp->IoStatus.Information = (ULONG_PTR)irrl;
671 return STATUS_SUCCESS;
672 }
674 static NTSTATUS
675 XenPci_Pnp_QueryTargetRelations(PDEVICE_OBJECT device_object, PIRP irp)
676 {
677 PDEVICE_RELATIONS dr;
678 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
680 dr = (PDEVICE_RELATIONS)ExAllocatePoolWithTag (PagedPool, sizeof(DEVICE_RELATIONS), XENPCI_POOL_TAG);
681 dr->Count = 1;
682 dr->Objects[0] = xppdd->common.pdo;
683 ObReferenceObject(xppdd->common.pdo);
684 irp->IoStatus.Information = (ULONG_PTR)dr;
686 return STATUS_SUCCESS;
687 }
689 static NTSTATUS
690 XenPci_Pnp_QueryCapabilities(PDEVICE_OBJECT device_object, PIRP irp)
691 {
692 PIO_STACK_LOCATION stack;
693 PDEVICE_CAPABILITIES dc;
695 UNREFERENCED_PARAMETER(device_object);
697 stack = IoGetCurrentIrpStackLocation(irp);
698 dc = stack->Parameters.DeviceCapabilities.Capabilities;
699 dc->LockSupported = FALSE;
700 dc->EjectSupported = FALSE;
701 dc->Removable = FALSE;
702 dc->DockDevice = FALSE;
703 dc->UniqueID = FALSE;
704 dc->SilentInstall = FALSE;
705 dc->RawDeviceOK = FALSE;
706 dc->SurpriseRemovalOK = FALSE;
707 dc->HardwareDisabled = FALSE;
708 dc->NoDisplayInUI = FALSE;
709 dc->DeviceWake = PowerDeviceUnspecified;
710 dc->D1Latency = 0;
711 dc->D2Latency = 0;
712 dc->D3Latency = 0;
713 /* we are really supposed to get the DeviceState entries from the parent... */
714 dc->DeviceState[PowerSystemWorking] = PowerDeviceD0;
715 dc->DeviceState[PowerSystemSleeping1] = PowerDeviceUnspecified;
716 dc->DeviceState[PowerSystemSleeping2] = PowerDeviceUnspecified;
717 dc->DeviceState[PowerSystemSleeping3] = PowerDeviceUnspecified;
718 dc->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
719 dc->DeviceState[PowerSystemShutdown] = PowerDeviceD3;
720 return STATUS_SUCCESS;
721 }
723 NTSTATUS
724 XenPci_Pnp_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
725 {
726 NTSTATUS status;
727 PIO_STACK_LOCATION stack;
728 PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
729 LPWSTR buffer;
730 WCHAR widebuf[256];
731 unsigned int i;
732 PPNP_BUS_INFORMATION pbi;
734 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
736 stack = IoGetCurrentIrpStackLocation(irp);
738 switch (stack->MinorFunction)
739 {
740 case IRP_MN_START_DEVICE:
741 KdPrint((__DRIVER_NAME " IRP_MN_START_DEVICE (status = %08x)\n", irp->IoStatus.Status));
742 status = XenPci_Pnp_StartDevice(device_object, irp);
743 break;
745 case IRP_MN_QUERY_STOP_DEVICE:
746 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
747 xppdd->common.device_pnp_state = StopPending;
748 status = STATUS_SUCCESS;
749 break;
751 case IRP_MN_STOP_DEVICE:
752 KdPrint((__DRIVER_NAME " IRP_MN_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
753 xppdd->common.device_pnp_state = Stopped;
754 status = STATUS_SUCCESS;
755 break;
757 case IRP_MN_CANCEL_STOP_DEVICE:
758 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
759 xppdd->common.device_pnp_state = Started; /* obviously this isn't really correct :) */
760 status = STATUS_SUCCESS;
761 break;
763 case IRP_MN_QUERY_REMOVE_DEVICE:
764 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
765 xppdd->common.device_pnp_state = RemovePending;
766 status = STATUS_SUCCESS;
767 break;
769 case IRP_MN_REMOVE_DEVICE:
770 KdPrint((__DRIVER_NAME " IRP_MN_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
771 status = XenPci_Pnp_RemoveDevice(device_object, irp);
772 break;
774 case IRP_MN_CANCEL_REMOVE_DEVICE:
775 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
776 xppdd->common.device_pnp_state = Started; /* obviously this isn't really correct :) */
777 status = STATUS_SUCCESS;
778 break;
780 case IRP_MN_SURPRISE_REMOVAL:
781 KdPrint((__DRIVER_NAME " IRP_MN_SURPRISE_REMOVAL (status = %08x)\n", irp->IoStatus.Status));
782 xppdd->common.device_pnp_state = SurpriseRemovePending;
783 status = STATUS_SUCCESS;
784 break;
786 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
787 KdPrint((__DRIVER_NAME " IRP_MN_DEVICE_USAGE_NOTIFICATION (status = %08x)\n", irp->IoStatus.Status));
788 switch (stack->Parameters.UsageNotification.Type)
789 {
790 case DeviceUsageTypePaging:
791 KdPrint((__DRIVER_NAME " type = DeviceUsageTypePaging\n"));
792 break;
793 case DeviceUsageTypeDumpFile:
794 KdPrint((__DRIVER_NAME " type = DeviceUsageTypeDumpFile\n"));
795 break;
796 case DeviceUsageTypeHibernation:
797 KdPrint((__DRIVER_NAME " type = DeviceUsageTypeHibernation\n"));
798 break;
799 }
800 KdPrint((__DRIVER_NAME " inpath = %d\n", stack->Parameters.UsageNotification.InPath));
801 status = STATUS_SUCCESS;
802 break;
804 case IRP_MN_QUERY_ID:
805 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_ID (status = %08x)\n", irp->IoStatus.Status));
806 switch (stack->Parameters.QueryId.IdType)
807 {
808 case BusQueryDeviceID: /* REG_SZ */
809 KdPrint((__DRIVER_NAME " BusQueryDeviceID\n"));
810 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
811 for (i = 0; i < strlen(xppdd->device); i++)
812 widebuf[i] = xppdd->device[i];
813 widebuf[i] = 0;
814 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
815 KdPrint((__DRIVER_NAME " %ls\n", buffer));
816 irp->IoStatus.Information = (ULONG_PTR)buffer;
817 status = STATUS_SUCCESS;
818 break;
819 case BusQueryHardwareIDs: /* REG_MULTI_SZ */
820 KdPrint((__DRIVER_NAME " BusQueryHardwareIDs\n"));
821 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
822 for (i = 0; i < strlen(xppdd->device); i++)
823 widebuf[i] = xppdd->device[i];
824 widebuf[i] = 0;
825 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
826 for (i = 0; buffer[i] != 0; i++);
827 buffer[i + 1] = 0;
828 // for (i = 0; i < 256; i++)
829 // KdPrint((__DRIVER_NAME " %04X: %04X %wc\n", i, buffer[i], buffer[i]));
830 KdPrint((__DRIVER_NAME " %ls\n", buffer));
831 irp->IoStatus.Information = (ULONG_PTR)buffer;
832 status = STATUS_SUCCESS;
833 break;
834 case BusQueryCompatibleIDs: /* REG_MULTI_SZ */
835 KdPrint((__DRIVER_NAME " BusQueryCompatibleIDs\n"));
836 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
837 for (i = 0; i < strlen(xppdd->device); i++)
838 widebuf[i] = xppdd->device[i];
839 widebuf[i] = 0;
840 RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
841 for (i = 0; buffer[i] != 0; i++);
842 buffer[i + 1] = 0;
843 KdPrint((__DRIVER_NAME " %ls\n", buffer));
844 irp->IoStatus.Information = (ULONG_PTR)buffer;
845 status = STATUS_SUCCESS;
846 break;
847 case BusQueryInstanceID: /* REG_SZ */
848 KdPrint((__DRIVER_NAME " BusQueryInstanceID\n"));
849 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
850 RtlStringCbPrintfW(buffer, 512, L"%02d", xppdd->index);
851 KdPrint((__DRIVER_NAME " %ls\n", buffer));
852 irp->IoStatus.Information = (ULONG_PTR)buffer;
853 status = STATUS_SUCCESS;
854 break;
855 default:
856 KdPrint((__DRIVER_NAME " Unhandled IdType = %d\n", stack->Parameters.QueryId.IdType));
857 irp->IoStatus.Information = 0;
858 status = STATUS_NOT_SUPPORTED;
859 break;
860 }
861 break;
863 case IRP_MN_QUERY_DEVICE_TEXT:
864 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_TEXT (status = %08x)\n", irp->IoStatus.Status));
865 switch (stack->Parameters.QueryDeviceText.DeviceTextType)
866 {
867 case DeviceTextDescription:
868 KdPrint((__DRIVER_NAME " DeviceTextDescription\n"));
869 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
870 for (i = 0; i < strlen(xppdd->device); i++)
871 widebuf[i] = xppdd->device[i];
872 widebuf[i] = 0;
873 RtlStringCbPrintfW(buffer, 512, L"Xen %ws device #%d", widebuf, xppdd->index);
874 KdPrint((__DRIVER_NAME " %ls\n", buffer));
875 irp->IoStatus.Information = (ULONG_PTR)buffer;
876 status = STATUS_SUCCESS;
877 break;
878 case DeviceTextLocationInformation:
879 KdPrint((__DRIVER_NAME " DeviceTextLocationInformation\n"));
880 buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
881 RtlStringCbPrintfW(buffer, 512, L"Xen Bus");
882 KdPrint((__DRIVER_NAME " %ls\n", buffer));
883 irp->IoStatus.Information = (ULONG_PTR)buffer;
884 status = STATUS_SUCCESS;
885 break;
886 default:
887 KdPrint((__DRIVER_NAME " Unhandled IdType = %d\n", stack->Parameters.QueryDeviceText.DeviceTextType));
888 irp->IoStatus.Information = 0;
889 status = STATUS_NOT_SUPPORTED;
890 break;
891 }
892 break;
894 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
895 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_RESOURCE_REQUIREMENTS (status = %08x)\n", irp->IoStatus.Status));
896 status = XenPci_QueryResourceRequirements(device_object, irp);
897 break;
899 case IRP_MN_QUERY_CAPABILITIES:
900 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_CAPABILITIES (status = %08x)\n", irp->IoStatus.Status));
901 status = XenPci_Pnp_QueryCapabilities(device_object, irp);
902 break;
904 case IRP_MN_QUERY_BUS_INFORMATION:
905 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_BUS_INFORMATION (status = %08x)\n", irp->IoStatus.Status));
906 pbi = (PPNP_BUS_INFORMATION)ExAllocatePoolWithTag(PagedPool, sizeof(PNP_BUS_INFORMATION), XENPCI_POOL_TAG);
907 pbi->BusTypeGuid = GUID_BUS_TYPE_XEN;
908 pbi->LegacyBusType = Internal;
909 pbi->BusNumber = 0;
910 irp->IoStatus.Information = (ULONG_PTR)pbi;
911 status = STATUS_SUCCESS;
912 break;
914 case IRP_MN_QUERY_RESOURCES:
915 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_RESOURCES (status = %08x)\n", irp->IoStatus.Status));
916 status = irp->IoStatus.Status;
917 #if 0
918 crl = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, sizeof(CM_RESOURCE_LIST) - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR), XENPCI_POOL_TAG);
919 crl->Count = 1;
920 crl->List[0].InterfaceType = Internal;
921 crl->List[0].BusNumber = 0;
922 crl->List[0].PartialResourceList.Version = 0;
923 crl->List[0].PartialResourceList.Revision = 0;
924 crl->List[0].PartialResourceList.Count = 0;
925 irp->IoStatus.Information = (ULONG_PTR)crl;
926 status = STATUS_SUCCESS;
927 #endif
928 break;
930 case IRP_MN_QUERY_PNP_DEVICE_STATE:
931 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_PNP_DEVICE_STATE (status = %08x)\n", irp->IoStatus.Status));
932 irp->IoStatus.Information = 0;
933 status = STATUS_SUCCESS;
934 break;
936 case IRP_MN_QUERY_DEVICE_RELATIONS:
937 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_RELATIONS (status = %08x)\n", irp->IoStatus.Status));
938 switch (stack->Parameters.QueryDeviceRelations.Type)
939 {
940 case TargetDeviceRelation:
941 KdPrint((__DRIVER_NAME " BusRelations\n"));
942 status = XenPci_Pnp_QueryTargetRelations(device_object, irp);
943 break;
944 default:
945 status = irp->IoStatus.Status;
946 break;
947 }
948 break;
950 default:
951 KdPrint((__DRIVER_NAME " Unhandled Minor = %d, Status = %08x\n", stack->MinorFunction, irp->IoStatus.Status));
952 status = irp->IoStatus.Status;
953 break;
954 }
956 irp->IoStatus.Status = status;
957 IoCompleteRequest(irp, IO_NO_INCREMENT);
959 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
961 return status;
962 }
964 NTSTATUS
965 XenPci_Irp_Create_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
966 {
967 NTSTATUS status;
969 UNREFERENCED_PARAMETER(device_object);
971 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
973 status = irp->IoStatus.Status;
974 IoCompleteRequest(irp, IO_NO_INCREMENT);
976 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
978 return status;
979 }
981 NTSTATUS
982 XenPci_Irp_Close_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
983 {
984 NTSTATUS status;
986 UNREFERENCED_PARAMETER(device_object);
988 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
990 status = irp->IoStatus.Status;
991 IoCompleteRequest(irp, IO_NO_INCREMENT);
993 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
995 return status;
996 }
998 NTSTATUS
999 XenPci_Irp_Read_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1001 NTSTATUS status;
1003 UNREFERENCED_PARAMETER(device_object);
1005 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
1007 status = irp->IoStatus.Status;
1008 IoCompleteRequest(irp, IO_NO_INCREMENT);
1010 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1012 return status;
1015 NTSTATUS
1016 XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
1018 NTSTATUS status;
1020 UNREFERENCED_PARAMETER(device_object);
1022 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
1024 status = irp->IoStatus.Status;
1025 IoCompleteRequest(irp, IO_NO_INCREMENT);
1027 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
1029 return status;