win-pvdrivers

changeset 259:161a8a26f3db wdm

Enumeration now working, but no useful info passed to child devices yet.
author James Harper <james.harper@bendigoit.com.au>
date Sun May 04 16:40:30 2008 +1000 (2008-05-04)
parents 9b16ad37af17
children 952b8aa9c44c
files common.inc xenpci/sources xenpci/xenpci.c xenpci/xenpci.h xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c
line diff
     1.1 --- a/common.inc	Fri May 02 20:54:46 2008 +1000
     1.2 +++ b/common.inc	Sun May 04 16:40:30 2008 +1000
     1.3 @@ -1,4 +1,4 @@
     1.4 -VERSION=0.8.9.35
     1.5 +VERSION=0.8.9.42
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7  KMDF_VERSION=1
     1.8  !IF $(_NT_TOOLS_VERSION) > 0x700
     2.1 --- a/xenpci/sources	Fri May 02 20:54:46 2008 +1000
     2.2 +++ b/xenpci/sources	Sun May 04 16:40:30 2008 +1000
     2.3 @@ -6,4 +6,4 @@ TARGETTYPE=DRIVER
     2.4  INF_NAME=$(TARGETNAME)
     2.5  MISCFILES=..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf
     2.6  AMD64_SOURCES=hypercall.asm
     2.7 -SOURCES=xenpci.c evtchn.c gnttbl.c xenbus.c
     2.8 \ No newline at end of file
     2.9 +SOURCES=xenpci.c xenpci_fdo.c xenpci_pdo.c evtchn.c gnttbl.c xenbus.c
    2.10 \ No newline at end of file
     3.1 --- a/xenpci/xenpci.c	Fri May 02 20:54:46 2008 +1000
     3.2 +++ b/xenpci/xenpci.c	Sun May 04 16:40:30 2008 +1000
     3.3 @@ -25,202 +25,44 @@ Foundation, Inc., 51 Franklin Street, Fi
     3.4  #define BALLOON_PATH "memory/target"
     3.5  
     3.6  DRIVER_INITIALIZE DriverEntry;
     3.7 -static NTSTATUS
     3.8 -XenPci_AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject);
     3.9 -static NTSTATUS
    3.10 -XenPci_Pnp(PDEVICE_OBJECT device_object, PIRP irp);
    3.11 -
    3.12 -#if 0
    3.13 -static NTSTATUS
    3.14 -XenPCI_PrepareHardware(WDFDEVICE hDevice, WDFCMRESLIST Resources, WDFCMRESLIST ResourcesTranslated);
    3.15 -static NTSTATUS
    3.16 -XenPCI_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated);
    3.17 -static NTSTATUS
    3.18 -XenPCI_D0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
    3.19 -static NTSTATUS
    3.20 -XenPCI_D0EntryPostInterruptsEnabled(WDFDEVICE  Device, WDF_POWER_DEVICE_STATE PreviousState);
    3.21 -static NTSTATUS
    3.22 -XenPCI_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState);
    3.23 -static NTSTATUS
    3.24 -XenPCI_D0ExitPreInterruptsDisabled(WDFDEVICE  Device, WDF_POWER_DEVICE_STATE TargetState);
    3.25 -static VOID
    3.26 -XenPCI_IoDefault(WDFQUEUE Queue, WDFREQUEST Request);
    3.27 -static VOID 
    3.28 -XenPCI_IoRead(WDFQUEUE Queue, WDFREQUEST Request, size_t Length);
    3.29 -static NTSTATUS
    3.30 -XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice);
    3.31 -static NTSTATUS
    3.32 -XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice);
    3.33 -static NTSTATUS
    3.34 -XenPCI_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit);
    3.35 -static NTSTATUS
    3.36 -XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
    3.37 -static NTSTATUS
    3.38 -XenPCI_FilterRemoveResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
    3.39 -static NTSTATUS
    3.40 -XenPCI_FilterAddResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList);
    3.41 -static NTSTATUS
    3.42 -XenPCI_RemoveAddedResources(WDFDEVICE Device, WDFCMRESLIST ResourcesRaw, WDFCMRESLIST ResourcesTranslated);
    3.43 -#endif
    3.44 -
    3.45 -static VOID
    3.46 -XenBus_SysrqHandler(char *Path, PVOID Data);
    3.47 -static VOID
    3.48 -XenBus_ShutdownHandler(char *Path, PVOID Data);
    3.49 -static VOID
    3.50 -XenBus_BalloonHandler(char *Path, PVOID Data);
    3.51 -static VOID
    3.52 -XenPCI_XenBusWatchHandler(char *Path, PVOID Data);
    3.53  
    3.54  #ifdef ALLOC_PRAGMA
    3.55  #pragma alloc_text (INIT, DriverEntry)
    3.56 -#pragma alloc_text (PAGE, XenPci_AddDevice)
    3.57  #endif
    3.58  
    3.59  /* Global (driver-wide) variables */
    3.60  static BOOLEAN AutoEnumerate;
    3.61 -static LIST_ENTRY ShutdownMsgList;
    3.62  
    3.63  #pragma warning(disable : 4200) // zero-sized array
    3.64  
    3.65 -typedef struct {
    3.66 -  LIST_ENTRY ListEntry;
    3.67 -  ULONG Ptr;
    3.68 -//  ULONG Len;
    3.69 -  CHAR Buf[0];
    3.70 -} SHUTDOWN_MSG_ENTRY, *PSHUTDOWN_MSG_ENTRY;
    3.71 -
    3.72 -static KSPIN_LOCK ShutdownMsgLock;
    3.73 -
    3.74 -CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptRaw;
    3.75 -CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptTranslated;
    3.76 -
    3.77  static NTSTATUS
    3.78 -XenPci_Power(PDEVICE_OBJECT device_object, PIRP irp)
    3.79 +XenPci_Pnp(PDEVICE_OBJECT device_object, PIRP irp)
    3.80  {
    3.81    NTSTATUS status;
    3.82 -  PIO_STACK_LOCATION stack;
    3.83 -  PXENPCI_DEVICE_DATA xpdd;
    3.84 -
    3.85 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    3.86 -
    3.87 -  xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
    3.88 -  stack = IoGetCurrentIrpStackLocation(irp);
    3.89 -  IoSkipCurrentIrpStackLocation(irp);
    3.90 -  status = PoCallDriver(xpdd->lower_do, irp);
    3.91 -
    3.92 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    3.93 +  PXENPCI_COMMON common = device_object->DeviceExtension;
    3.94 +  
    3.95 +  if (common->lower_do)
    3.96 +    status = XenPci_Pnp_Fdo(device_object, irp);
    3.97 +  else
    3.98 +    status = XenPci_Pnp_Pdo(device_object, irp);  
    3.99  
   3.100    return status;
   3.101  }
   3.102  
   3.103  static NTSTATUS
   3.104 -XenPci_Dummy(PDEVICE_OBJECT device_object, PIRP irp)
   3.105 +XenPci_Power(PDEVICE_OBJECT device_object, PIRP irp)
   3.106  {
   3.107    NTSTATUS status;
   3.108 -  PIO_STACK_LOCATION stack;
   3.109 -  PXENPCI_DEVICE_DATA xpdd;
   3.110 -
   3.111 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.112 -
   3.113 -  xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   3.114 -  stack = IoGetCurrentIrpStackLocation(irp);
   3.115 -  IoSkipCurrentIrpStackLocation(irp);
   3.116 -  status = IoCallDriver(xpdd->lower_do, irp);
   3.117 -
   3.118 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.119 -
   3.120 -  return status;
   3.121 -}
   3.122 -
   3.123 -NTSTATUS
   3.124 -DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
   3.125 -{
   3.126 -  NTSTATUS status = STATUS_SUCCESS;
   3.127 -
   3.128 -  UNREFERENCED_PARAMETER(RegistryPath);
   3.129 -
   3.130 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.131 -
   3.132 -  InitializeListHead(&ShutdownMsgList);
   3.133 -  KeInitializeSpinLock(&ShutdownMsgLock);
   3.134 -
   3.135 -  DriverObject->DriverExtension->AddDevice = XenPci_AddDevice;
   3.136 -  DriverObject->MajorFunction[IRP_MJ_PNP] = XenPci_Pnp;
   3.137 -  DriverObject->MajorFunction[IRP_MJ_POWER] = XenPci_Power;
   3.138 -  DriverObject->MajorFunction[IRP_MJ_CREATE] = XenPci_Dummy;
   3.139 -  DriverObject->MajorFunction[IRP_MJ_CLOSE] = XenPci_Dummy;
   3.140 -  DriverObject->MajorFunction[IRP_MJ_CLEANUP] = XenPci_Dummy;
   3.141 -  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = XenPci_Dummy;
   3.142 -  DriverObject->MajorFunction[IRP_MJ_READ] = XenPci_Dummy;
   3.143 -  DriverObject->MajorFunction[IRP_MJ_WRITE] = XenPci_Dummy;
   3.144 -  DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = XenPci_Dummy;
   3.145 -
   3.146 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.147 +  PXENPCI_COMMON common = device_object->DeviceExtension;
   3.148 +  
   3.149 +  if (common->lower_do)
   3.150 +    status = XenPci_Power_Fdo(device_object, irp);
   3.151 +  else
   3.152 +    status = XenPci_Power_Pdo(device_object, irp);  
   3.153  
   3.154    return status;
   3.155  }
   3.156  
   3.157 -/*
   3.158 - * Many XEN_IFACE functions allocate memory. Clients must use this to free it.
   3.159 - * (Xenbus_Read, XenBus_List, XenBus_AddWatch, XenBus_RemWatch)
   3.160 - */
   3.161 -static void
   3.162 -XenPCI_FreeMem(PVOID Ptr)
   3.163 -{
   3.164 -  ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
   3.165 -}
   3.166 -
   3.167 -/*
   3.168 - * Alloc MMIO from the device's MMIO region. There is no corresponding free() fn
   3.169 - */
   3.170 -PHYSICAL_ADDRESS
   3.171 -XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len)
   3.172 -{
   3.173 -  PHYSICAL_ADDRESS addr;
   3.174 -
   3.175 -  len = (len + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
   3.176 -
   3.177 -  addr = xpdd->platform_mmio_addr;
   3.178 -  addr.QuadPart += xpdd->platform_mmio_alloc;
   3.179 -  xpdd->platform_mmio_alloc += len;
   3.180 -
   3.181 -  ASSERT(xpdd->platform_mmio_alloc <= xpdd->platform_mmio_len);
   3.182 -
   3.183 -  return addr;
   3.184 -}
   3.185 -
   3.186 -static NTSTATUS
   3.187 -XenPci_Init(PXENPCI_DEVICE_DATA xpdd)
   3.188 -{
   3.189 -  struct xen_add_to_physmap xatp;
   3.190 -  int ret;
   3.191 -  PHYSICAL_ADDRESS shared_info_area_unmapped;
   3.192 -
   3.193 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.194 -
   3.195 -  hvm_get_stubs(xpdd);
   3.196 -
   3.197 -  shared_info_area_unmapped = XenPci_AllocMMIO(xpdd, PAGE_SIZE);
   3.198 -  KdPrint((__DRIVER_NAME " shared_info_area_unmapped.QuadPart = %lx\n", shared_info_area_unmapped.QuadPart));
   3.199 -  xatp.domid = DOMID_SELF;
   3.200 -  xatp.idx = 0;
   3.201 -  xatp.space = XENMAPSPACE_shared_info;
   3.202 -  xatp.gpfn = (xen_pfn_t)(shared_info_area_unmapped.QuadPart >> PAGE_SHIFT);
   3.203 -  KdPrint((__DRIVER_NAME " gpfn = %d\n", xatp.gpfn));
   3.204 -  ret = HYPERVISOR_memory_op(xpdd, XENMEM_add_to_physmap, &xatp);
   3.205 -  KdPrint((__DRIVER_NAME " hypervisor memory op ret = %d\n", ret));
   3.206 -  xpdd->shared_info_area = MmMapIoSpace(shared_info_area_unmapped,
   3.207 -    PAGE_SIZE, MmCached);
   3.208 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.209 -
   3.210 -  return STATUS_SUCCESS;
   3.211 -}
   3.212 -
   3.213 -#if 0
   3.214 -WDFQUEUE ReadQueue;
   3.215 -#endif
   3.216 -
   3.217  static NTSTATUS
   3.218  XenPci_AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject)
   3.219  {
   3.220 @@ -258,16 +100,16 @@ XenPci_AddDevice(PDRIVER_OBJECT DriverOb
   3.221  
   3.222    xpdd = (PXENPCI_DEVICE_DATA)fdo->DeviceExtension;
   3.223  
   3.224 -  // zero out xpdd
   3.225 +  RtlZeroMemory(xpdd, sizeof(XENPCI_DEVICE_DATA));
   3.226  
   3.227 -  xpdd->fdo = fdo;
   3.228 -  xpdd->pdo = PhysicalDeviceObject;
   3.229 -
   3.230 -  xpdd->lower_do = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
   3.231 -  if(xpdd->lower_do == NULL) {
   3.232 +  xpdd->common.fdo = fdo;
   3.233 +  xpdd->common.pdo = PhysicalDeviceObject;
   3.234 +  xpdd->common.lower_do = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
   3.235 +  if(xpdd->common.lower_do == NULL) {
   3.236      IoDeleteDevice(fdo);
   3.237      return STATUS_NO_SUCH_DEVICE;
   3.238    }
   3.239 +  InitializeListHead(&xpdd->child_list);
   3.240  
   3.241    fdo->Flags &= ~DO_DEVICE_INITIALIZING;
   3.242  
   3.243 @@ -385,1097 +227,30 @@ XenPci_AddDevice(PDRIVER_OBJECT DriverOb
   3.244    return status;
   3.245  }
   3.246  
   3.247 -static NTSTATUS
   3.248 -XenPci_Pnp_IoCompletion(PDEVICE_OBJECT device_object, PIRP irp, PVOID context)
   3.249 -{
   3.250 -  PKEVENT event = (PKEVENT)context;
   3.251 -
   3.252 -  UNREFERENCED_PARAMETER(device_object);
   3.253 -
   3.254 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.255 -
   3.256 -  if (irp->PendingReturned)
   3.257 -  {
   3.258 -    KeSetEvent(event, IO_NO_INCREMENT, FALSE);
   3.259 -  }
   3.260 -
   3.261 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   3.262 -
   3.263 -  return STATUS_MORE_PROCESSING_REQUIRED;
   3.264 -}
   3.265 -
   3.266 -static NTSTATUS
   3.267 -XenPci_QueueWorkItem(PDEVICE_OBJECT device_object, PIO_WORKITEM_ROUTINE routine, PVOID context)
   3.268 -{
   3.269 -    PIO_WORKITEM work_item;
   3.270 -    NTSTATUS status = STATUS_SUCCESS;
   3.271 -
   3.272 -	work_item = IoAllocateWorkItem(device_object);
   3.273 -	IoQueueWorkItem(work_item, routine, DelayedWorkQueue, context);
   3.274 -	
   3.275 -    return status;
   3.276 -}
   3.277 -
   3.278 -static NTSTATUS
   3.279 -XenPci_SendAndWaitForIrp(PDEVICE_OBJECT device_object, PIRP irp)
   3.280 -{
   3.281 -  NTSTATUS status;
   3.282 -  PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   3.283 -  KEVENT event;
   3.284 -
   3.285 -  UNREFERENCED_PARAMETER(device_object);
   3.286 -
   3.287 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.288 -
   3.289 -  KeInitializeEvent(&event, NotificationEvent, FALSE);
   3.290 -
   3.291 -  IoCopyCurrentIrpStackLocationToNext(irp);
   3.292 -  IoSetCompletionRoutine(irp, XenPci_Pnp_IoCompletion, &event, TRUE, TRUE, TRUE);
   3.293 -
   3.294 -  status = IoCallDriver(xpdd->lower_do, irp);
   3.295 -
   3.296 -  if (status == STATUS_PENDING)
   3.297 -  {
   3.298 -    KdPrint((__DRIVER_NAME "     waiting ...\n"));
   3.299 -    KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
   3.300 -    KdPrint((__DRIVER_NAME "     ... done\n"));
   3.301 -    status = irp->IoStatus.Status;
   3.302 -  }
   3.303 -
   3.304 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   3.305 -
   3.306 -  return status;
   3.307 -}
   3.308 -
   3.309 -static VOID
   3.310 -XenPci_Pnp_StartDeviceCallback(PDEVICE_OBJECT device_object, PVOID context)
   3.311 -{
   3.312 -  NTSTATUS status = STATUS_SUCCESS;
   3.313 -  PXENPCI_DEVICE_DATA xpdd = device_object->DeviceExtension;
   3.314 -  PIRP irp = context;
   3.315 -
   3.316 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.317 -  
   3.318 -  XenPci_Init(xpdd);
   3.319 -
   3.320 -  GntTbl_Init(xpdd);
   3.321 -
   3.322 -  EvtChn_Init(xpdd);
   3.323 -
   3.324 -  XenBus_Init(xpdd);
   3.325 -
   3.326 -  irp->IoStatus.Status = status;
   3.327 -  
   3.328 -  IoCompleteRequest(irp, IO_NO_INCREMENT);
   3.329 -
   3.330 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   3.331 -}
   3.332 -
   3.333 -static NTSTATUS
   3.334 -XenPci_Pnp_StartDevice(PDEVICE_OBJECT device_object, PIRP irp)
   3.335 -{
   3.336 -  NTSTATUS status;
   3.337 -  PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   3.338 -  PIO_STACK_LOCATION stack;
   3.339 -  PCM_PARTIAL_RESOURCE_LIST res_list;
   3.340 -  PCM_PARTIAL_RESOURCE_DESCRIPTOR res_descriptor;
   3.341 -  ULONG i;
   3.342 -
   3.343 -  UNREFERENCED_PARAMETER(device_object);
   3.344 -
   3.345 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.346 -
   3.347 -  stack = IoGetCurrentIrpStackLocation(irp);
   3.348 -
   3.349 -  IoMarkIrpPending(irp);
   3.350 -
   3.351 -  status = XenPci_SendAndWaitForIrp(device_object, irp);
   3.352 -
   3.353 -  /* I think we want to start a work item here to do this... */
   3.354 -
   3.355 -  res_list = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
   3.356 -  
   3.357 -  for (i = 0; i < res_list->Count; i++)
   3.358 -  {
   3.359 -    res_descriptor = &res_list->PartialDescriptors[i];
   3.360 -    switch (res_descriptor->Type)
   3.361 -    {
   3.362 -    case CmResourceTypeInterrupt:
   3.363 -      xpdd->irq_number = res_descriptor->u.Interrupt.Vector;
   3.364 -      memcpy(&InterruptRaw, res_descriptor, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
   3.365 -      break;
   3.366 -    }
   3.367 -  }
   3.368 -
   3.369 -  res_list = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
   3.370 -  
   3.371 -  for (i = 0; i < res_list->Count; i++)
   3.372 -  {
   3.373 -    res_descriptor = &res_list->PartialDescriptors[i];
   3.374 -    switch (res_descriptor->Type) {
   3.375 -    case CmResourceTypePort:
   3.376 -      break;
   3.377 -    case CmResourceTypeMemory:
   3.378 -      KdPrint((__DRIVER_NAME "     Memory mapped CSR:(%x:%x) Length:(%d)\n", res_descriptor->u.Memory.Start.LowPart, res_descriptor->u.Memory.Start.HighPart, res_descriptor->u.Memory.Length));
   3.379 -      xpdd->platform_mmio_addr = res_descriptor->u.Memory.Start;
   3.380 -      xpdd->platform_mmio_len = res_descriptor->u.Memory.Length;
   3.381 -      xpdd->platform_mmio_alloc = 0;
   3.382 -      break;
   3.383 -    case CmResourceTypeInterrupt:
   3.384 -	  xpdd->irq_level = (KIRQL)res_descriptor->u.Interrupt.Level;
   3.385 -	  xpdd->irq_vector = res_descriptor->u.Interrupt.Vector;
   3.386 -	  xpdd->irq_affinity = res_descriptor->u.Interrupt.Affinity;
   3.387 -      memcpy(&InterruptTranslated, res_descriptor, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
   3.388 -      break;
   3.389 -    case CmResourceTypeDevicePrivate:
   3.390 -      KdPrint((__DRIVER_NAME "     Private Data: 0x%02x 0x%02x 0x%02x\n", res_descriptor->u.DevicePrivate.Data[0], res_descriptor->u.DevicePrivate.Data[1], res_descriptor->u.DevicePrivate.Data[2] ));
   3.391 -      break;
   3.392 -    default:
   3.393 -      KdPrint((__DRIVER_NAME "     Unhandled resource type (0x%x)\n", res_descriptor->Type));
   3.394 -      break;
   3.395 -    }
   3.396 -  }
   3.397 -
   3.398 -  XenPci_QueueWorkItem(device_object, XenPci_Pnp_StartDeviceCallback, irp);
   3.399 -
   3.400 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   3.401 -  
   3.402 -  return STATUS_PENDING;
   3.403 -}
   3.404 -
   3.405 -static NTSTATUS
   3.406 -XenPci_Pnp_StopDevice(PDEVICE_OBJECT device_object, PIRP irp, PVOID context)
   3.407 +NTSTATUS
   3.408 +DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
   3.409  {
   3.410    NTSTATUS status = STATUS_SUCCESS;
   3.411  
   3.412 -  UNREFERENCED_PARAMETER(device_object);
   3.413 -  UNREFERENCED_PARAMETER(context);
   3.414 -
   3.415 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.416 -
   3.417 -  irp->IoStatus.Status = status;
   3.418 -  IoCompleteRequest(irp, IO_NO_INCREMENT);
   3.419 -
   3.420 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   3.421 -
   3.422 -  return irp->IoStatus.Status;
   3.423 -}
   3.424 -
   3.425 -static NTSTATUS
   3.426 -XenPci_Pnp_QueryRemoveDevice(PDEVICE_OBJECT device_object, PIRP irp)
   3.427 -{
   3.428 -  NTSTATUS status;
   3.429 -  PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   3.430 -  int devices = 0;
   3.431 -  PDEVICE_RELATIONS dev_relations;
   3.432 -
   3.433 -  UNREFERENCED_PARAMETER(device_object);
   3.434 -
   3.435 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.436 -
   3.437 -  if (FALSE)
   3.438 -  {
   3.439 -    /* We are in the paging or hibernation path - can't remove */
   3.440 -    status = irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
   3.441 -    IoCompleteRequest(irp, IO_NO_INCREMENT);
   3.442 -  }
   3.443 -  else
   3.444 -  {
   3.445 -    IoSkipCurrentIrpStackLocation(irp);
   3.446 -    status = IoCallDriver(xpdd->lower_do, irp);
   3.447 -  }
   3.448 -
   3.449 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   3.450 -
   3.451 -  return status;
   3.452 -}
   3.453 -
   3.454 -static NTSTATUS
   3.455 -XenPci_Pnp_RemoveDevice(PDEVICE_OBJECT device_object, PIRP irp)
   3.456 -{
   3.457 -  NTSTATUS status;
   3.458 -  PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   3.459 -  int devices = 0;
   3.460 -  PDEVICE_RELATIONS dev_relations;
   3.461 -
   3.462 -  UNREFERENCED_PARAMETER(device_object);
   3.463 +  UNREFERENCED_PARAMETER(RegistryPath);
   3.464  
   3.465    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.466  
   3.467 -  irp->IoStatus.Status = STATUS_SUCCESS;
   3.468 -  IoSkipCurrentIrpStackLocation(irp);
   3.469 -  status = IoCallDriver(xpdd->lower_do, irp);
   3.470 -  IoDetachDevice(xpdd->lower_do);
   3.471 -
   3.472 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   3.473 -
   3.474 -  return status;
   3.475 -}
   3.476 -
   3.477 -static NTSTATUS
   3.478 -XenPci_Pnp_QueryBusRelationsCallback(PDEVICE_OBJECT device_object, PVOID context)
   3.479 -{
   3.480 -  NTSTATUS status = STATUS_SUCCESS;
   3.481 -  PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   3.482 -  PIRP irp = context;
   3.483 -  int devices = 0;
   3.484 -  PDEVICE_RELATIONS dev_relations;
   3.485 -  //char *response;
   3.486 -  char *msgTypes;
   3.487 -  char **Types;
   3.488 -  int i;
   3.489 -
   3.490 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.491 -
   3.492 -  msgTypes = XenBus_List(xpdd, XBT_NIL, "device", &Types);
   3.493 -  if (!msgTypes)
   3.494 -  {
   3.495 -    // set all children to CHILD_STATE_DELETED
   3.496 -    for (i = 0; Types[i]; i++)
   3.497 -    {
   3.498 -	  // read device name
   3.499 -	  // check if already exists or not
   3.500 -	  // create pdo if it doesn't
   3.501 -	  // set it as ADDED
   3.502 -      //RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/%s", Types[i]);
   3.503 -      //XenPCI_XenBusWatchHandler(buffer, Device);
   3.504 -      KdPrint((__DRIVER_NAME "     %s\n", Types[i]));
   3.505 -      ExFreePoolWithTag(Types[i], XENPCI_POOL_TAG);
   3.506 -    }
   3.507 -    devices = 0;
   3.508 -    dev_relations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (devices - 1), XENPCI_POOL_TAG);
   3.509 -    dev_relations->Count = devices;
   3.510 -	status = STATUS_SUCCESS;
   3.511 -  }
   3.512 -  else
   3.513 -  {
   3.514 -    devices = 0;
   3.515 -    dev_relations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (devices - 1), XENPCI_POOL_TAG);
   3.516 -    dev_relations->Count = devices;
   3.517 -  }
   3.518 -
   3.519 -  XenPCI_FreeMem(Types);
   3.520 -
   3.521 -  irp->IoStatus.Status = status;
   3.522 -  irp->IoStatus.Information = (ULONG_PTR)dev_relations;
   3.523 -
   3.524 -  IoCompleteRequest (irp, IO_NO_INCREMENT);
   3.525 -
   3.526 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   3.527 -}
   3.528 -
   3.529 -static NTSTATUS
   3.530 -XenPci_Pnp_QueryBusRelations(PDEVICE_OBJECT device_object, PIRP irp)
   3.531 -{
   3.532 -  NTSTATUS status;
   3.533 -  PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   3.534 -  int devices = 0;
   3.535 -  PDEVICE_RELATIONS dev_relations;
   3.536 -
   3.537 -  UNREFERENCED_PARAMETER(device_object);
   3.538 -
   3.539 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.540 -
   3.541 -  IoMarkIrpPending(irp);
   3.542 -
   3.543 -  status = XenPci_SendAndWaitForIrp(device_object, irp);
   3.544 -
   3.545 -  XenPci_QueueWorkItem(device_object, XenPci_Pnp_QueryBusRelationsCallback, irp);
   3.546 -
   3.547 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   3.548 -
   3.549 -  return STATUS_PENDING;
   3.550 -}
   3.551 -
   3.552 -static NTSTATUS
   3.553 -XenPci_Pnp(PDEVICE_OBJECT device_object, PIRP irp)
   3.554 -{
   3.555 -  PIO_STACK_LOCATION stack;
   3.556 -  NTSTATUS status;
   3.557 -  PXENPCI_DEVICE_DATA xpdd;
   3.558 -
   3.559 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.560 -
   3.561 -  xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   3.562 -
   3.563 -  stack = IoGetCurrentIrpStackLocation(irp);
   3.564 -
   3.565 -  switch (stack->MinorFunction)
   3.566 -  {
   3.567 -  case IRP_MN_START_DEVICE:
   3.568 -    KdPrint((__DRIVER_NAME "     IRP_MN_START_DEVICE\n"));
   3.569 -    return XenPci_Pnp_StartDevice(device_object, irp);
   3.570 -
   3.571 -  case IRP_MN_QUERY_STOP_DEVICE:
   3.572 -    KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_STOP_DEVICE\n"));
   3.573 -    IoSkipCurrentIrpStackLocation(irp);
   3.574 -    irp->IoStatus.Status = STATUS_SUCCESS;
   3.575 -    break;
   3.576 -
   3.577 -  case IRP_MN_STOP_DEVICE:
   3.578 -    KdPrint((__DRIVER_NAME "     IRP_MN_STOP_DEVICE\n"));
   3.579 -    IoCopyCurrentIrpStackLocationToNext(irp);
   3.580 -    IoSetCompletionRoutine(irp, XenPci_Pnp_StopDevice, NULL, TRUE, TRUE, TRUE);
   3.581 -    break;
   3.582 +  //InitializeListHead(&ShutdownMsgList);
   3.583 +  //KeInitializeSpinLock(&ShutdownMsgLock);
   3.584  
   3.585 -  case IRP_MN_CANCEL_STOP_DEVICE:
   3.586 -    KdPrint((__DRIVER_NAME "     IRP_MN_CANCEL_STOP_DEVICE\n"));
   3.587 -    IoSkipCurrentIrpStackLocation(irp);
   3.588 -    irp->IoStatus.Status = STATUS_SUCCESS;
   3.589 -    break;
   3.590 -
   3.591 -  case IRP_MN_QUERY_REMOVE_DEVICE:
   3.592 -    KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_REMOVE_DEVICE\n"));
   3.593 -    return XenPci_Pnp_QueryRemoveDevice(device_object, irp);
   3.594 -
   3.595 -  case IRP_MN_REMOVE_DEVICE:
   3.596 -    KdPrint((__DRIVER_NAME "     IRP_MN_REMOVE_DEVICE\n"));
   3.597 -    return XenPci_Pnp_QueryRemoveDevice(device_object, irp);
   3.598 -    break;
   3.599 -
   3.600 -  case IRP_MN_CANCEL_REMOVE_DEVICE:
   3.601 -    KdPrint((__DRIVER_NAME "     IRP_MN_CANCEL_REMOVE_DEVICE\n"));
   3.602 -    IoSkipCurrentIrpStackLocation(irp);
   3.603 -    irp->IoStatus.Status = STATUS_SUCCESS;
   3.604 -    break;
   3.605 -
   3.606 -  case IRP_MN_SURPRISE_REMOVAL:
   3.607 -    KdPrint((__DRIVER_NAME "     IRP_MN_SURPRISE_REMOVAL\n"));
   3.608 -    IoSkipCurrentIrpStackLocation(irp);
   3.609 -    irp->IoStatus.Status = STATUS_SUCCESS;
   3.610 -    break;
   3.611 -
   3.612 -  case IRP_MN_DEVICE_USAGE_NOTIFICATION:
   3.613 -    KdPrint((__DRIVER_NAME "     IRP_MN_DEVICE_USAGE_NOTIFICATION\n"));
   3.614 -    IoSkipCurrentIrpStackLocation(irp);
   3.615 -    irp->IoStatus.Status = STATUS_SUCCESS;
   3.616 -    break;
   3.617 -
   3.618 -  case IRP_MN_QUERY_DEVICE_RELATIONS:
   3.619 -    KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_DEVICE_RELATIONS\n"));
   3.620 -    switch (stack->Parameters.QueryDeviceRelations.Type)
   3.621 -    {
   3.622 -    case BusRelations:
   3.623 -      KdPrint((__DRIVER_NAME "     BusRelations\n"));
   3.624 -      return XenPci_Pnp_QueryBusRelations(device_object, irp);
   3.625 -      break;  
   3.626 -    default:
   3.627 -      IoSkipCurrentIrpStackLocation(irp);
   3.628 -      break;  
   3.629 -    }
   3.630 -    break;
   3.631 -
   3.632 -  default:
   3.633 -    KdPrint((__DRIVER_NAME "     Unhandled Minor = %d\n", stack->MinorFunction));
   3.634 -    IoSkipCurrentIrpStackLocation(irp);
   3.635 -    break;
   3.636 -  }
   3.637 -
   3.638 -  status = IoCallDriver(xpdd->lower_do, irp);
   3.639 -
   3.640 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   3.641 -
   3.642 -  return status;
   3.643 -}
   3.644 -
   3.645 -#if 0
   3.646 -
   3.647 -static NTSTATUS
   3.648 -XenPCI_D0Entry(
   3.649 -    IN WDFDEVICE  Device,
   3.650 -    IN WDF_POWER_DEVICE_STATE PreviousState
   3.651 -    )
   3.652 -{
   3.653 -  NTSTATUS status = STATUS_SUCCESS;
   3.654 -
   3.655 -  UNREFERENCED_PARAMETER(Device);
   3.656 -  UNREFERENCED_PARAMETER(PreviousState);
   3.657 -
   3.658 -  KdPrint((__DRIVER_NAME " --> EvtDeviceD0Entry\n"));
   3.659 -
   3.660 -  KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Entry\n"));
   3.661 -
   3.662 -  return status;
   3.663 -}
   3.664 -
   3.665 -static NTSTATUS
   3.666 -XenPCI_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState)
   3.667 -{
   3.668 -  NTSTATUS status = STATUS_SUCCESS;
   3.669 -  //OBJECT_ATTRIBUTES oa;
   3.670 -  char *response;
   3.671 -  char *msgTypes;
   3.672 -  char **Types;
   3.673 -  int i;
   3.674 -  char buffer[128];
   3.675 -  WDFCHILDLIST ChildList;
   3.676 -
   3.677 -  UNREFERENCED_PARAMETER(PreviousState);
   3.678 -
   3.679 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.680 -
   3.681 -  XenBus_Start(Device);
   3.682 -
   3.683 -  response = XenBus_AddWatch(Device, XBT_NIL, SYSRQ_PATH, XenBus_SysrqHandler, Device);
   3.684 -  KdPrint((__DRIVER_NAME "     sysrqwatch response = '%s'\n", response)); 
   3.685 -  
   3.686 -  response = XenBus_AddWatch(Device, XBT_NIL, SHUTDOWN_PATH, XenBus_ShutdownHandler, Device);
   3.687 -  KdPrint((__DRIVER_NAME "     shutdown watch response = '%s'\n", response)); 
   3.688 -
   3.689 -  response = XenBus_AddWatch(Device, XBT_NIL, BALLOON_PATH, XenBus_BalloonHandler, Device);
   3.690 -  KdPrint((__DRIVER_NAME "     shutdown watch response = '%s'\n", response)); 
   3.691 -
   3.692 -  response = XenBus_AddWatch(Device, XBT_NIL, "device", XenPCI_XenBusWatchHandler, Device);
   3.693 -  KdPrint((__DRIVER_NAME "     device watch response = '%s'\n", response)); 
   3.694 -
   3.695 -  ChildList = WdfFdoGetDefaultChildList(Device);
   3.696 -
   3.697 -  WdfChildListBeginScan(ChildList);
   3.698 -  msgTypes = XenBus_List(Device, XBT_NIL, "device", &Types);
   3.699 -  if (!msgTypes) {
   3.700 -    for (i = 0; Types[i]; i++)
   3.701 -    {
   3.702 -      RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/%s", Types[i]);
   3.703 -      XenPCI_XenBusWatchHandler(buffer, Device);
   3.704 -      ExFreePoolWithTag(Types[i], XENPCI_POOL_TAG);
   3.705 -    }
   3.706 -  }
   3.707 -  WdfChildListEndScan(ChildList);
   3.708 -
   3.709 -  XenPCI_FreeMem(Types);
   3.710 +  DriverObject->DriverExtension->AddDevice = XenPci_AddDevice;
   3.711 +  DriverObject->MajorFunction[IRP_MJ_PNP] = XenPci_Pnp;
   3.712 +  DriverObject->MajorFunction[IRP_MJ_POWER] = XenPci_Power;
   3.713 +  DriverObject->MajorFunction[IRP_MJ_CREATE] = NULL; //XenPci_Dummy;
   3.714 +  DriverObject->MajorFunction[IRP_MJ_CLOSE] = NULL; //XenPci_Dummy;
   3.715 +  DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NULL; //XenPci_Dummy;
   3.716 +  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NULL; //XenPci_Dummy;
   3.717 +  DriverObject->MajorFunction[IRP_MJ_READ] = NULL; //XenPci_Dummy;
   3.718 +  DriverObject->MajorFunction[IRP_MJ_WRITE] = NULL; //XenPci_Dummy;
   3.719 +  DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = NULL; //XenPci_Dummy;
   3.720  
   3.721    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.722  
   3.723    return status;
   3.724 -}
   3.725 -
   3.726 -static NTSTATUS
   3.727 -XenPCI_D0ExitPreInterruptsDisabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
   3.728 -{
   3.729 -  NTSTATUS status = STATUS_SUCCESS;
   3.730 -
   3.731 -  UNREFERENCED_PARAMETER(TargetState);
   3.732 -
   3.733 -  KdPrint((__DRIVER_NAME " --> D0ExitPreInterruptsDisabled\n"));
   3.734 -
   3.735 -  XenBus_Stop(Device);
   3.736 -
   3.737 -  KdPrint((__DRIVER_NAME " <-- D0ExitPreInterruptsDisabled\n"));
   3.738 -
   3.739 -  return status;
   3.740 -}
   3.741 -
   3.742 -static NTSTATUS
   3.743 -XenPCI_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
   3.744 -{
   3.745 -  NTSTATUS status = STATUS_SUCCESS;
   3.746 -
   3.747 -  UNREFERENCED_PARAMETER(Device);
   3.748 -  UNREFERENCED_PARAMETER(TargetState);
   3.749 -
   3.750 -  KdPrint((__DRIVER_NAME " --> DeviceD0Exit\n"));
   3.751 -
   3.752 -  XenBus_Close(Device);
   3.753 -
   3.754 -  KdPrint((__DRIVER_NAME " <-- DeviceD0Exit\n"));
   3.755 -
   3.756 -  return status;
   3.757 -}
   3.758 -
   3.759 -static VOID 
   3.760 -XenPCI_IoDefault(
   3.761 -    IN WDFQUEUE  Queue,
   3.762 -    IN WDFREQUEST  Request
   3.763 -    )
   3.764 -{
   3.765 -  UNREFERENCED_PARAMETER(Queue);
   3.766 -
   3.767 -  KdPrint((__DRIVER_NAME " --> EvtDeviceIoDefault\n"));
   3.768 -
   3.769 -  WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
   3.770 -
   3.771 -  KdPrint((__DRIVER_NAME " <-- EvtDeviceIoDefault\n"));
   3.772 -}
   3.773 -
   3.774 -static VOID 
   3.775 -XenPCI_IoRead(WDFQUEUE Queue, WDFREQUEST Request, size_t Length)
   3.776 -{
   3.777 -  PSHUTDOWN_MSG_ENTRY Entry;
   3.778 -  size_t Remaining;
   3.779 -  size_t CopyLen;
   3.780 -  PCHAR Buffer;
   3.781 -  size_t BufLen;
   3.782 -  KIRQL OldIrql;
   3.783 -
   3.784 -  UNREFERENCED_PARAMETER(Queue);
   3.785 -  UNREFERENCED_PARAMETER(Length);
   3.786 -
   3.787 -  KdPrint((__DRIVER_NAME " --> IoRead\n"));
   3.788 -
   3.789 -  WdfRequestRetrieveOutputBuffer(Request, 1, &Buffer, &BufLen);
   3.790 -
   3.791 -  KeAcquireSpinLock(&ShutdownMsgLock, &OldIrql);
   3.792 -
   3.793 -  Entry = (PSHUTDOWN_MSG_ENTRY)RemoveHeadList(&ShutdownMsgList);
   3.794 -
   3.795 -  if ((PLIST_ENTRY)Entry == &ShutdownMsgList)
   3.796 -  {
   3.797 -    KdPrint((__DRIVER_NAME " <-- IoRead (Nothing in queue... xenpci is now broken)\n"));
   3.798 -    return;
   3.799 -  }
   3.800 -
   3.801 -  Remaining = strlen(Entry->Buf + Entry->Ptr);
   3.802 -  CopyLen = min(Remaining, BufLen);
   3.803 -
   3.804 -  memcpy(Buffer, Entry->Buf + Entry->Ptr, CopyLen);
   3.805 -
   3.806 -  if (Entry->Buf[Entry->Ptr] == 0)
   3.807 -  {
   3.808 -    KdPrint((__DRIVER_NAME "     All done... stopping queue\n"));
   3.809 -    if (IsListEmpty(&ShutdownMsgList))
   3.810 -      WdfIoQueueStop(ReadQueue, NULL, NULL);
   3.811 -  }
   3.812 -  else
   3.813 -  {    
   3.814 -    KdPrint((__DRIVER_NAME "     More to do...\n"));
   3.815 -    Entry->Ptr += (ULONG)CopyLen;
   3.816 -    InsertHeadList(&ShutdownMsgList, &Entry->ListEntry);
   3.817 -  }
   3.818 -
   3.819 -  KeReleaseSpinLock(&ShutdownMsgLock, OldIrql);
   3.820 -
   3.821 -  WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, CopyLen);
   3.822 -
   3.823 -  KdPrint((__DRIVER_NAME " <-- IoRead\n"));
   3.824 -}
   3.825 -
   3.826 -
   3.827 -static NTSTATUS
   3.828 -XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
   3.829 -{
   3.830 -  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(AssociatedDevice);
   3.831 -
   3.832 -  UNREFERENCED_PARAMETER(Interrupt);
   3.833 -
   3.834 -  KdPrint((__DRIVER_NAME " --> EvtInterruptEnable\n"));
   3.835 -
   3.836 -  xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_mask = 0;
   3.837 -
   3.838 -  KdPrint((__DRIVER_NAME " <-- EvtInterruptEnable\n"));
   3.839 -
   3.840 -  return STATUS_SUCCESS;
   3.841 -}
   3.842 -
   3.843 -static NTSTATUS
   3.844 -XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
   3.845 -{
   3.846 -  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(AssociatedDevice);
   3.847 -
   3.848 -  UNREFERENCED_PARAMETER(Interrupt);
   3.849 -
   3.850 -  //KdPrint((__DRIVER_NAME " --> EvtInterruptDisable\n"));
   3.851 -
   3.852 -  xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_mask = 1;
   3.853 -  // should we kick off any pending interrupts here?
   3.854 -
   3.855 -  //KdPrint((__DRIVER_NAME " <-- EvtInterruptDisable\n"));
   3.856 -
   3.857 -  return STATUS_SUCCESS;
   3.858 -}
   3.859 -
   3.860 -static NTSTATUS
   3.861 -XenPCI_ChildListCreateDevice(
   3.862 -  WDFCHILDLIST ChildList,
   3.863 -  PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription,
   3.864 -  PWDFDEVICE_INIT ChildInit)
   3.865 -{
   3.866 -  NTSTATUS status;
   3.867 -  WDFDEVICE ChildDevice = NULL;
   3.868 -  PXENPCI_IDENTIFICATION_DESCRIPTION XenIdentificationDesc;
   3.869 -  DECLARE_UNICODE_STRING_SIZE(buffer, 20);
   3.870 -  WDF_OBJECT_ATTRIBUTES PdoAttributes;
   3.871 -  DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
   3.872 -  WDF_QUERY_INTERFACE_CONFIG  qiConfig;
   3.873 -  PXENPCI_XEN_DEVICE_DATA ChildDeviceData = NULL;
   3.874 -  UNICODE_STRING DeviceType;
   3.875 -  ANSI_STRING AnsiBuf;
   3.876 -
   3.877 -  UNREFERENCED_PARAMETER(ChildList);
   3.878 -
   3.879 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.880 -
   3.881 -  XenIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENPCI_IDENTIFICATION_DESCRIPTION, Header);
   3.882 -
   3.883 -  RtlInitAnsiString(&AnsiBuf, XenIdentificationDesc->DeviceType);
   3.884 -  RtlAnsiStringToUnicodeString(&DeviceType, &AnsiBuf, TRUE);
   3.885 -
   3.886 -  KdPrint((__DRIVER_NAME "     Type = %s\n", XenIdentificationDesc->DeviceType));
   3.887 -
   3.888 -  //DeviceInit = WdfPdoInitAllocate(Device);
   3.889 -  WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_CONTROLLER);
   3.890 -
   3.891 -  status = RtlUnicodeStringPrintf(&buffer, L"Xen\\%wZ\0", &DeviceType);
   3.892 -  status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
   3.893 -  status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
   3.894 -  status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
   3.895 -
   3.896 -  status = RtlUnicodeStringPrintf(&buffer, L"%02d", 0);
   3.897 -  status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
   3.898 -
   3.899 -  status = RtlUnicodeStringPrintf(&buffer, L"%wZ", &DeviceType);
   3.900 -  status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
   3.901 -
   3.902 -  WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
   3.903 -  
   3.904 -  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&PdoAttributes, XENPCI_XEN_DEVICE_DATA);
   3.905 -
   3.906 -//  WDF_PDO_EVENT_CALLBACKS_INIT(&PdoCallbacks);
   3.907 -//  PdoCallbacks.EvtDeviceResourceRequirementsQuery = XenPCI_DeviceResourceRequirementsQuery;
   3.908 -//  WdfPdoInitSetEventCallbacks(ChildInit, &PdoCallbacks);
   3.909 -
   3.910 -  status = WdfDeviceCreate(&ChildInit, &PdoAttributes, &ChildDevice);
   3.911 -  if (!NT_SUCCESS(status))
   3.912 -  {
   3.913 -    KdPrint((__DRIVER_NAME "     WdfDeviceCreate status = %08X\n", status));
   3.914 -  }
   3.915 -
   3.916 -  WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFilePaging, TRUE);
   3.917 -  WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileHibernation, TRUE);
   3.918 -  WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileDump, TRUE);
   3.919 -
   3.920 -  ChildDeviceData = GetXenDeviceData(ChildDevice);
   3.921 -  ChildDeviceData->Magic = XEN_DATA_MAGIC;
   3.922 -  ChildDeviceData->AutoEnumerate = AutoEnumerate;
   3.923 -  ChildDeviceData->WatchHandler = NULL;
   3.924 -  strncpy(ChildDeviceData->Path, XenIdentificationDesc->Path, 128);
   3.925 -  ChildDeviceData->DeviceIndex = XenIdentificationDesc->DeviceIndex;
   3.926 -  memcpy(&ChildDeviceData->InterruptRaw, &InterruptRaw, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
   3.927 -  memcpy(&ChildDeviceData->InterruptTranslated, &InterruptTranslated, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
   3.928 -  
   3.929 -  ChildDeviceData->XenInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->XenInterface);
   3.930 -  ChildDeviceData->XenInterface.InterfaceHeader.Version = 2;
   3.931 -  ChildDeviceData->XenInterface.InterfaceHeader.Context = WdfPdoGetParent(ChildDevice);
   3.932 -  ChildDeviceData->XenInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
   3.933 -  ChildDeviceData->XenInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
   3.934 -
   3.935 -  ChildDeviceData->XenInterface.AllocMMIO = XenPci_AllocMMIO;
   3.936 -  ChildDeviceData->XenInterface.FreeMem = XenPCI_FreeMem;
   3.937 -
   3.938 -  ChildDeviceData->XenInterface.EvtChn_Bind = EvtChn_Bind;
   3.939 -  ChildDeviceData->XenInterface.EvtChn_Unbind = EvtChn_Unbind;
   3.940 -  ChildDeviceData->XenInterface.EvtChn_Mask = EvtChn_Mask;
   3.941 -  ChildDeviceData->XenInterface.EvtChn_Unmask = EvtChn_Unmask;
   3.942 -  ChildDeviceData->XenInterface.EvtChn_Notify = EvtChn_Notify;
   3.943 -  ChildDeviceData->XenInterface.EvtChn_AllocUnbound = EvtChn_AllocUnbound;
   3.944 -  ChildDeviceData->XenInterface.EvtChn_BindDpc = EvtChn_BindDpc;
   3.945 -
   3.946 -  ChildDeviceData->XenInterface.GntTbl_GetRef = GntTbl_GetRef;
   3.947 -  ChildDeviceData->XenInterface.GntTbl_PutRef = GntTbl_PutRef;
   3.948 -  ChildDeviceData->XenInterface.GntTbl_GrantAccess = GntTbl_GrantAccess;
   3.949 -  ChildDeviceData->XenInterface.GntTbl_EndAccess = GntTbl_EndAccess;
   3.950 -
   3.951 -  ChildDeviceData->XenInterface.XenBus_Read = XenBus_Read;
   3.952 -  ChildDeviceData->XenInterface.XenBus_Write = XenBus_Write;
   3.953 -  ChildDeviceData->XenInterface.XenBus_Printf = XenBus_Printf;
   3.954 -  ChildDeviceData->XenInterface.XenBus_StartTransaction = XenBus_StartTransaction;
   3.955 -  ChildDeviceData->XenInterface.XenBus_EndTransaction = XenBus_EndTransaction;
   3.956 -  ChildDeviceData->XenInterface.XenBus_List = XenBus_List;
   3.957 -  ChildDeviceData->XenInterface.XenBus_AddWatch = XenBus_AddWatch;
   3.958 -  ChildDeviceData->XenInterface.XenBus_RemWatch = XenBus_RemWatch;
   3.959 -
   3.960 -  WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->XenInterface, &GUID_XEN_IFACE, NULL);
   3.961 -  status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
   3.962 -  if (!NT_SUCCESS(status)) {
   3.963 -    return status;
   3.964 -  }
   3.965 -
   3.966 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.967 -
   3.968 -  return status;
   3.969 -}
   3.970 -
   3.971 -VOID
   3.972 -XenPCI_XenBusWatchHandler(char *Path, PVOID Data)
   3.973 -{
   3.974 -  NTSTATUS status;
   3.975 -  char **Bits;
   3.976 -  int Count;
   3.977 -  WDFDEVICE Device = Data;
   3.978 -  WDFCHILDLIST ChildList;
   3.979 -  WDF_CHILD_LIST_ITERATOR ChildIterator;
   3.980 -  WDFDEVICE ChildDevice;
   3.981 -  PXENPCI_XEN_DEVICE_DATA ChildDeviceData;
   3.982 -  XENPCI_IDENTIFICATION_DESCRIPTION description;
   3.983 -#if (NTDDI_VERSION >= NTDDI_WS03SP1)
   3.984 -  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
   3.985 -#endif
   3.986 -
   3.987 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.988 -
   3.989 -#if (NTDDI_VERSION >= NTDDI_WS03SP1)
   3.990 -  KeAcquireGuardedMutex(&xpdd->WatchHandlerMutex);
   3.991 -#endif
   3.992 -
   3.993 -  KdPrint((__DRIVER_NAME "     Path = %s\n", Path));
   3.994 -
   3.995 -  ChildList = WdfFdoGetDefaultChildList(Device);
   3.996 -
   3.997 -  Bits = SplitString(Path, '/', 3, &Count);
   3.998 -
   3.999 -  KdPrint((__DRIVER_NAME "     Count = %s\n", Count));
  3.1000 -
  3.1001 -  ChildDeviceData = NULL;
  3.1002 -  WDF_CHILD_LIST_ITERATOR_INIT(&ChildIterator, WdfRetrievePresentChildren);
  3.1003 -  WdfChildListBeginIteration(ChildList, &ChildIterator);
  3.1004 -  while (NT_SUCCESS(WdfChildListRetrieveNextDevice(ChildList, &ChildIterator, &ChildDevice, NULL)))
  3.1005 -  {
  3.1006 -    ChildDeviceData = GetXenDeviceData(ChildDevice);
  3.1007 -    if (!ChildDeviceData)
  3.1008 -    {
  3.1009 -      KdPrint(("     No child device data, should never happen\n"));
  3.1010 -      continue;
  3.1011 -    }
  3.1012 -    if (strncmp(ChildDeviceData->Path, Path, strlen(ChildDeviceData->Path)) == 0 && Path[strlen(ChildDeviceData->Path)] == '/')
  3.1013 -    {
  3.1014 -      if (Count == 3 && ChildDeviceData->WatchHandler != NULL)
  3.1015 -        ChildDeviceData->WatchHandler(Path, ChildDeviceData->WatchContext);
  3.1016 -      break;
  3.1017 -    }
  3.1018 -    ChildDeviceData = NULL;
  3.1019 -  }
  3.1020 -  WdfChildListEndIteration(ChildList, &ChildIterator);
  3.1021 -  if (Count >= 2 && ChildDeviceData == NULL)
  3.1022 -  {
  3.1023 -    RtlZeroMemory(&description, sizeof(description));
  3.1024 -    WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&description.Header, sizeof(description));
  3.1025 -    strncpy(description.Path, Path, 128);
  3.1026 -    strncpy(description.DeviceType, Bits[1], 128);
  3.1027 -    KdPrint((__DRIVER_NAME "     Adding child for %s\n", description.DeviceType));
  3.1028 -    status = WdfChildListAddOrUpdateChildDescriptionAsPresent(ChildList, &description.Header, NULL);
  3.1029 -  }
  3.1030 -  FreeSplitString(Bits, Count);
  3.1031 -
  3.1032 -#if (NTDDI_VERSION >= NTDDI_WS03SP1)
  3.1033 -  KeReleaseGuardedMutex(&xpdd->WatchHandlerMutex);
  3.1034 -#endif
  3.1035 -
  3.1036 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  3.1037 -}
  3.1038 -
  3.1039 -struct {
  3.1040 -  ULONG do_spin;
  3.1041 -  ULONG nr_spinning;
  3.1042 -} typedef SUSPEND_INFO, *PSUSPEND_INFO;
  3.1043 -
  3.1044 -static VOID
  3.1045 -XenPci_Suspend(
  3.1046 - PRKDPC Dpc,
  3.1047 - PVOID Context,
  3.1048 - PVOID SystemArgument1,
  3.1049 - PVOID SystemArgument2)
  3.1050 -{
  3.1051 -  WDFDEVICE Device = Context;
  3.1052 -//  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
  3.1053 -  PSUSPEND_INFO suspend_info = SystemArgument1;
  3.1054 -  ULONG ActiveProcessorCount;
  3.1055 -  KIRQL OldIrql;
  3.1056 -  int cancelled;
  3.1057 -
  3.1058 -  UNREFERENCED_PARAMETER(Dpc);
  3.1059 -  UNREFERENCED_PARAMETER(SystemArgument2);
  3.1060 -
  3.1061 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (CPU = %d)\n", KeGetCurrentProcessorNumber()));
  3.1062 -  KdPrint((__DRIVER_NAME "     Device = %p\n", Device));
  3.1063 -
  3.1064 -  if (KeGetCurrentProcessorNumber() != 0)
  3.1065 -  {
  3.1066 -    KdPrint((__DRIVER_NAME "     spinning...\n"));
  3.1067 -    InterlockedIncrement((volatile LONG *)&suspend_info->nr_spinning);
  3.1068 -    KeMemoryBarrier();
  3.1069 -    while(suspend_info->do_spin)
  3.1070 -    {
  3.1071 -      /* we should be able to wait more nicely than this... */
  3.1072 -    }
  3.1073 -    KeMemoryBarrier();
  3.1074 -    InterlockedDecrement((volatile LONG *)&suspend_info->nr_spinning);    
  3.1075 -    KdPrint((__DRIVER_NAME "     ...done spinning\n"));
  3.1076 -    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n", KeGetCurrentProcessorNumber()));
  3.1077 -    return;
  3.1078 -  }
  3.1079 -  ActiveProcessorCount = (ULONG)KeNumberProcessors;
  3.1080 -
  3.1081 -  KdPrint((__DRIVER_NAME "     waiting for all other processors to spin\n"));
  3.1082 -  while (suspend_info->nr_spinning < ActiveProcessorCount - 1)
  3.1083 -  {
  3.1084 -      /* we should be able to wait more nicely than this... */
  3.1085 -  }
  3.1086 -  KdPrint((__DRIVER_NAME "     all other processors are spinning\n"));
  3.1087 -
  3.1088 -  KeRaiseIrql(HIGH_LEVEL, &OldIrql);
  3.1089 -  KdPrint((__DRIVER_NAME "     calling suspend\n"));
  3.1090 -  cancelled = HYPERVISOR_shutdown(Device, SHUTDOWN_suspend);
  3.1091 -  KdPrint((__DRIVER_NAME "     back from suspend, cancelled = %d\n", cancelled));
  3.1092 -  KeLowerIrql(OldIrql);
  3.1093 -
  3.1094 -  KdPrint((__DRIVER_NAME "     waiting for all other processors to stop spinning\n"));
  3.1095 -  suspend_info->do_spin = 0;
  3.1096 -  while (suspend_info->nr_spinning != 0)
  3.1097 -  {
  3.1098 -      /* we should be able to wait more nicely than this... */
  3.1099 -  }
  3.1100 -  KdPrint((__DRIVER_NAME "     all other processors have stopped spinning\n"));
  3.1101 -
  3.1102 -  // TODO: Enable xenbus
  3.1103 -  // TODO: Enable our IRQ
  3.1104 -
  3.1105 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n", KeGetCurrentProcessorNumber()));
  3.1106 -}
  3.1107 -
  3.1108 -static VOID
  3.1109 -XenPci_BeginSuspend(WDFDEVICE Device)
  3.1110 -{
  3.1111 -  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
  3.1112 -//  KAFFINITY ActiveProcessorMask = 0;
  3.1113 -  ULONG ActiveProcessorCount;
  3.1114 -  ULONG i;
  3.1115 -  PSUSPEND_INFO suspend_info;
  3.1116 -  PKDPC Dpc;
  3.1117 -  KIRQL OldIrql;
  3.1118 -
  3.1119 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  3.1120 -  KdPrint((__DRIVER_NAME "     Device = %p\n", Device));
  3.1121 -
  3.1122 -  if (!xpdd->suspending)
  3.1123 -  {
  3.1124 -    xpdd->suspending = 1;
  3.1125 -    suspend_info = ExAllocatePoolWithTag(NonPagedPool, sizeof(SUSPEND_INFO), XENPCI_POOL_TAG);
  3.1126 -    suspend_info->do_spin = 1;
  3.1127 -    RtlZeroMemory(suspend_info, sizeof(SUSPEND_INFO));
  3.1128 -    // TODO: Disable xenbus
  3.1129 -    // TODO: Disable our IRQ
  3.1130 -    //ActiveProcessorCount = KeQueryActiveProcessorCount(&ActiveProcessorMask);
  3.1131 -    ActiveProcessorCount = (ULONG)KeNumberProcessors;
  3.1132 -    KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
  3.1133 -    for (i = 0; i < ActiveProcessorCount; i++)
  3.1134 -    {
  3.1135 -      Dpc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KDPC), XENPCI_POOL_TAG);
  3.1136 -      KeInitializeDpc(Dpc, XenPci_Suspend, Device);
  3.1137 -      KeSetTargetProcessorDpc(Dpc, (CCHAR)i);
  3.1138 -      KeInsertQueueDpc(Dpc, suspend_info, NULL);
  3.1139 -    }
  3.1140 -    KeLowerIrql(OldIrql);
  3.1141 -  }
  3.1142 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  3.1143 -}
  3.1144 -
  3.1145 -static void
  3.1146 -XenBus_ShutdownHandler(char *Path, PVOID Data)
  3.1147 -{
  3.1148 -  WDFDEVICE Device = Data;  
  3.1149 -  char *res;
  3.1150 -  char *Value;
  3.1151 -  xenbus_transaction_t xbt;
  3.1152 -  int retry;
  3.1153 -  PSHUTDOWN_MSG_ENTRY Entry;
  3.1154 -
  3.1155 -  UNREFERENCED_PARAMETER(Path);
  3.1156 -
  3.1157 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  3.1158 -  KdPrint((__DRIVER_NAME "     Device = %p\n", Device));
  3.1159 -
  3.1160 -  res = XenBus_StartTransaction(Device, &xbt);
  3.1161 -  if (res)
  3.1162 -  {
  3.1163 -    KdPrint(("Error starting transaction\n"));
  3.1164 -    XenPCI_FreeMem(res);
  3.1165 -    return;
  3.1166 -  }
  3.1167 -
  3.1168 -  res = XenBus_Read(Device, XBT_NIL, SHUTDOWN_PATH, &Value);
  3.1169 -  if (res)
  3.1170 -  {
  3.1171 -    KdPrint(("Error reading shutdown path\n"));
  3.1172 -    XenPCI_FreeMem(res);
  3.1173 -    XenBus_EndTransaction(Device, xbt, 1, &retry);
  3.1174 -    return;
  3.1175 -  }
  3.1176 -
  3.1177 -  if (Value != NULL && strlen(Value) != 0)
  3.1178 -  {
  3.1179 -    res = XenBus_Write(Device, XBT_NIL, SHUTDOWN_PATH, "");
  3.1180 -    if (res)
  3.1181 -    {
  3.1182 -      KdPrint(("Error writing shutdown path\n"));
  3.1183 -      XenPCI_FreeMem(res);
  3.1184 -      // end trans?
  3.1185 -      return;
  3.1186 -    }
  3.1187 -  } 
  3.1188 -
  3.1189 -  if (Value != NULL)
  3.1190 -  {
  3.1191 -    KdPrint((__DRIVER_NAME "     Shutdown Value = %s\n", Value));
  3.1192 -    KdPrint((__DRIVER_NAME "     strlen(...) = %d\n", strlen(Value)));
  3.1193 -  }
  3.1194 -  else
  3.1195 -  {
  3.1196 -    KdPrint((__DRIVER_NAME "     Shutdown Value = <null>\n"));
  3.1197 -  }
  3.1198 -
  3.1199 -  res = XenBus_EndTransaction(Device, xbt, 0, &retry);
  3.1200 -  if (res)
  3.1201 -  {
  3.1202 -    KdPrint(("Error ending transaction\n"));
  3.1203 -    XenPCI_FreeMem(res);
  3.1204 -    return;
  3.1205 -  }
  3.1206 -
  3.1207 -  if (Value != NULL && strlen(Value) != 0)
  3.1208 -  {
  3.1209 -    if (strcmp(Value, "suspend") == 0)
  3.1210 -    {
  3.1211 -      KdPrint((__DRIVER_NAME "     Suspend detected\n"));
  3.1212 -      XenPci_BeginSuspend(Device);
  3.1213 -    }
  3.1214 -    else
  3.1215 -    {
  3.1216 -      Entry = (PSHUTDOWN_MSG_ENTRY)ExAllocatePoolWithTag(NonPagedPool, sizeof(SHUTDOWN_MSG_ENTRY) + strlen(Value) + 1 + 1, XENPCI_POOL_TAG);
  3.1217 -      Entry->Ptr = 0;
  3.1218 -      RtlStringCbPrintfA(Entry->Buf, sizeof(SHUTDOWN_MSG_ENTRY) + strlen(Value) + 1 + 1, "%s\n", Value);
  3.1219 -      InsertTailList(&ShutdownMsgList, &Entry->ListEntry);
  3.1220 -      WdfIoQueueStart(ReadQueue);
  3.1221 -    }
  3.1222 -  }
  3.1223 -
  3.1224 -  XenPCI_FreeMem(Value);
  3.1225 -
  3.1226 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  3.1227 -}
  3.1228 -
  3.1229 -static VOID
  3.1230 -XenBus_BalloonHandler(char *Path, PVOID Data)
  3.1231 -{
  3.1232 -  WDFDEVICE Device = Data;
  3.1233 -  char *value;
  3.1234 -  xenbus_transaction_t xbt;
  3.1235 -  int retry;
  3.1236 -
  3.1237 -  UNREFERENCED_PARAMETER(Path);
  3.1238 -
  3.1239 -  KdPrint((__DRIVER_NAME " --> XenBus_BalloonHandler\n"));
  3.1240 -
  3.1241 -  XenBus_StartTransaction(Device, &xbt);
  3.1242 -
  3.1243 -  XenBus_Read(Device, XBT_NIL, BALLOON_PATH, &value);
  3.1244 -
  3.1245 -  KdPrint((__DRIVER_NAME "     Balloon Value = %s\n", value));
  3.1246 -
  3.1247 -  // use the memory_op(unsigned int op, void *arg) hypercall to adjust this
  3.1248 -  // use XENMEM_increase_reservation and XENMEM_decrease_reservation
  3.1249 -
  3.1250 -  XenBus_EndTransaction(Device, xbt, 0, &retry);
  3.1251 -
  3.1252 -  XenPCI_FreeMem(value);
  3.1253 -
  3.1254 -  KdPrint((__DRIVER_NAME " <-- XenBus_BalloonHandler\n"));
  3.1255 -}
  3.1256 -
  3.1257 -static VOID
  3.1258 -XenBus_SysrqHandler(char *Path, PVOID Data)
  3.1259 -{
  3.1260 -  WDFDEVICE Device = Data;
  3.1261 -  char *Value;
  3.1262 -  xenbus_transaction_t xbt;
  3.1263 -  int retry;
  3.1264 -  char letter;
  3.1265 -  char *res;
  3.1266 -
  3.1267 -  UNREFERENCED_PARAMETER(Path);
  3.1268 -
  3.1269 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  3.1270 -
  3.1271 -  XenBus_StartTransaction(Device, &xbt);
  3.1272 -
  3.1273 -  XenBus_Read(Device, XBT_NIL, SYSRQ_PATH, &Value);
  3.1274 -
  3.1275 -  KdPrint((__DRIVER_NAME "     SysRq Value = %s\n", Value));
  3.1276 -
  3.1277 -  if (Value != NULL && strlen(Value) != 0)
  3.1278 -  {
  3.1279 -    letter = *Value;
  3.1280 -    res = XenBus_Write(Device, XBT_NIL, SYSRQ_PATH, "");
  3.1281 -    if (res)
  3.1282 -    {
  3.1283 -      KdPrint(("Error writing sysrq path\n"));
  3.1284 -      XenPCI_FreeMem(res);
  3.1285 -      XenBus_EndTransaction(Device, xbt, 0, &retry);
  3.1286 -      return;
  3.1287 -    }
  3.1288 -  }
  3.1289 -  else
  3.1290 -  {
  3.1291 -    letter = 0;
  3.1292 -  }
  3.1293 -
  3.1294 -  XenBus_EndTransaction(Device, xbt, 0, &retry);
  3.1295 -
  3.1296 -  if (Value != NULL)
  3.1297 -  {
  3.1298 -    XenPCI_FreeMem(Value);
  3.1299 -  }
  3.1300 -
  3.1301 -  switch (letter)
  3.1302 -  {
  3.1303 -  case 'B':
  3.1304 -    KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000001, 0x00000000, 0x00000000, 0x00000000);
  3.1305 -    break;
  3.1306 -  default:
  3.1307 -    KdPrint(("     Unhandled sysrq letter %c\n", letter));
  3.1308 -    break;
  3.1309 -  }
  3.1310 -
  3.1311 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  3.1312 -}
  3.1313 -
  3.1314 -static NTSTATUS
  3.1315 -XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList)
  3.1316 -{
  3.1317 -  NTSTATUS  status;
  3.1318 -  WDFIORESLIST resourceList;
  3.1319 -  IO_RESOURCE_DESCRIPTOR descriptor;
  3.1320 -  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
  3.1321 -
  3.1322 -  //KdPrint((__DRIVER_NAME " --> DeviceResourceRequirementsQuery\n"));
  3.1323 -
  3.1324 -  status = WdfIoResourceListCreate(IoResourceRequirementsList, WDF_NO_OBJECT_ATTRIBUTES, &resourceList);
  3.1325 -  if (!NT_SUCCESS(status))
  3.1326 -    return status;
  3.1327 -
  3.1328 -  RtlZeroMemory(&descriptor, sizeof(descriptor));
  3.1329 -
  3.1330 -  descriptor.Option = 0;
  3.1331 -  descriptor.Type = CmResourceTypeMemory;
  3.1332 -  descriptor.ShareDisposition = CmResourceShareShared; //CmResourceShareDeviceExclusive;
  3.1333 -  descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
  3.1334 -  descriptor.u.Memory.Length = PAGE_SIZE;
  3.1335 -  descriptor.u.Memory.Alignment = PAGE_SIZE;
  3.1336 -  descriptor.u.Memory.MinimumAddress.QuadPart
  3.1337 -    = xpdd->platform_mmio_addr.QuadPart + PAGE_SIZE;
  3.1338 -  descriptor.u.Memory.MaximumAddress.QuadPart
  3.1339 -    = xpdd->platform_mmio_addr.QuadPart + xpdd->platform_mmio_len - 1;
  3.1340 -
  3.1341 -  //KdPrint((__DRIVER_NAME "     MinimumAddress = %08x, MaximumAddress = %08X\n", descriptor.u.Memory.MinimumAddress.LowPart, descriptor.u.Memory.MaximumAddress.LowPart));
  3.1342 -
  3.1343 -  status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
  3.1344 -  if (!NT_SUCCESS(status))
  3.1345 -    return status;
  3.1346 -
  3.1347 -  status = WdfIoResourceRequirementsListAppendIoResList(IoResourceRequirementsList, resourceList);
  3.1348 -  if (!NT_SUCCESS(status))
  3.1349 -    return status;
  3.1350 -
  3.1351 -  //KdPrint((__DRIVER_NAME " <-- DeviceResourceRequirementsQuery\n"));
  3.1352 -
  3.1353 -  return status;
  3.1354 -}
  3.1355 -#endif
  3.1356 \ No newline at end of file
  3.1357 +}
  3.1358 \ No newline at end of file
     4.1 --- a/xenpci/xenpci.h	Fri May 02 20:54:46 2008 +1000
     4.2 +++ b/xenpci/xenpci.h	Sun May 04 16:40:30 2008 +1000
     4.3 @@ -93,21 +93,22 @@ typedef struct _XENBUS_WATCH_ENTRY {
     4.4  #define NR_XB_REQS 32
     4.5  #define MAX_WATCH_ENTRIES 128
     4.6  
     4.7 -#define CHILD_STATE_DELETED 0
     4.8 -#define CHILD_STATE_ADDED 1
     4.9 +#define CHILD_STATE_EMPTY 0
    4.10 +#define CHILD_STATE_DELETED 1
    4.11 +#define CHILD_STATE_ADDED 2
    4.12 +
    4.13 +// TODO: tidy up & organize this struct
    4.14  
    4.15  typedef struct
    4.16  {
    4.17 -  DEVICE_OBJECT pdo;
    4.18 -  int state;
    4.19 -  PCHAR path;
    4.20 -} XEN_CHILD, *PXEN_CHILD;
    4.21 -
    4.22 -// TODO: tidy up & organize this struct
    4.23 -typedef struct {
    4.24    PDEVICE_OBJECT fdo;
    4.25    PDEVICE_OBJECT pdo;
    4.26    PDEVICE_OBJECT lower_do;
    4.27 +} XENPCI_COMMON, *PXENPCI_COMMON;
    4.28 +
    4.29 +typedef struct {  
    4.30 +  XENPCI_COMMON common;
    4.31 +  
    4.32    BOOLEAN XenBus_ShuttingDown;
    4.33  
    4.34    PKINTERRUPT interrupt;
    4.35 @@ -154,14 +155,24 @@ typedef struct {
    4.36  
    4.37    KGUARDED_MUTEX WatchHandlerMutex;
    4.38  
    4.39 -  int child_count;
    4.40 -  XEN_CHILD child_devices[16];
    4.41 +  LIST_ENTRY child_list;
    4.42    
    4.43    int suspending;
    4.44  } XENPCI_DEVICE_DATA, *PXENPCI_DEVICE_DATA;
    4.45  
    4.46 -//WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_DATA, GetDeviceData);
    4.47 +typedef struct {  
    4.48 +  XENPCI_COMMON common;
    4.49 +  char path[128];
    4.50 +  ULONG index;
    4.51 +} XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
    4.52  
    4.53 +typedef struct
    4.54 +{
    4.55 +  LIST_ENTRY entry;
    4.56 +  int state;
    4.57 +  PXENPCI_PDO_DEVICE_DATA context;
    4.58 +} XEN_CHILD, *PXEN_CHILD;
    4.59 +  
    4.60  #include "hypercall.h"
    4.61  
    4.62  typedef unsigned long xenbus_transaction_t;
    4.63 @@ -169,6 +180,22 @@ typedef uint32_t XENSTORE_RING_IDX;
    4.64  
    4.65  #define XBT_NIL ((xenbus_transaction_t)0)
    4.66  
    4.67 +NTSTATUS
    4.68 +XenPci_Power_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
    4.69 +NTSTATUS
    4.70 +XenPci_Dummy_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
    4.71 +NTSTATUS
    4.72 +XenPci_Pnp_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
    4.73 +
    4.74 +NTSTATUS
    4.75 +XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
    4.76 +NTSTATUS
    4.77 +XenPci_Dummy_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
    4.78 +NTSTATUS
    4.79 +XenPci_Pnp_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
    4.80 +
    4.81 +
    4.82 +
    4.83  char *
    4.84  XenBus_Read(PVOID Context, xenbus_transaction_t xbt, const char *path, char **value);
    4.85  char *
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xenpci/xenpci_fdo.c	Sun May 04 16:40:30 2008 +1000
     5.3 @@ -0,0 +1,1329 @@
     5.4 +/*
     5.5 +PV Drivers for Windows Xen HVM Domains
     5.6 +Copyright (C) 2007 James Harper
     5.7 +
     5.8 +This program is free software; you can redistribute it and/or
     5.9 +modify it under the terms of the GNU General Public License
    5.10 +as published by the Free Software Foundation; either version 2
    5.11 +of the License, or (at your option) any later version.
    5.12 +
    5.13 +This program is distributed in the hope that it will be useful,
    5.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.16 +GNU General Public License for more details.
    5.17 +
    5.18 +You should have received a copy of the GNU General Public License
    5.19 +along with this program; if not, write to the Free Software
    5.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    5.21 +*/
    5.22 +
    5.23 +#include "xenpci.h"
    5.24 +#include <stdlib.h>
    5.25 +
    5.26 +#define SYSRQ_PATH "control/sysrq"
    5.27 +#define SHUTDOWN_PATH "control/shutdown"
    5.28 +#define BALLOON_PATH "memory/target"
    5.29 +
    5.30 +#if 0
    5.31 +static NTSTATUS
    5.32 +XenPCI_PrepareHardware(WDFDEVICE hDevice, WDFCMRESLIST Resources, WDFCMRESLIST ResourcesTranslated);
    5.33 +static NTSTATUS
    5.34 +XenPCI_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated);
    5.35 +static NTSTATUS
    5.36 +XenPCI_D0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
    5.37 +static NTSTATUS
    5.38 +XenPCI_D0EntryPostInterruptsEnabled(WDFDEVICE  Device, WDF_POWER_DEVICE_STATE PreviousState);
    5.39 +static NTSTATUS
    5.40 +XenPCI_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState);
    5.41 +static NTSTATUS
    5.42 +XenPCI_D0ExitPreInterruptsDisabled(WDFDEVICE  Device, WDF_POWER_DEVICE_STATE TargetState);
    5.43 +static VOID
    5.44 +XenPCI_IoDefault(WDFQUEUE Queue, WDFREQUEST Request);
    5.45 +static VOID 
    5.46 +XenPCI_IoRead(WDFQUEUE Queue, WDFREQUEST Request, size_t Length);
    5.47 +static NTSTATUS
    5.48 +XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice);
    5.49 +static NTSTATUS
    5.50 +XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice);
    5.51 +static NTSTATUS
    5.52 +XenPCI_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit);
    5.53 +static NTSTATUS
    5.54 +XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
    5.55 +static NTSTATUS
    5.56 +XenPCI_FilterRemoveResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
    5.57 +static NTSTATUS
    5.58 +XenPCI_FilterAddResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList);
    5.59 +static NTSTATUS
    5.60 +XenPCI_RemoveAddedResources(WDFDEVICE Device, WDFCMRESLIST ResourcesRaw, WDFCMRESLIST ResourcesTranslated);
    5.61 +#endif
    5.62 +
    5.63 +static VOID
    5.64 +XenBus_SysrqHandler(char *Path, PVOID Data);
    5.65 +static VOID
    5.66 +XenBus_ShutdownHandler(char *Path, PVOID Data);
    5.67 +static VOID
    5.68 +XenBus_BalloonHandler(char *Path, PVOID Data);
    5.69 +/*
    5.70 +static VOID
    5.71 +XenPCI_XenBusWatchHandler(char *Path, PVOID Data);
    5.72 +*/
    5.73 +
    5.74 +/* Global (driver-wide) variables */
    5.75 +static BOOLEAN AutoEnumerate;
    5.76 +static LIST_ENTRY ShutdownMsgList;
    5.77 +
    5.78 +#pragma warning(disable : 4200) // zero-sized array
    5.79 +
    5.80 +typedef struct {
    5.81 +  LIST_ENTRY ListEntry;
    5.82 +  ULONG Ptr;
    5.83 +//  ULONG Len;
    5.84 +  CHAR Buf[0];
    5.85 +} SHUTDOWN_MSG_ENTRY, *PSHUTDOWN_MSG_ENTRY;
    5.86 +
    5.87 +static KSPIN_LOCK ShutdownMsgLock;
    5.88 +
    5.89 +CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptRaw;
    5.90 +CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptTranslated;
    5.91 +
    5.92 +NTSTATUS
    5.93 +XenPci_Power_Fdo(PDEVICE_OBJECT device_object, PIRP irp)
    5.94 +{
    5.95 +  NTSTATUS status;
    5.96 +  PIO_STACK_LOCATION stack;
    5.97 +  PXENPCI_DEVICE_DATA xpdd;
    5.98 +
    5.99 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.100 +
   5.101 +  xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   5.102 +  stack = IoGetCurrentIrpStackLocation(irp);
   5.103 +  IoSkipCurrentIrpStackLocation(irp);
   5.104 +  status = PoCallDriver(xpdd->common.lower_do, irp);
   5.105 +
   5.106 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.107 +
   5.108 +  return status;
   5.109 +}
   5.110 +
   5.111 +NTSTATUS
   5.112 +XenPci_Dummy_Fdo(PDEVICE_OBJECT device_object, PIRP irp)
   5.113 +{
   5.114 +  NTSTATUS status;
   5.115 +  PIO_STACK_LOCATION stack;
   5.116 +  PXENPCI_DEVICE_DATA xpdd;
   5.117 +
   5.118 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.119 +
   5.120 +  xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   5.121 +  stack = IoGetCurrentIrpStackLocation(irp);
   5.122 +  IoSkipCurrentIrpStackLocation(irp);
   5.123 +  status = IoCallDriver(xpdd->common.lower_do, irp);
   5.124 +
   5.125 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.126 +
   5.127 +  return status;
   5.128 +}
   5.129 +
   5.130 +/*
   5.131 + * Many XEN_IFACE functions allocate memory. Clients must use this to free it.
   5.132 + * (Xenbus_Read, XenBus_List, XenBus_AddWatch, XenBus_RemWatch)
   5.133 + */
   5.134 +static void
   5.135 +XenPCI_FreeMem(PVOID Ptr)
   5.136 +{
   5.137 +  ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
   5.138 +}
   5.139 +
   5.140 +/*
   5.141 + * Alloc MMIO from the device's MMIO region. There is no corresponding free() fn
   5.142 + */
   5.143 +PHYSICAL_ADDRESS
   5.144 +XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len)
   5.145 +{
   5.146 +  PHYSICAL_ADDRESS addr;
   5.147 +
   5.148 +  len = (len + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
   5.149 +
   5.150 +  addr = xpdd->platform_mmio_addr;
   5.151 +  addr.QuadPart += xpdd->platform_mmio_alloc;
   5.152 +  xpdd->platform_mmio_alloc += len;
   5.153 +
   5.154 +  ASSERT(xpdd->platform_mmio_alloc <= xpdd->platform_mmio_len);
   5.155 +
   5.156 +  return addr;
   5.157 +}
   5.158 +
   5.159 +static NTSTATUS
   5.160 +XenPci_Init(PXENPCI_DEVICE_DATA xpdd)
   5.161 +{
   5.162 +  struct xen_add_to_physmap xatp;
   5.163 +  int ret;
   5.164 +  PHYSICAL_ADDRESS shared_info_area_unmapped;
   5.165 +
   5.166 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.167 +
   5.168 +  hvm_get_stubs(xpdd);
   5.169 +
   5.170 +  shared_info_area_unmapped = XenPci_AllocMMIO(xpdd, PAGE_SIZE);
   5.171 +  KdPrint((__DRIVER_NAME " shared_info_area_unmapped.QuadPart = %lx\n", shared_info_area_unmapped.QuadPart));
   5.172 +  xatp.domid = DOMID_SELF;
   5.173 +  xatp.idx = 0;
   5.174 +  xatp.space = XENMAPSPACE_shared_info;
   5.175 +  xatp.gpfn = (xen_pfn_t)(shared_info_area_unmapped.QuadPart >> PAGE_SHIFT);
   5.176 +  KdPrint((__DRIVER_NAME " gpfn = %d\n", xatp.gpfn));
   5.177 +  ret = HYPERVISOR_memory_op(xpdd, XENMEM_add_to_physmap, &xatp);
   5.178 +  KdPrint((__DRIVER_NAME " hypervisor memory op ret = %d\n", ret));
   5.179 +  xpdd->shared_info_area = MmMapIoSpace(shared_info_area_unmapped,
   5.180 +    PAGE_SIZE, MmCached);
   5.181 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.182 +
   5.183 +  return STATUS_SUCCESS;
   5.184 +}
   5.185 +
   5.186 +#if 0
   5.187 +WDFQUEUE ReadQueue;
   5.188 +#endif
   5.189 +
   5.190 +static NTSTATUS
   5.191 +XenPci_Pnp_IoCompletion(PDEVICE_OBJECT device_object, PIRP irp, PVOID context)
   5.192 +{
   5.193 +  PKEVENT event = (PKEVENT)context;
   5.194 +
   5.195 +  UNREFERENCED_PARAMETER(device_object);
   5.196 +
   5.197 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.198 +
   5.199 +  if (irp->PendingReturned)
   5.200 +  {
   5.201 +    KeSetEvent(event, IO_NO_INCREMENT, FALSE);
   5.202 +  }
   5.203 +
   5.204 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   5.205 +
   5.206 +  return STATUS_MORE_PROCESSING_REQUIRED;
   5.207 +}
   5.208 +
   5.209 +static NTSTATUS
   5.210 +XenPci_QueueWorkItem(PDEVICE_OBJECT device_object, PIO_WORKITEM_ROUTINE routine, PVOID context)
   5.211 +{
   5.212 +    PIO_WORKITEM work_item;
   5.213 +    NTSTATUS status = STATUS_SUCCESS;
   5.214 +
   5.215 +	work_item = IoAllocateWorkItem(device_object);
   5.216 +	IoQueueWorkItem(work_item, routine, DelayedWorkQueue, context);
   5.217 +	
   5.218 +    return status;
   5.219 +}
   5.220 +
   5.221 +static NTSTATUS
   5.222 +XenPci_SendAndWaitForIrp(PDEVICE_OBJECT device_object, PIRP irp)
   5.223 +{
   5.224 +  NTSTATUS status;
   5.225 +  PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   5.226 +  KEVENT event;
   5.227 +
   5.228 +  UNREFERENCED_PARAMETER(device_object);
   5.229 +
   5.230 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.231 +
   5.232 +  KeInitializeEvent(&event, NotificationEvent, FALSE);
   5.233 +
   5.234 +  IoCopyCurrentIrpStackLocationToNext(irp);
   5.235 +  IoSetCompletionRoutine(irp, XenPci_Pnp_IoCompletion, &event, TRUE, TRUE, TRUE);
   5.236 +
   5.237 +  status = IoCallDriver(xpdd->common.lower_do, irp);
   5.238 +
   5.239 +  if (status == STATUS_PENDING)
   5.240 +  {
   5.241 +    KdPrint((__DRIVER_NAME "     waiting ...\n"));
   5.242 +    KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
   5.243 +    KdPrint((__DRIVER_NAME "     ... done\n"));
   5.244 +    status = irp->IoStatus.Status;
   5.245 +  }
   5.246 +
   5.247 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   5.248 +
   5.249 +  return status;
   5.250 +}
   5.251 +
   5.252 +static VOID
   5.253 +XenPci_Pnp_StartDeviceCallback(PDEVICE_OBJECT device_object, PVOID context)
   5.254 +{
   5.255 +  NTSTATUS status = STATUS_SUCCESS;
   5.256 +  PXENPCI_DEVICE_DATA xpdd = device_object->DeviceExtension;
   5.257 +  PIRP irp = context;
   5.258 +
   5.259 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.260 +  
   5.261 +  XenPci_Init(xpdd);
   5.262 +
   5.263 +  GntTbl_Init(xpdd);
   5.264 +
   5.265 +  EvtChn_Init(xpdd);
   5.266 +
   5.267 +  XenBus_Init(xpdd);
   5.268 +
   5.269 +  irp->IoStatus.Status = status;
   5.270 +  
   5.271 +  IoCompleteRequest(irp, IO_NO_INCREMENT);
   5.272 +
   5.273 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   5.274 +}
   5.275 +
   5.276 +static NTSTATUS
   5.277 +XenPci_Pnp_StartDevice(PDEVICE_OBJECT device_object, PIRP irp)
   5.278 +{
   5.279 +  NTSTATUS status;
   5.280 +  PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   5.281 +  PIO_STACK_LOCATION stack;
   5.282 +  PCM_PARTIAL_RESOURCE_LIST res_list;
   5.283 +  PCM_PARTIAL_RESOURCE_DESCRIPTOR res_descriptor;
   5.284 +  ULONG i;
   5.285 +
   5.286 +  UNREFERENCED_PARAMETER(device_object);
   5.287 +
   5.288 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.289 +
   5.290 +  stack = IoGetCurrentIrpStackLocation(irp);
   5.291 +
   5.292 +  IoMarkIrpPending(irp);
   5.293 +
   5.294 +  status = XenPci_SendAndWaitForIrp(device_object, irp);
   5.295 +
   5.296 +  /* I think we want to start a work item here to do this... */
   5.297 +
   5.298 +  res_list = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
   5.299 +  
   5.300 +  for (i = 0; i < res_list->Count; i++)
   5.301 +  {
   5.302 +    res_descriptor = &res_list->PartialDescriptors[i];
   5.303 +    switch (res_descriptor->Type)
   5.304 +    {
   5.305 +    case CmResourceTypeInterrupt:
   5.306 +      xpdd->irq_number = res_descriptor->u.Interrupt.Vector;
   5.307 +      memcpy(&InterruptRaw, res_descriptor, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
   5.308 +      break;
   5.309 +    }
   5.310 +  }
   5.311 +
   5.312 +  res_list = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
   5.313 +  
   5.314 +  for (i = 0; i < res_list->Count; i++)
   5.315 +  {
   5.316 +    res_descriptor = &res_list->PartialDescriptors[i];
   5.317 +    switch (res_descriptor->Type) {
   5.318 +    case CmResourceTypePort:
   5.319 +      break;
   5.320 +    case CmResourceTypeMemory:
   5.321 +      KdPrint((__DRIVER_NAME "     Memory mapped CSR:(%x:%x) Length:(%d)\n", res_descriptor->u.Memory.Start.LowPart, res_descriptor->u.Memory.Start.HighPart, res_descriptor->u.Memory.Length));
   5.322 +      xpdd->platform_mmio_addr = res_descriptor->u.Memory.Start;
   5.323 +      xpdd->platform_mmio_len = res_descriptor->u.Memory.Length;
   5.324 +      xpdd->platform_mmio_alloc = 0;
   5.325 +      break;
   5.326 +    case CmResourceTypeInterrupt:
   5.327 +	  xpdd->irq_level = (KIRQL)res_descriptor->u.Interrupt.Level;
   5.328 +	  xpdd->irq_vector = res_descriptor->u.Interrupt.Vector;
   5.329 +	  xpdd->irq_affinity = res_descriptor->u.Interrupt.Affinity;
   5.330 +      memcpy(&InterruptTranslated, res_descriptor, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
   5.331 +      break;
   5.332 +    case CmResourceTypeDevicePrivate:
   5.333 +      KdPrint((__DRIVER_NAME "     Private Data: 0x%02x 0x%02x 0x%02x\n", res_descriptor->u.DevicePrivate.Data[0], res_descriptor->u.DevicePrivate.Data[1], res_descriptor->u.DevicePrivate.Data[2] ));
   5.334 +      break;
   5.335 +    default:
   5.336 +      KdPrint((__DRIVER_NAME "     Unhandled resource type (0x%x)\n", res_descriptor->Type));
   5.337 +      break;
   5.338 +    }
   5.339 +  }
   5.340 +
   5.341 +  XenPci_QueueWorkItem(device_object, XenPci_Pnp_StartDeviceCallback, irp);
   5.342 +
   5.343 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   5.344 +  
   5.345 +  return STATUS_PENDING;
   5.346 +}
   5.347 +
   5.348 +static NTSTATUS
   5.349 +XenPci_Pnp_StopDevice(PDEVICE_OBJECT device_object, PIRP irp, PVOID context)
   5.350 +{
   5.351 +  NTSTATUS status = STATUS_SUCCESS;
   5.352 +
   5.353 +  UNREFERENCED_PARAMETER(device_object);
   5.354 +  UNREFERENCED_PARAMETER(context);
   5.355 +
   5.356 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.357 +
   5.358 +  irp->IoStatus.Status = status;
   5.359 +  IoCompleteRequest(irp, IO_NO_INCREMENT);
   5.360 +
   5.361 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   5.362 +
   5.363 +  return irp->IoStatus.Status;
   5.364 +}
   5.365 +
   5.366 +static NTSTATUS
   5.367 +XenPci_Pnp_QueryRemoveDevice(PDEVICE_OBJECT device_object, PIRP irp)
   5.368 +{
   5.369 +  NTSTATUS status;
   5.370 +  PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   5.371 +
   5.372 +  UNREFERENCED_PARAMETER(device_object);
   5.373 +
   5.374 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.375 +
   5.376 +  if (FALSE)
   5.377 +  {
   5.378 +    /* We are in the paging or hibernation path - can't remove */
   5.379 +    status = irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
   5.380 +    IoCompleteRequest(irp, IO_NO_INCREMENT);
   5.381 +  }
   5.382 +  else
   5.383 +  {
   5.384 +    IoSkipCurrentIrpStackLocation(irp);
   5.385 +    status = IoCallDriver(xpdd->common.lower_do, irp);
   5.386 +  }
   5.387 +
   5.388 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   5.389 +
   5.390 +  return status;
   5.391 +}
   5.392 +
   5.393 +static NTSTATUS
   5.394 +XenPci_Pnp_RemoveDevice(PDEVICE_OBJECT device_object, PIRP irp)
   5.395 +{
   5.396 +  NTSTATUS status;
   5.397 +  PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   5.398 +
   5.399 +  UNREFERENCED_PARAMETER(device_object);
   5.400 +
   5.401 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.402 +
   5.403 +  irp->IoStatus.Status = STATUS_SUCCESS;
   5.404 +  IoSkipCurrentIrpStackLocation(irp);
   5.405 +  status = IoCallDriver(xpdd->common.lower_do, irp);
   5.406 +  IoDetachDevice(xpdd->common.lower_do);
   5.407 +
   5.408 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   5.409 +
   5.410 +  return status;
   5.411 +}
   5.412 +
   5.413 +#if 0
   5.414 +static VOID
   5.415 +XenPci_XenBusWatchHandler(PVOID context, char *path)
   5.416 +{
   5.417 +  NTSTATUS status;
   5.418 +  char **bits;
   5.419 +  int count;
   5.420 +  int i;
   5.421 +//  WDFDEVICE Device = Data;
   5.422 +//  WDFCHILDLIST ChildList;
   5.423 +//  WDF_CHILD_LIST_ITERATOR ChildIterator;
   5.424 +//  WDFDEVICE ChildDevice;
   5.425 +//  PXENPCI_XEN_DEVICE_DATA ChildDeviceData;
   5.426 +//  XENPCI_IDENTIFICATION_DESCRIPTION description;
   5.427 +  PXEN_CHILD child = NULL;
   5.428 +  PXENPCI_DEVICE_DATA xpdd = context;
   5.429 +
   5.430 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.431 +
   5.432 +#if (NTDDI_VERSION >= NTDDI_WS03SP1)
   5.433 +  KeAcquireGuardedMutex(&xpdd->WatchHandlerMutex);
   5.434 +#endif
   5.435 +
   5.436 +  KdPrint((__DRIVER_NAME "     path = %s\n", path));
   5.437 +  bits = SplitString(path, '/', 3, &count);
   5.438 +  KdPrint((__DRIVER_NAME "     Count = %s\n", count));
   5.439 +  
   5.440 +  ASSERT(count >= 2);
   5.441 +  
   5.442 +  for (i = 0; i < 16; i++)
   5.443 +  {
   5.444 +    if (xpdd->child_devices[i].pdo != NULL && strncmp(xpdd->child_devices[i].path, path, strlen(xpdd->child_devices[i].path)) == 0 && path[strlen(xpdd->child_devices[i].path] == '/')
   5.445 +    {
   5.446 +	  child = &xpdd->child_devices[i];
   5.447 +	  break;
   5.448 +	}
   5.449 +  }
   5.450 +  
   5.451 +  if (child == NULL && count >= 2)
   5.452 +    IoInvalidateDeviceRelations(xpdd->common.fdo, BusRelations);
   5.453 +  else if (count > 2)
   5.454 +  {
   5.455 +    // forward on to the child
   5.456 +  }
   5.457 +  
   5.458 +#if 0
   5.459 +  ChildDeviceData = NULL;
   5.460 +  WDF_CHILD_LIST_ITERATOR_INIT(&ChildIterator, WdfRetrievePresentChildren);
   5.461 +  WdfChildListBeginIteration(ChildList, &ChildIterator);
   5.462 +  while (NT_SUCCESS(WdfChildListRetrieveNextDevice(ChildList, &ChildIterator, &ChildDevice, NULL)))
   5.463 +  {
   5.464 +    ChildDeviceData = GetXenDeviceData(ChildDevice);
   5.465 +    if (!ChildDeviceData)
   5.466 +    {
   5.467 +      KdPrint(("     No child device data, should never happen\n"));
   5.468 +      continue;
   5.469 +    }
   5.470 +    if (strncmp(ChildDeviceData->Path, Path, strlen(ChildDeviceData->Path)) == 0 && Path[strlen(ChildDeviceData->Path)] == '/')
   5.471 +    {
   5.472 +      if (Count == 3 && ChildDeviceData->WatchHandler != NULL)
   5.473 +        ChildDeviceData->WatchHandler(Path, ChildDeviceData->WatchContext);
   5.474 +      break;
   5.475 +    }
   5.476 +    ChildDeviceData = NULL;
   5.477 +  }
   5.478 +  WdfChildListEndIteration(ChildList, &ChildIterator);
   5.479 +  if (Count >= 2 && ChildDeviceData == NULL)
   5.480 +  {
   5.481 +    RtlZeroMemory(&description, sizeof(description));
   5.482 +    WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&description.Header, sizeof(description));
   5.483 +    strncpy(description.Path, Path, 128);
   5.484 +    strncpy(description.DeviceType, Bits[1], 128);
   5.485 +    KdPrint((__DRIVER_NAME "     Adding child for %s\n", description.DeviceType));
   5.486 +    status = WdfChildListAddOrUpdateChildDescriptionAsPresent(ChildList, &description.Header, NULL);
   5.487 +  }
   5.488 +  FreeSplitString(Bits, Count);
   5.489 +
   5.490 +#if (NTDDI_VERSION >= NTDDI_WS03SP1)
   5.491 +  KeReleaseGuardedMutex(&xpdd->WatchHandlerMutex);
   5.492 +#endif
   5.493 +
   5.494 +#endif
   5.495 +
   5.496 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.497 +}
   5.498 +#endif
   5.499 +
   5.500 +static VOID
   5.501 +XenPci_Pnp_QueryBusRelationsCallback(PDEVICE_OBJECT device_object, PVOID context)
   5.502 +{
   5.503 +  NTSTATUS status = STATUS_SUCCESS;
   5.504 +  PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   5.505 +  PIRP irp = context;
   5.506 +  int devices = 0;
   5.507 +  PDEVICE_RELATIONS dev_relations;
   5.508 +  PXEN_CHILD child;
   5.509 +  //char *response;
   5.510 +  char *msgTypes;
   5.511 +  char **Types;
   5.512 +  int i;
   5.513 +  //CHAR buffer[128];
   5.514 +  PDEVICE_OBJECT pdo;
   5.515 +  
   5.516 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.517 +
   5.518 +  msgTypes = XenBus_List(xpdd, XBT_NIL, "device", &Types);
   5.519 +  if (!msgTypes)
   5.520 +  {
   5.521 +    for (child = (PXEN_CHILD)xpdd->child_list.Flink; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
   5.522 +    {
   5.523 +      if (child->state == CHILD_STATE_DELETED)
   5.524 +        KdPrint((__DRIVER_NAME "     Found deleted child - this shouldn't happen\n" ));
   5.525 +      child->state = CHILD_STATE_DELETED;
   5.526 +    }
   5.527 +
   5.528 +    for (i = 0; Types[i]; i++)
   5.529 +    {
   5.530 +      //RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/%s", Types[i]);
   5.531 +
   5.532 +      for (child = (PXEN_CHILD)xpdd->child_list.Flink; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
   5.533 +      {
   5.534 +        if (strcmp(child->context->path, Types[i]) == 0)
   5.535 +        {
   5.536 +          KdPrint((__DRIVER_NAME "     Existing device %s\n", Types[i]));
   5.537 +          ASSERT(child->state != CHILD_STATE_DELETED);
   5.538 +          child->state = CHILD_STATE_ADDED;
   5.539 +          devices++;
   5.540 +          break;
   5.541 +        }
   5.542 +      }
   5.543 +      if (child == (PXEN_CHILD)&xpdd->child_list)
   5.544 +      {
   5.545 +        KdPrint((__DRIVER_NAME "     New device %s\n", Types[i]));
   5.546 +        child = ExAllocatePoolWithTag(NonPagedPool, sizeof(XEN_CHILD), XENPCI_POOL_TAG);
   5.547 +        child->state = CHILD_STATE_ADDED;
   5.548 +        status = IoCreateDevice(xpdd->common.fdo->DriverObject, sizeof(XENPCI_COMMON), NULL, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pdo);
   5.549 +        if (!NT_SUCCESS(status))
   5.550 +          KdPrint((__DRIVER_NAME "     IoCreateDevice status = %08X\n", status));
   5.551 +        child->context = (PXENPCI_PDO_DEVICE_DATA)pdo->DeviceExtension;
   5.552 +        child->context->common.fdo = NULL;
   5.553 +        child->context->common.pdo = pdo;
   5.554 +        child->context->common.lower_do = NULL;
   5.555 +        strcpy(child->context->path, Types[i]);
   5.556 +        child->context->index = 0;
   5.557 +        InsertTailList(&xpdd->child_list, (PLIST_ENTRY)child);
   5.558 +        devices++;
   5.559 +      }
   5.560 +      ExFreePoolWithTag(Types[i], XENPCI_POOL_TAG);
   5.561 +    }
   5.562 +    dev_relations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (devices - 1), XENPCI_POOL_TAG);
   5.563 +    for (child = (PXEN_CHILD)xpdd->child_list.Flink, devices = 0; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
   5.564 +    {
   5.565 +      if (child->state == CHILD_STATE_ADDED)
   5.566 +        dev_relations->Objects[devices++] = child->context->common.pdo;
   5.567 +    }
   5.568 +    dev_relations->Count = devices;
   5.569 +
   5.570 +    status = STATUS_SUCCESS;
   5.571 +  }
   5.572 +  else
   5.573 +  {
   5.574 +    devices = 0;
   5.575 +    dev_relations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (devices - 1), XENPCI_POOL_TAG);
   5.576 +    dev_relations->Count = devices;
   5.577 +  }
   5.578 +
   5.579 +  XenPCI_FreeMem(Types);
   5.580 +
   5.581 +  irp->IoStatus.Status = status;
   5.582 +  irp->IoStatus.Information = (ULONG_PTR)dev_relations;
   5.583 +
   5.584 +  IoCompleteRequest (irp, IO_NO_INCREMENT);
   5.585 +
   5.586 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   5.587 +}
   5.588 +
   5.589 +static NTSTATUS
   5.590 +XenPci_Pnp_QueryBusRelations(PDEVICE_OBJECT device_object, PIRP irp)
   5.591 +{
   5.592 +  NTSTATUS status;
   5.593 +
   5.594 +  UNREFERENCED_PARAMETER(device_object);
   5.595 +
   5.596 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.597 +
   5.598 +  IoMarkIrpPending(irp);
   5.599 +
   5.600 +  status = XenPci_SendAndWaitForIrp(device_object, irp);
   5.601 +
   5.602 +  XenPci_QueueWorkItem(device_object, XenPci_Pnp_QueryBusRelationsCallback, irp);
   5.603 +
   5.604 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   5.605 +
   5.606 +  return STATUS_PENDING;
   5.607 +}
   5.608 +
   5.609 +NTSTATUS
   5.610 +XenPci_Pnp_Fdo(PDEVICE_OBJECT device_object, PIRP irp)
   5.611 +{
   5.612 +  PIO_STACK_LOCATION stack;
   5.613 +  NTSTATUS status;
   5.614 +  PXENPCI_DEVICE_DATA xpdd;
   5.615 +
   5.616 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.617 +
   5.618 +  xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   5.619 +
   5.620 +  stack = IoGetCurrentIrpStackLocation(irp);
   5.621 +
   5.622 +  switch (stack->MinorFunction)
   5.623 +  {
   5.624 +  case IRP_MN_START_DEVICE:
   5.625 +    KdPrint((__DRIVER_NAME "     IRP_MN_START_DEVICE\n"));
   5.626 +    return XenPci_Pnp_StartDevice(device_object, irp);
   5.627 +
   5.628 +  case IRP_MN_QUERY_STOP_DEVICE:
   5.629 +    KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_STOP_DEVICE\n"));
   5.630 +    IoSkipCurrentIrpStackLocation(irp);
   5.631 +    irp->IoStatus.Status = STATUS_SUCCESS;
   5.632 +    break;
   5.633 +
   5.634 +  case IRP_MN_STOP_DEVICE:
   5.635 +    KdPrint((__DRIVER_NAME "     IRP_MN_STOP_DEVICE\n"));
   5.636 +    IoCopyCurrentIrpStackLocationToNext(irp);
   5.637 +    IoSetCompletionRoutine(irp, XenPci_Pnp_StopDevice, NULL, TRUE, TRUE, TRUE);
   5.638 +    break;
   5.639 +
   5.640 +  case IRP_MN_CANCEL_STOP_DEVICE:
   5.641 +    KdPrint((__DRIVER_NAME "     IRP_MN_CANCEL_STOP_DEVICE\n"));
   5.642 +    IoSkipCurrentIrpStackLocation(irp);
   5.643 +    irp->IoStatus.Status = STATUS_SUCCESS;
   5.644 +    break;
   5.645 +
   5.646 +  case IRP_MN_QUERY_REMOVE_DEVICE:
   5.647 +    KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_REMOVE_DEVICE\n"));
   5.648 +    return XenPci_Pnp_QueryRemoveDevice(device_object, irp);
   5.649 +
   5.650 +  case IRP_MN_REMOVE_DEVICE:
   5.651 +    KdPrint((__DRIVER_NAME "     IRP_MN_REMOVE_DEVICE\n"));
   5.652 +    return XenPci_Pnp_QueryRemoveDevice(device_object, irp);
   5.653 +    break;
   5.654 +
   5.655 +  case IRP_MN_CANCEL_REMOVE_DEVICE:
   5.656 +    KdPrint((__DRIVER_NAME "     IRP_MN_CANCEL_REMOVE_DEVICE\n"));
   5.657 +    IoSkipCurrentIrpStackLocation(irp);
   5.658 +    irp->IoStatus.Status = STATUS_SUCCESS;
   5.659 +    break;
   5.660 +
   5.661 +  case IRP_MN_SURPRISE_REMOVAL:
   5.662 +    KdPrint((__DRIVER_NAME "     IRP_MN_SURPRISE_REMOVAL\n"));
   5.663 +    IoSkipCurrentIrpStackLocation(irp);
   5.664 +    irp->IoStatus.Status = STATUS_SUCCESS;
   5.665 +    break;
   5.666 +
   5.667 +  case IRP_MN_DEVICE_USAGE_NOTIFICATION:
   5.668 +    KdPrint((__DRIVER_NAME "     IRP_MN_DEVICE_USAGE_NOTIFICATION\n"));
   5.669 +    IoSkipCurrentIrpStackLocation(irp);
   5.670 +    irp->IoStatus.Status = STATUS_SUCCESS;
   5.671 +    break;
   5.672 +
   5.673 +  case IRP_MN_QUERY_DEVICE_RELATIONS:
   5.674 +    KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_DEVICE_RELATIONS\n"));
   5.675 +    switch (stack->Parameters.QueryDeviceRelations.Type)
   5.676 +    {
   5.677 +    case BusRelations:
   5.678 +      KdPrint((__DRIVER_NAME "     BusRelations\n"));
   5.679 +      return XenPci_Pnp_QueryBusRelations(device_object, irp);
   5.680 +      break;  
   5.681 +    default:
   5.682 +      IoSkipCurrentIrpStackLocation(irp);
   5.683 +      break;  
   5.684 +    }
   5.685 +    break;
   5.686 +
   5.687 +  default:
   5.688 +    KdPrint((__DRIVER_NAME "     Unhandled Minor = %d\n", stack->MinorFunction));
   5.689 +    IoSkipCurrentIrpStackLocation(irp);
   5.690 +    break;
   5.691 +  }
   5.692 +
   5.693 +  status = IoCallDriver(xpdd->common.lower_do, irp);
   5.694 +
   5.695 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   5.696 +
   5.697 +  return status;
   5.698 +}
   5.699 +
   5.700 +#if 0
   5.701 +
   5.702 +static NTSTATUS
   5.703 +XenPCI_D0Entry(
   5.704 +    IN WDFDEVICE  Device,
   5.705 +    IN WDF_POWER_DEVICE_STATE PreviousState
   5.706 +    )
   5.707 +{
   5.708 +  NTSTATUS status = STATUS_SUCCESS;
   5.709 +
   5.710 +  UNREFERENCED_PARAMETER(Device);
   5.711 +  UNREFERENCED_PARAMETER(PreviousState);
   5.712 +
   5.713 +  KdPrint((__DRIVER_NAME " --> EvtDeviceD0Entry\n"));
   5.714 +
   5.715 +  KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Entry\n"));
   5.716 +
   5.717 +  return status;
   5.718 +}
   5.719 +
   5.720 +static NTSTATUS
   5.721 +XenPCI_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState)
   5.722 +{
   5.723 +  NTSTATUS status = STATUS_SUCCESS;
   5.724 +  //OBJECT_ATTRIBUTES oa;
   5.725 +  char *response;
   5.726 +  char *msgTypes;
   5.727 +  char **Types;
   5.728 +  int i;
   5.729 +  char buffer[128];
   5.730 +  WDFCHILDLIST ChildList;
   5.731 +
   5.732 +  UNREFERENCED_PARAMETER(PreviousState);
   5.733 +
   5.734 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.735 +
   5.736 +  XenBus_Start(Device);
   5.737 +
   5.738 +  response = XenBus_AddWatch(Device, XBT_NIL, SYSRQ_PATH, XenBus_SysrqHandler, Device);
   5.739 +  KdPrint((__DRIVER_NAME "     sysrqwatch response = '%s'\n", response)); 
   5.740 +  
   5.741 +  response = XenBus_AddWatch(Device, XBT_NIL, SHUTDOWN_PATH, XenBus_ShutdownHandler, Device);
   5.742 +  KdPrint((__DRIVER_NAME "     shutdown watch response = '%s'\n", response)); 
   5.743 +
   5.744 +  response = XenBus_AddWatch(Device, XBT_NIL, BALLOON_PATH, XenBus_BalloonHandler, Device);
   5.745 +  KdPrint((__DRIVER_NAME "     shutdown watch response = '%s'\n", response)); 
   5.746 +
   5.747 +  response = XenBus_AddWatch(Device, XBT_NIL, "device", XenPCI_XenBusWatchHandler, Device);
   5.748 +  KdPrint((__DRIVER_NAME "     device watch response = '%s'\n", response)); 
   5.749 +
   5.750 +  ChildList = WdfFdoGetDefaultChildList(Device);
   5.751 +
   5.752 +  WdfChildListBeginScan(ChildList);
   5.753 +  msgTypes = XenBus_List(Device, XBT_NIL, "device", &Types);
   5.754 +  if (!msgTypes) {
   5.755 +    for (i = 0; Types[i]; i++)
   5.756 +    {
   5.757 +      RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/%s", Types[i]);
   5.758 +      XenPCI_XenBusWatchHandler(buffer, Device);
   5.759 +      ExFreePoolWithTag(Types[i], XENPCI_POOL_TAG);
   5.760 +    }
   5.761 +  }
   5.762 +  WdfChildListEndScan(ChildList);
   5.763 +
   5.764 +  XenPCI_FreeMem(Types);
   5.765 +
   5.766 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.767 +
   5.768 +  return status;
   5.769 +}
   5.770 +
   5.771 +static NTSTATUS
   5.772 +XenPCI_D0ExitPreInterruptsDisabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
   5.773 +{
   5.774 +  NTSTATUS status = STATUS_SUCCESS;
   5.775 +
   5.776 +  UNREFERENCED_PARAMETER(TargetState);
   5.777 +
   5.778 +  KdPrint((__DRIVER_NAME " --> D0ExitPreInterruptsDisabled\n"));
   5.779 +
   5.780 +  XenBus_Stop(Device);
   5.781 +
   5.782 +  KdPrint((__DRIVER_NAME " <-- D0ExitPreInterruptsDisabled\n"));
   5.783 +
   5.784 +  return status;
   5.785 +}
   5.786 +
   5.787 +static NTSTATUS
   5.788 +XenPCI_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
   5.789 +{
   5.790 +  NTSTATUS status = STATUS_SUCCESS;
   5.791 +
   5.792 +  UNREFERENCED_PARAMETER(Device);
   5.793 +  UNREFERENCED_PARAMETER(TargetState);
   5.794 +
   5.795 +  KdPrint((__DRIVER_NAME " --> DeviceD0Exit\n"));
   5.796 +
   5.797 +  XenBus_Close(Device);
   5.798 +
   5.799 +  KdPrint((__DRIVER_NAME " <-- DeviceD0Exit\n"));
   5.800 +
   5.801 +  return status;
   5.802 +}
   5.803 +
   5.804 +static VOID 
   5.805 +XenPCI_IoDefault(
   5.806 +    IN WDFQUEUE  Queue,
   5.807 +    IN WDFREQUEST  Request
   5.808 +    )
   5.809 +{
   5.810 +  UNREFERENCED_PARAMETER(Queue);
   5.811 +
   5.812 +  KdPrint((__DRIVER_NAME " --> EvtDeviceIoDefault\n"));
   5.813 +
   5.814 +  WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
   5.815 +
   5.816 +  KdPrint((__DRIVER_NAME " <-- EvtDeviceIoDefault\n"));
   5.817 +}
   5.818 +
   5.819 +static VOID 
   5.820 +XenPCI_IoRead(WDFQUEUE Queue, WDFREQUEST Request, size_t Length)
   5.821 +{
   5.822 +  PSHUTDOWN_MSG_ENTRY Entry;
   5.823 +  size_t Remaining;
   5.824 +  size_t CopyLen;
   5.825 +  PCHAR Buffer;
   5.826 +  size_t BufLen;
   5.827 +  KIRQL OldIrql;
   5.828 +
   5.829 +  UNREFERENCED_PARAMETER(Queue);
   5.830 +  UNREFERENCED_PARAMETER(Length);
   5.831 +
   5.832 +  KdPrint((__DRIVER_NAME " --> IoRead\n"));
   5.833 +
   5.834 +  WdfRequestRetrieveOutputBuffer(Request, 1, &Buffer, &BufLen);
   5.835 +
   5.836 +  KeAcquireSpinLock(&ShutdownMsgLock, &OldIrql);
   5.837 +
   5.838 +  Entry = (PSHUTDOWN_MSG_ENTRY)RemoveHeadList(&ShutdownMsgList);
   5.839 +
   5.840 +  if ((PLIST_ENTRY)Entry == &ShutdownMsgList)
   5.841 +  {
   5.842 +    KdPrint((__DRIVER_NAME " <-- IoRead (Nothing in queue... xenpci is now broken)\n"));
   5.843 +    return;
   5.844 +  }
   5.845 +
   5.846 +  Remaining = strlen(Entry->Buf + Entry->Ptr);
   5.847 +  CopyLen = min(Remaining, BufLen);
   5.848 +
   5.849 +  memcpy(Buffer, Entry->Buf + Entry->Ptr, CopyLen);
   5.850 +
   5.851 +  if (Entry->Buf[Entry->Ptr] == 0)
   5.852 +  {
   5.853 +    KdPrint((__DRIVER_NAME "     All done... stopping queue\n"));
   5.854 +    if (IsListEmpty(&ShutdownMsgList))
   5.855 +      WdfIoQueueStop(ReadQueue, NULL, NULL);
   5.856 +  }
   5.857 +  else
   5.858 +  {    
   5.859 +    KdPrint((__DRIVER_NAME "     More to do...\n"));
   5.860 +    Entry->Ptr += (ULONG)CopyLen;
   5.861 +    InsertHeadList(&ShutdownMsgList, &Entry->ListEntry);
   5.862 +  }
   5.863 +
   5.864 +  KeReleaseSpinLock(&ShutdownMsgLock, OldIrql);
   5.865 +
   5.866 +  WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, CopyLen);
   5.867 +
   5.868 +  KdPrint((__DRIVER_NAME " <-- IoRead\n"));
   5.869 +}
   5.870 +
   5.871 +
   5.872 +static NTSTATUS
   5.873 +XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
   5.874 +{
   5.875 +  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(AssociatedDevice);
   5.876 +
   5.877 +  UNREFERENCED_PARAMETER(Interrupt);
   5.878 +
   5.879 +  KdPrint((__DRIVER_NAME " --> EvtInterruptEnable\n"));
   5.880 +
   5.881 +  xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_mask = 0;
   5.882 +
   5.883 +  KdPrint((__DRIVER_NAME " <-- EvtInterruptEnable\n"));
   5.884 +
   5.885 +  return STATUS_SUCCESS;
   5.886 +}
   5.887 +
   5.888 +static NTSTATUS
   5.889 +XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
   5.890 +{
   5.891 +  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(AssociatedDevice);
   5.892 +
   5.893 +  UNREFERENCED_PARAMETER(Interrupt);
   5.894 +
   5.895 +  //KdPrint((__DRIVER_NAME " --> EvtInterruptDisable\n"));
   5.896 +
   5.897 +  xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_mask = 1;
   5.898 +  // should we kick off any pending interrupts here?
   5.899 +
   5.900 +  //KdPrint((__DRIVER_NAME " <-- EvtInterruptDisable\n"));
   5.901 +
   5.902 +  return STATUS_SUCCESS;
   5.903 +}
   5.904 +
   5.905 +static NTSTATUS
   5.906 +XenPCI_ChildListCreateDevice(
   5.907 +  WDFCHILDLIST ChildList,
   5.908 +  PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription,
   5.909 +  PWDFDEVICE_INIT ChildInit)
   5.910 +{
   5.911 +  NTSTATUS status;
   5.912 +  WDFDEVICE ChildDevice = NULL;
   5.913 +  PXENPCI_IDENTIFICATION_DESCRIPTION XenIdentificationDesc;
   5.914 +  DECLARE_UNICODE_STRING_SIZE(buffer, 20);
   5.915 +  WDF_OBJECT_ATTRIBUTES PdoAttributes;
   5.916 +  DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
   5.917 +  WDF_QUERY_INTERFACE_CONFIG  qiConfig;
   5.918 +  PXENPCI_XEN_DEVICE_DATA ChildDeviceData = NULL;
   5.919 +  UNICODE_STRING DeviceType;
   5.920 +  ANSI_STRING AnsiBuf;
   5.921 +
   5.922 +  UNREFERENCED_PARAMETER(ChildList);
   5.923 +
   5.924 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.925 +
   5.926 +  XenIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENPCI_IDENTIFICATION_DESCRIPTION, Header);
   5.927 +
   5.928 +  RtlInitAnsiString(&AnsiBuf, XenIdentificationDesc->DeviceType);
   5.929 +  RtlAnsiStringToUnicodeString(&DeviceType, &AnsiBuf, TRUE);
   5.930 +
   5.931 +  KdPrint((__DRIVER_NAME "     Type = %s\n", XenIdentificationDesc->DeviceType));
   5.932 +
   5.933 +  //DeviceInit = WdfPdoInitAllocate(Device);
   5.934 +  WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_CONTROLLER);
   5.935 +
   5.936 +  status = RtlUnicodeStringPrintf(&buffer, L"Xen\\%wZ\0", &DeviceType);
   5.937 +  status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
   5.938 +  status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
   5.939 +  status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
   5.940 +
   5.941 +  status = RtlUnicodeStringPrintf(&buffer, L"%02d", 0);
   5.942 +  status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
   5.943 +
   5.944 +  status = RtlUnicodeStringPrintf(&buffer, L"%wZ", &DeviceType);
   5.945 +  status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
   5.946 +
   5.947 +  WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
   5.948 +  
   5.949 +  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&PdoAttributes, XENPCI_XEN_DEVICE_DATA);
   5.950 +
   5.951 +//  WDF_PDO_EVENT_CALLBACKS_INIT(&PdoCallbacks);
   5.952 +//  PdoCallbacks.EvtDeviceResourceRequirementsQuery = XenPCI_DeviceResourceRequirementsQuery;
   5.953 +//  WdfPdoInitSetEventCallbacks(ChildInit, &PdoCallbacks);
   5.954 +
   5.955 +  status = WdfDeviceCreate(&ChildInit, &PdoAttributes, &ChildDevice);
   5.956 +  if (!NT_SUCCESS(status))
   5.957 +  {
   5.958 +    KdPrint((__DRIVER_NAME "     WdfDeviceCreate status = %08X\n", status));
   5.959 +  }
   5.960 +
   5.961 +  WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFilePaging, TRUE);
   5.962 +  WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileHibernation, TRUE);
   5.963 +  WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileDump, TRUE);
   5.964 +
   5.965 +  ChildDeviceData = GetXenDeviceData(ChildDevice);
   5.966 +  ChildDeviceData->Magic = XEN_DATA_MAGIC;
   5.967 +  ChildDeviceData->AutoEnumerate = AutoEnumerate;
   5.968 +  ChildDeviceData->WatchHandler = NULL;
   5.969 +  strncpy(ChildDeviceData->Path, XenIdentificationDesc->Path, 128);
   5.970 +  ChildDeviceData->DeviceIndex = XenIdentificationDesc->DeviceIndex;
   5.971 +  memcpy(&ChildDeviceData->InterruptRaw, &InterruptRaw, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
   5.972 +  memcpy(&ChildDeviceData->InterruptTranslated, &InterruptTranslated, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
   5.973 +  
   5.974 +  ChildDeviceData->XenInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->XenInterface);
   5.975 +  ChildDeviceData->XenInterface.InterfaceHeader.Version = 2;
   5.976 +  ChildDeviceData->XenInterface.InterfaceHeader.Context = WdfPdoGetParent(ChildDevice);
   5.977 +  ChildDeviceData->XenInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
   5.978 +  ChildDeviceData->XenInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
   5.979 +
   5.980 +  ChildDeviceData->XenInterface.AllocMMIO = XenPci_AllocMMIO;
   5.981 +  ChildDeviceData->XenInterface.FreeMem = XenPCI_FreeMem;
   5.982 +
   5.983 +  ChildDeviceData->XenInterface.EvtChn_Bind = EvtChn_Bind;
   5.984 +  ChildDeviceData->XenInterface.EvtChn_Unbind = EvtChn_Unbind;
   5.985 +  ChildDeviceData->XenInterface.EvtChn_Mask = EvtChn_Mask;
   5.986 +  ChildDeviceData->XenInterface.EvtChn_Unmask = EvtChn_Unmask;
   5.987 +  ChildDeviceData->XenInterface.EvtChn_Notify = EvtChn_Notify;
   5.988 +  ChildDeviceData->XenInterface.EvtChn_AllocUnbound = EvtChn_AllocUnbound;
   5.989 +  ChildDeviceData->XenInterface.EvtChn_BindDpc = EvtChn_BindDpc;
   5.990 +
   5.991 +  ChildDeviceData->XenInterface.GntTbl_GetRef = GntTbl_GetRef;
   5.992 +  ChildDeviceData->XenInterface.GntTbl_PutRef = GntTbl_PutRef;
   5.993 +  ChildDeviceData->XenInterface.GntTbl_GrantAccess = GntTbl_GrantAccess;
   5.994 +  ChildDeviceData->XenInterface.GntTbl_EndAccess = GntTbl_EndAccess;
   5.995 +
   5.996 +  ChildDeviceData->XenInterface.XenBus_Read = XenBus_Read;
   5.997 +  ChildDeviceData->XenInterface.XenBus_Write = XenBus_Write;
   5.998 +  ChildDeviceData->XenInterface.XenBus_Printf = XenBus_Printf;
   5.999 +  ChildDeviceData->XenInterface.XenBus_StartTransaction = XenBus_StartTransaction;
  5.1000 +  ChildDeviceData->XenInterface.XenBus_EndTransaction = XenBus_EndTransaction;
  5.1001 +  ChildDeviceData->XenInterface.XenBus_List = XenBus_List;
  5.1002 +  ChildDeviceData->XenInterface.XenBus_AddWatch = XenBus_AddWatch;
  5.1003 +  ChildDeviceData->XenInterface.XenBus_RemWatch = XenBus_RemWatch;
  5.1004 +
  5.1005 +  WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->XenInterface, &GUID_XEN_IFACE, NULL);
  5.1006 +  status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
  5.1007 +  if (!NT_SUCCESS(status)) {
  5.1008 +    return status;
  5.1009 +  }
  5.1010 +
  5.1011 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  5.1012 +
  5.1013 +  return status;
  5.1014 +}
  5.1015 +
  5.1016 +struct {
  5.1017 +  ULONG do_spin;
  5.1018 +  ULONG nr_spinning;
  5.1019 +} typedef SUSPEND_INFO, *PSUSPEND_INFO;
  5.1020 +
  5.1021 +static VOID
  5.1022 +XenPci_Suspend(
  5.1023 + PRKDPC Dpc,
  5.1024 + PVOID Context,
  5.1025 + PVOID SystemArgument1,
  5.1026 + PVOID SystemArgument2)
  5.1027 +{
  5.1028 +  WDFDEVICE Device = Context;
  5.1029 +//  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
  5.1030 +  PSUSPEND_INFO suspend_info = SystemArgument1;
  5.1031 +  ULONG ActiveProcessorCount;
  5.1032 +  KIRQL OldIrql;
  5.1033 +  int cancelled;
  5.1034 +
  5.1035 +  UNREFERENCED_PARAMETER(Dpc);
  5.1036 +  UNREFERENCED_PARAMETER(SystemArgument2);
  5.1037 +
  5.1038 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (CPU = %d)\n", KeGetCurrentProcessorNumber()));
  5.1039 +  KdPrint((__DRIVER_NAME "     Device = %p\n", Device));
  5.1040 +
  5.1041 +  if (KeGetCurrentProcessorNumber() != 0)
  5.1042 +  {
  5.1043 +    KdPrint((__DRIVER_NAME "     spinning...\n"));
  5.1044 +    InterlockedIncrement((volatile LONG *)&suspend_info->nr_spinning);
  5.1045 +    KeMemoryBarrier();
  5.1046 +    while(suspend_info->do_spin)
  5.1047 +    {
  5.1048 +      /* we should be able to wait more nicely than this... */
  5.1049 +    }
  5.1050 +    KeMemoryBarrier();
  5.1051 +    InterlockedDecrement((volatile LONG *)&suspend_info->nr_spinning);    
  5.1052 +    KdPrint((__DRIVER_NAME "     ...done spinning\n"));
  5.1053 +    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n", KeGetCurrentProcessorNumber()));
  5.1054 +    return;
  5.1055 +  }
  5.1056 +  ActiveProcessorCount = (ULONG)KeNumberProcessors;
  5.1057 +
  5.1058 +  KdPrint((__DRIVER_NAME "     waiting for all other processors to spin\n"));
  5.1059 +  while (suspend_info->nr_spinning < ActiveProcessorCount - 1)
  5.1060 +  {
  5.1061 +      /* we should be able to wait more nicely than this... */
  5.1062 +  }
  5.1063 +  KdPrint((__DRIVER_NAME "     all other processors are spinning\n"));
  5.1064 +
  5.1065 +  KeRaiseIrql(HIGH_LEVEL, &OldIrql);
  5.1066 +  KdPrint((__DRIVER_NAME "     calling suspend\n"));
  5.1067 +  cancelled = HYPERVISOR_shutdown(Device, SHUTDOWN_suspend);
  5.1068 +  KdPrint((__DRIVER_NAME "     back from suspend, cancelled = %d\n", cancelled));
  5.1069 +  KeLowerIrql(OldIrql);
  5.1070 +
  5.1071 +  KdPrint((__DRIVER_NAME "     waiting for all other processors to stop spinning\n"));
  5.1072 +  suspend_info->do_spin = 0;
  5.1073 +  while (suspend_info->nr_spinning != 0)
  5.1074 +  {
  5.1075 +      /* we should be able to wait more nicely than this... */
  5.1076 +  }
  5.1077 +  KdPrint((__DRIVER_NAME "     all other processors have stopped spinning\n"));
  5.1078 +
  5.1079 +  // TODO: Enable xenbus
  5.1080 +  // TODO: Enable our IRQ
  5.1081 +
  5.1082 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n", KeGetCurrentProcessorNumber()));
  5.1083 +}
  5.1084 +
  5.1085 +static VOID
  5.1086 +XenPci_BeginSuspend(WDFDEVICE Device)
  5.1087 +{
  5.1088 +  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
  5.1089 +//  KAFFINITY ActiveProcessorMask = 0;
  5.1090 +  ULONG ActiveProcessorCount;
  5.1091 +  ULONG i;
  5.1092 +  PSUSPEND_INFO suspend_info;
  5.1093 +  PKDPC Dpc;
  5.1094 +  KIRQL OldIrql;
  5.1095 +
  5.1096 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  5.1097 +  KdPrint((__DRIVER_NAME "     Device = %p\n", Device));
  5.1098 +
  5.1099 +  if (!xpdd->suspending)
  5.1100 +  {
  5.1101 +    xpdd->suspending = 1;
  5.1102 +    suspend_info = ExAllocatePoolWithTag(NonPagedPool, sizeof(SUSPEND_INFO), XENPCI_POOL_TAG);
  5.1103 +    suspend_info->do_spin = 1;
  5.1104 +    RtlZeroMemory(suspend_info, sizeof(SUSPEND_INFO));
  5.1105 +    // TODO: Disable xenbus
  5.1106 +    // TODO: Disable our IRQ
  5.1107 +    //ActiveProcessorCount = KeQueryActiveProcessorCount(&ActiveProcessorMask);
  5.1108 +    ActiveProcessorCount = (ULONG)KeNumberProcessors;
  5.1109 +    KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
  5.1110 +    for (i = 0; i < ActiveProcessorCount; i++)
  5.1111 +    {
  5.1112 +      Dpc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KDPC), XENPCI_POOL_TAG);
  5.1113 +      KeInitializeDpc(Dpc, XenPci_Suspend, Device);
  5.1114 +      KeSetTargetProcessorDpc(Dpc, (CCHAR)i);
  5.1115 +      KeInsertQueueDpc(Dpc, suspend_info, NULL);
  5.1116 +    }
  5.1117 +    KeLowerIrql(OldIrql);
  5.1118 +  }
  5.1119 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  5.1120 +}
  5.1121 +
  5.1122 +static void
  5.1123 +XenBus_ShutdownHandler(char *Path, PVOID Data)
  5.1124 +{
  5.1125 +  WDFDEVICE Device = Data;  
  5.1126 +  char *res;
  5.1127 +  char *Value;
  5.1128 +  xenbus_transaction_t xbt;
  5.1129 +  int retry;
  5.1130 +  PSHUTDOWN_MSG_ENTRY Entry;
  5.1131 +
  5.1132 +  UNREFERENCED_PARAMETER(Path);
  5.1133 +
  5.1134 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  5.1135 +  KdPrint((__DRIVER_NAME "     Device = %p\n", Device));
  5.1136 +
  5.1137 +  res = XenBus_StartTransaction(Device, &xbt);
  5.1138 +  if (res)
  5.1139 +  {
  5.1140 +    KdPrint(("Error starting transaction\n"));
  5.1141 +    XenPCI_FreeMem(res);
  5.1142 +    return;
  5.1143 +  }
  5.1144 +
  5.1145 +  res = XenBus_Read(Device, XBT_NIL, SHUTDOWN_PATH, &Value);
  5.1146 +  if (res)
  5.1147 +  {
  5.1148 +    KdPrint(("Error reading shutdown path\n"));
  5.1149 +    XenPCI_FreeMem(res);
  5.1150 +    XenBus_EndTransaction(Device, xbt, 1, &retry);
  5.1151 +    return;
  5.1152 +  }
  5.1153 +
  5.1154 +  if (Value != NULL && strlen(Value) != 0)
  5.1155 +  {
  5.1156 +    res = XenBus_Write(Device, XBT_NIL, SHUTDOWN_PATH, "");
  5.1157 +    if (res)
  5.1158 +    {
  5.1159 +      KdPrint(("Error writing shutdown path\n"));
  5.1160 +      XenPCI_FreeMem(res);
  5.1161 +      // end trans?
  5.1162 +      return;
  5.1163 +    }
  5.1164 +  } 
  5.1165 +
  5.1166 +  if (Value != NULL)
  5.1167 +  {
  5.1168 +    KdPrint((__DRIVER_NAME "     Shutdown Value = %s\n", Value));
  5.1169 +    KdPrint((__DRIVER_NAME "     strlen(...) = %d\n", strlen(Value)));
  5.1170 +  }
  5.1171 +  else
  5.1172 +  {
  5.1173 +    KdPrint((__DRIVER_NAME "     Shutdown Value = <null>\n"));
  5.1174 +  }
  5.1175 +
  5.1176 +  res = XenBus_EndTransaction(Device, xbt, 0, &retry);
  5.1177 +  if (res)
  5.1178 +  {
  5.1179 +    KdPrint(("Error ending transaction\n"));
  5.1180 +    XenPCI_FreeMem(res);
  5.1181 +    return;
  5.1182 +  }
  5.1183 +
  5.1184 +  if (Value != NULL && strlen(Value) != 0)
  5.1185 +  {
  5.1186 +    if (strcmp(Value, "suspend") == 0)
  5.1187 +    {
  5.1188 +      KdPrint((__DRIVER_NAME "     Suspend detected\n"));
  5.1189 +      XenPci_BeginSuspend(Device);
  5.1190 +    }
  5.1191 +    else
  5.1192 +    {
  5.1193 +      Entry = (PSHUTDOWN_MSG_ENTRY)ExAllocatePoolWithTag(NonPagedPool, sizeof(SHUTDOWN_MSG_ENTRY) + strlen(Value) + 1 + 1, XENPCI_POOL_TAG);
  5.1194 +      Entry->Ptr = 0;
  5.1195 +      RtlStringCbPrintfA(Entry->Buf, sizeof(SHUTDOWN_MSG_ENTRY) + strlen(Value) + 1 + 1, "%s\n", Value);
  5.1196 +      InsertTailList(&ShutdownMsgList, &Entry->ListEntry);
  5.1197 +      WdfIoQueueStart(ReadQueue);
  5.1198 +    }
  5.1199 +  }
  5.1200 +
  5.1201 +  XenPCI_FreeMem(Value);
  5.1202 +
  5.1203 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  5.1204 +}
  5.1205 +
  5.1206 +static VOID
  5.1207 +XenBus_BalloonHandler(char *Path, PVOID Data)
  5.1208 +{
  5.1209 +  WDFDEVICE Device = Data;
  5.1210 +  char *value;
  5.1211 +  xenbus_transaction_t xbt;
  5.1212 +  int retry;
  5.1213 +
  5.1214 +  UNREFERENCED_PARAMETER(Path);
  5.1215 +
  5.1216 +  KdPrint((__DRIVER_NAME " --> XenBus_BalloonHandler\n"));
  5.1217 +
  5.1218 +  XenBus_StartTransaction(Device, &xbt);
  5.1219 +
  5.1220 +  XenBus_Read(Device, XBT_NIL, BALLOON_PATH, &value);
  5.1221 +
  5.1222 +  KdPrint((__DRIVER_NAME "     Balloon Value = %s\n", value));
  5.1223 +
  5.1224 +  // use the memory_op(unsigned int op, void *arg) hypercall to adjust this
  5.1225 +  // use XENMEM_increase_reservation and XENMEM_decrease_reservation
  5.1226 +
  5.1227 +  XenBus_EndTransaction(Device, xbt, 0, &retry);
  5.1228 +
  5.1229 +  XenPCI_FreeMem(value);
  5.1230 +
  5.1231 +  KdPrint((__DRIVER_NAME " <-- XenBus_BalloonHandler\n"));
  5.1232 +}
  5.1233 +
  5.1234 +static VOID
  5.1235 +XenBus_SysrqHandler(char *Path, PVOID Data)
  5.1236 +{
  5.1237 +  WDFDEVICE Device = Data;
  5.1238 +  char *Value;
  5.1239 +  xenbus_transaction_t xbt;
  5.1240 +  int retry;
  5.1241 +  char letter;
  5.1242 +  char *res;
  5.1243 +
  5.1244 +  UNREFERENCED_PARAMETER(Path);
  5.1245 +
  5.1246 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  5.1247 +
  5.1248 +  XenBus_StartTransaction(Device, &xbt);
  5.1249 +
  5.1250 +  XenBus_Read(Device, XBT_NIL, SYSRQ_PATH, &Value);
  5.1251 +
  5.1252 +  KdPrint((__DRIVER_NAME "     SysRq Value = %s\n", Value));
  5.1253 +
  5.1254 +  if (Value != NULL && strlen(Value) != 0)
  5.1255 +  {
  5.1256 +    letter = *Value;
  5.1257 +    res = XenBus_Write(Device, XBT_NIL, SYSRQ_PATH, "");
  5.1258 +    if (res)
  5.1259 +    {
  5.1260 +      KdPrint(("Error writing sysrq path\n"));
  5.1261 +      XenPCI_FreeMem(res);
  5.1262 +      XenBus_EndTransaction(Device, xbt, 0, &retry);
  5.1263 +      return;
  5.1264 +    }
  5.1265 +  }
  5.1266 +  else
  5.1267 +  {
  5.1268 +    letter = 0;
  5.1269 +  }
  5.1270 +
  5.1271 +  XenBus_EndTransaction(Device, xbt, 0, &retry);
  5.1272 +
  5.1273 +  if (Value != NULL)
  5.1274 +  {
  5.1275 +    XenPCI_FreeMem(Value);
  5.1276 +  }
  5.1277 +
  5.1278 +  switch (letter)
  5.1279 +  {
  5.1280 +  case 'B':
  5.1281 +    KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000001, 0x00000000, 0x00000000, 0x00000000);
  5.1282 +    break;
  5.1283 +  default:
  5.1284 +    KdPrint(("     Unhandled sysrq letter %c\n", letter));
  5.1285 +    break;
  5.1286 +  }
  5.1287 +
  5.1288 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  5.1289 +}
  5.1290 +
  5.1291 +static NTSTATUS
  5.1292 +XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList)
  5.1293 +{
  5.1294 +  NTSTATUS  status;
  5.1295 +  WDFIORESLIST resourceList;
  5.1296 +  IO_RESOURCE_DESCRIPTOR descriptor;
  5.1297 +  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
  5.1298 +
  5.1299 +  //KdPrint((__DRIVER_NAME " --> DeviceResourceRequirementsQuery\n"));
  5.1300 +
  5.1301 +  status = WdfIoResourceListCreate(IoResourceRequirementsList, WDF_NO_OBJECT_ATTRIBUTES, &resourceList);
  5.1302 +  if (!NT_SUCCESS(status))
  5.1303 +    return status;
  5.1304 +
  5.1305 +  RtlZeroMemory(&descriptor, sizeof(descriptor));
  5.1306 +
  5.1307 +  descriptor.Option = 0;
  5.1308 +  descriptor.Type = CmResourceTypeMemory;
  5.1309 +  descriptor.ShareDisposition = CmResourceShareShared; //CmResourceShareDeviceExclusive;
  5.1310 +  descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
  5.1311 +  descriptor.u.Memory.Length = PAGE_SIZE;
  5.1312 +  descriptor.u.Memory.Alignment = PAGE_SIZE;
  5.1313 +  descriptor.u.Memory.MinimumAddress.QuadPart
  5.1314 +    = xpdd->platform_mmio_addr.QuadPart + PAGE_SIZE;
  5.1315 +  descriptor.u.Memory.MaximumAddress.QuadPart
  5.1316 +    = xpdd->platform_mmio_addr.QuadPart + xpdd->platform_mmio_len - 1;
  5.1317 +
  5.1318 +  //KdPrint((__DRIVER_NAME "     MinimumAddress = %08x, MaximumAddress = %08X\n", descriptor.u.Memory.MinimumAddress.LowPart, descriptor.u.Memory.MaximumAddress.LowPart));
  5.1319 +
  5.1320 +  status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
  5.1321 +  if (!NT_SUCCESS(status))
  5.1322 +    return status;
  5.1323 +
  5.1324 +  status = WdfIoResourceRequirementsListAppendIoResList(IoResourceRequirementsList, resourceList);
  5.1325 +  if (!NT_SUCCESS(status))
  5.1326 +    return status;
  5.1327 +
  5.1328 +  //KdPrint((__DRIVER_NAME " <-- DeviceResourceRequirementsQuery\n"));
  5.1329 +
  5.1330 +  return status;
  5.1331 +}
  5.1332 +#endif
  5.1333 \ No newline at end of file
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/xenpci/xenpci_pdo.c	Sun May 04 16:40:30 2008 +1000
     6.3 @@ -0,0 +1,202 @@
     6.4 +/*
     6.5 +PV Drivers for Windows Xen HVM Domains
     6.6 +Copyright (C) 2007 James Harper
     6.7 +
     6.8 +This program is free software; you can redistribute it and/or
     6.9 +modify it under the terms of the GNU General Public License
    6.10 +as published by the Free Software Foundation; either version 2
    6.11 +of the License, or (at your option) any later version.
    6.12 +
    6.13 +This program is distributed in the hope that it will be useful,
    6.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.16 +GNU General Public License for more details.
    6.17 +
    6.18 +You should have received a copy of the GNU General Public License
    6.19 +along with this program; if not, write to the Free Software
    6.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    6.21 +*/
    6.22 +
    6.23 +#include "xenpci.h"
    6.24 +#include <stdlib.h>
    6.25 +
    6.26 +#pragma warning(disable : 4200) // zero-sized array
    6.27 +
    6.28 +NTSTATUS
    6.29 +XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
    6.30 +{
    6.31 +  UNREFERENCED_PARAMETER(device_object);
    6.32 +  
    6.33 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    6.34 +
    6.35 +  irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
    6.36 +  IoCompleteRequest(irp, IO_NO_INCREMENT);
    6.37 +  
    6.38 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    6.39 +
    6.40 +  return irp->IoStatus.Status;
    6.41 +}
    6.42 +
    6.43 +NTSTATUS
    6.44 +XenPci_Pnp_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
    6.45 +{
    6.46 +  NTSTATUS status;
    6.47 +  PIO_STACK_LOCATION stack;
    6.48 +  PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
    6.49 +  LPWSTR buffer;
    6.50 +  WCHAR widebuf[256];
    6.51 +  unsigned int i;
    6.52 +
    6.53 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    6.54 +
    6.55 +  stack = IoGetCurrentIrpStackLocation(irp);
    6.56 +
    6.57 +  switch (stack->MinorFunction)
    6.58 +  {
    6.59 +  case IRP_MN_START_DEVICE:
    6.60 +    KdPrint((__DRIVER_NAME "     IRP_MN_START_DEVICE\n"));
    6.61 +    status = STATUS_SUCCESS;
    6.62 +    break;
    6.63 +    
    6.64 +  case IRP_MN_QUERY_STOP_DEVICE:
    6.65 +    KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_STOP_DEVICE\n"));
    6.66 +    status = STATUS_SUCCESS;
    6.67 +    break;
    6.68 +
    6.69 +  case IRP_MN_STOP_DEVICE:
    6.70 +    KdPrint((__DRIVER_NAME "     IRP_MN_STOP_DEVICE\n"));
    6.71 +    status = STATUS_SUCCESS;
    6.72 +    break;
    6.73 +
    6.74 +  case IRP_MN_CANCEL_STOP_DEVICE:
    6.75 +    KdPrint((__DRIVER_NAME "     IRP_MN_CANCEL_STOP_DEVICE\n"));
    6.76 +    status = STATUS_SUCCESS;
    6.77 +    break;
    6.78 +
    6.79 +  case IRP_MN_QUERY_REMOVE_DEVICE:
    6.80 +    KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_REMOVE_DEVICE\n"));
    6.81 +    status = STATUS_SUCCESS;
    6.82 +    break;
    6.83 +
    6.84 +  case IRP_MN_REMOVE_DEVICE:
    6.85 +    KdPrint((__DRIVER_NAME "     IRP_MN_REMOVE_DEVICE\n"));
    6.86 +    status = STATUS_SUCCESS;
    6.87 +    break;
    6.88 +
    6.89 +  case IRP_MN_CANCEL_REMOVE_DEVICE:
    6.90 +    KdPrint((__DRIVER_NAME "     IRP_MN_CANCEL_REMOVE_DEVICE\n"));
    6.91 +    status = STATUS_SUCCESS;
    6.92 +    break;
    6.93 +
    6.94 +  case IRP_MN_SURPRISE_REMOVAL:
    6.95 +    KdPrint((__DRIVER_NAME "     IRP_MN_SURPRISE_REMOVAL\n"));
    6.96 +    status = STATUS_SUCCESS;
    6.97 +    break;
    6.98 +
    6.99 +  case IRP_MN_DEVICE_USAGE_NOTIFICATION:
   6.100 +    KdPrint((__DRIVER_NAME "     IRP_MN_DEVICE_USAGE_NOTIFICATION\n"));
   6.101 +    status = STATUS_SUCCESS;
   6.102 +    break;
   6.103 +
   6.104 +  case IRP_MN_QUERY_DEVICE_RELATIONS:
   6.105 +    KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_DEVICE_RELATIONS\n"));
   6.106 +    status = STATUS_NOT_SUPPORTED;
   6.107 +    break;
   6.108 +
   6.109 +  case IRP_MN_QUERY_ID:
   6.110 +    KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_ID\n"));
   6.111 +    switch (stack->Parameters.QueryId.IdType)
   6.112 +    {
   6.113 +    case BusQueryDeviceID: /* REG_SZ */
   6.114 +      KdPrint((__DRIVER_NAME "     BusQueryDeviceID\n"));
   6.115 +      buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
   6.116 +      for (i = 0; i < strlen(xppdd->path); i++)
   6.117 +        widebuf[i] = xppdd->path[i];
   6.118 +      widebuf[i] = 0;
   6.119 +      RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws\0", widebuf);
   6.120 +      KdPrint((__DRIVER_NAME "     %ls\n", buffer));
   6.121 +      irp->IoStatus.Information = (ULONG_PTR)buffer;
   6.122 +      status = STATUS_SUCCESS;
   6.123 +      break;
   6.124 +    case BusQueryHardwareIDs: /* REG_MULTI_SZ */
   6.125 +      KdPrint((__DRIVER_NAME "     BusQueryHardwareIDs\n"));
   6.126 +      buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
   6.127 +      for (i = 0; i < strlen(xppdd->path); i++)
   6.128 +        widebuf[i] = xppdd->path[i];
   6.129 +      widebuf[i] = 0;
   6.130 +      RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws\0", widebuf);
   6.131 +      KdPrint((__DRIVER_NAME "     %ls\n", buffer));
   6.132 +      irp->IoStatus.Information = (ULONG_PTR)buffer;
   6.133 +      status = STATUS_SUCCESS;
   6.134 +      break;
   6.135 +    case BusQueryCompatibleIDs: /* REG_MULTI_SZ */
   6.136 +      KdPrint((__DRIVER_NAME "     BusQueryCompatibleIDs\n"));
   6.137 +      buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
   6.138 +      for (i = 0; i < strlen(xppdd->path); i++)
   6.139 +        widebuf[i] = xppdd->path[i];
   6.140 +      widebuf[i] = 0;
   6.141 +      RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws\0", widebuf);
   6.142 +      KdPrint((__DRIVER_NAME "     %ls\n", buffer));
   6.143 +      irp->IoStatus.Information = (ULONG_PTR)buffer;
   6.144 +      status = STATUS_SUCCESS;
   6.145 +      break;
   6.146 +    case BusQueryInstanceID: /* REG_SZ */
   6.147 +      KdPrint((__DRIVER_NAME "     BusQueryInstanceID\n"));
   6.148 +      buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
   6.149 +      RtlStringCbPrintfW(buffer, 512, L"%02d", xppdd->index);
   6.150 +      KdPrint((__DRIVER_NAME "     %ls\n", buffer));
   6.151 +      irp->IoStatus.Information = (ULONG_PTR)buffer;
   6.152 +      status = STATUS_SUCCESS;
   6.153 +      break;
   6.154 +    default:
   6.155 +      KdPrint((__DRIVER_NAME "     Unhandled IdType = %d\n", stack->Parameters.QueryId.IdType));
   6.156 +      irp->IoStatus.Information = 0;
   6.157 +      status = STATUS_NOT_SUPPORTED;
   6.158 +      break;
   6.159 +    }
   6.160 +    break;
   6.161 +    
   6.162 +  case IRP_MN_QUERY_DEVICE_TEXT:
   6.163 +    KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_DEVICE_TEXT\n"));
   6.164 +    switch (stack->Parameters.QueryDeviceText.DeviceTextType)
   6.165 +    {
   6.166 +    case DeviceTextDescription:
   6.167 +      KdPrint((__DRIVER_NAME "     DeviceTextDescription\n"));
   6.168 +      buffer = ExAllocatePoolWithTag(NonPagedPool, 512, XENPCI_POOL_TAG);
   6.169 +      for (i = 0; i < strlen(xppdd->path); i++)
   6.170 +        widebuf[i] = xppdd->path[i];
   6.171 +      widebuf[i] = 0;
   6.172 +      RtlStringCbPrintfW(buffer, 512, L"Xen %ws device #%d", widebuf, xppdd->index);
   6.173 +      KdPrint((__DRIVER_NAME "     %ls\n", buffer));
   6.174 +      irp->IoStatus.Information = (ULONG_PTR)buffer;
   6.175 +      status = STATUS_SUCCESS;
   6.176 +      break;
   6.177 +    case DeviceTextLocationInformation:
   6.178 +      KdPrint((__DRIVER_NAME "     DeviceTextLocationInformation\n"));
   6.179 +      buffer = ExAllocatePoolWithTag(NonPagedPool, 512, XENPCI_POOL_TAG);
   6.180 +      RtlStringCbPrintfW(buffer, 512, L"Xen Bus");
   6.181 +      KdPrint((__DRIVER_NAME "     %ls\n", buffer));
   6.182 +      irp->IoStatus.Information = (ULONG_PTR)buffer;
   6.183 +      status = STATUS_SUCCESS;
   6.184 +      break;
   6.185 +    default:
   6.186 +      KdPrint((__DRIVER_NAME "     Unhandled IdType = %d\n", stack->Parameters.QueryDeviceText.DeviceTextType));
   6.187 +      irp->IoStatus.Information = 0;
   6.188 +      status = STATUS_NOT_SUPPORTED;
   6.189 +      break;
   6.190 +    }
   6.191 +    break;
   6.192 +
   6.193 +    default:
   6.194 +      KdPrint((__DRIVER_NAME "     Unhandled Minor = %d\n", stack->MinorFunction));
   6.195 +      status = STATUS_NOT_SUPPORTED;
   6.196 +    break;
   6.197 +  }
   6.198 +
   6.199 +  irp->IoStatus.Status = status;
   6.200 +  IoCompleteRequest(irp, IO_NO_INCREMENT);
   6.201 +
   6.202 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   6.203 +
   6.204 +  return status;
   6.205 +}