win-pvdrivers

changeset 279:685399b9adb0 wdm

Converted the suspend code to WDM. Still far from working properly but it's a starting point.
author James Harper <james.harper@bendigoit.com.au>
date Fri May 23 23:53:02 2008 +1000 (2008-05-23)
parents 79d89db3f7ba
children 3ee7c3e5036d
files xenpci/gnttbl.c xenpci/xenbus.c xenpci/xenpci.h xenpci/xenpci_fdo.c xenstub/xenstub.c
line diff
     1.1 --- a/xenpci/gnttbl.c	Fri May 23 22:59:10 2008 +1000
     1.2 +++ b/xenpci/gnttbl.c	Fri May 23 23:53:02 2008 +1000
     1.3 @@ -48,7 +48,7 @@ GntTbl_GetRef(PVOID Context)
     1.4    return ref;
     1.5  }
     1.6  
     1.7 -static int 
     1.8 +int 
     1.9  GntTbl_Map(PVOID Context, unsigned int start_idx, unsigned int end_idx)
    1.10  {
    1.11    PXENPCI_DEVICE_DATA xpdd = Context;
     2.1 --- a/xenpci/xenbus.c	Fri May 23 22:59:10 2008 +1000
     2.2 +++ b/xenpci/xenbus.c	Fri May 23 23:53:02 2008 +1000
     2.3 @@ -565,6 +565,44 @@ KdPrint((__DRIVER_NAME " --- for %s\n", 
     2.4    }
     2.5  }    
     2.6  
     2.7 +static char *
     2.8 +XenBus_SendAddWatch(
     2.9 +  PVOID Context,
    2.10 +  xenbus_transaction_t xbt,
    2.11 +  const char *Path,
    2.12 +  int slot)
    2.13 +{
    2.14 +  PXENPCI_DEVICE_DATA xpdd = Context;
    2.15 +  struct xsd_sockmsg *rep;
    2.16 +  char *msg;
    2.17 +  char Token[20];
    2.18 +  struct write_req req[2];
    2.19 +
    2.20 +  req[0].data = Path;
    2.21 +  req[0].len = (ULONG)strlen(Path) + 1;
    2.22 +
    2.23 +  RtlStringCbPrintfA(Token, ARRAY_SIZE(Token), "%d", slot);
    2.24 +  req[1].data = Token;
    2.25 +  req[1].len = (ULONG)strlen(Token) + 1;
    2.26 +
    2.27 +  rep = xenbus_msg_reply(xpdd, XS_WATCH, xbt, req, ARRAY_SIZE(req));
    2.28 +  msg = errmsg(rep);
    2.29 +
    2.30 +  ExFreePoolWithTag(rep, XENPCI_POOL_TAG);
    2.31 +
    2.32 +  return msg;
    2.33 +}
    2.34 +
    2.35 +VOID
    2.36 +XenBus_Resume(PXENPCI_DEVICE_DATA xpdd)
    2.37 +{
    2.38 +  int i;
    2.39 +  
    2.40 +  for (i = 0; i < MAX_WATCH_ENTRIES; i++)
    2.41 +    if (xpdd->XenBus_WatchEntries[i].Active)
    2.42 +      XenBus_SendAddWatch(xpdd, XBT_NIL, xpdd->XenBus_WatchEntries[i].Path, i);
    2.43 +}
    2.44 +
    2.45  char *
    2.46  XenBus_AddWatch(
    2.47    PVOID Context,
    2.48 @@ -574,11 +612,8 @@ XenBus_AddWatch(
    2.49    PVOID ServiceContext)
    2.50  {
    2.51    PXENPCI_DEVICE_DATA xpdd = Context;
    2.52 -  struct xsd_sockmsg *rep;
    2.53    char *msg;
    2.54    int i;
    2.55 -  char Token[20];
    2.56 -  struct write_req req[2];
    2.57    PXENBUS_WATCH_ENTRY w_entry;
    2.58    KIRQL OldIrql;
    2.59  
    2.60 @@ -612,23 +647,14 @@ XenBus_AddWatch(
    2.61  
    2.62    KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
    2.63  
    2.64 -  req[0].data = Path;
    2.65 -  req[0].len = (ULONG)strlen(Path) + 1;
    2.66 +  msg = XenBus_SendAddWatch(xpdd, xbt, Path, i);
    2.67  
    2.68 -  RtlStringCbPrintfA(Token, ARRAY_SIZE(Token), "%d", i);
    2.69 -  req[1].data = Token;
    2.70 -  req[1].len = (ULONG)strlen(Token) + 1;
    2.71 -
    2.72 -  rep = xenbus_msg_reply(xpdd, XS_WATCH, xbt, req, ARRAY_SIZE(req));
    2.73 -
    2.74 -  msg = errmsg(rep);
    2.75    if (msg)
    2.76    {
    2.77      xpdd->XenBus_WatchEntries[i].Active = 0;
    2.78      KdPrint((__DRIVER_NAME " <-- XenBus_AddWatch (%s)\n", msg));
    2.79      return msg;
    2.80    }
    2.81 -  ExFreePoolWithTag(rep, XENPCI_POOL_TAG);
    2.82  
    2.83    KdPrint((__DRIVER_NAME " <-- XenBus_AddWatch\n"));
    2.84  
     3.1 --- a/xenpci/xenpci.h	Fri May 23 22:59:10 2008 +1000
     3.2 +++ b/xenpci/xenpci.h	Fri May 23 23:53:02 2008 +1000
     3.3 @@ -324,8 +324,8 @@ char *
     3.4  XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, const char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
     3.5  char *
     3.6  XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, const char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
     3.7 -VOID
     3.8 -XenBus_ThreadProc(PVOID StartContext);
     3.9 +//VOID
    3.10 +//XenBus_ThreadProc(PVOID StartContext);
    3.11  NTSTATUS
    3.12  XenBus_Init(PXENPCI_DEVICE_DATA xpdd);
    3.13  NTSTATUS
    3.14 @@ -334,6 +334,8 @@ NTSTATUS
    3.15  XenBus_Start(PXENPCI_DEVICE_DATA xpdd);
    3.16  NTSTATUS
    3.17  XenBus_Stop(PXENPCI_DEVICE_DATA xpdd);
    3.18 +VOID
    3.19 +XenBus_Resume(PXENPCI_DEVICE_DATA xpdd);
    3.20  
    3.21  PHYSICAL_ADDRESS
    3.22  XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len);
    3.23 @@ -371,5 +373,6 @@ VOID
    3.24  GntTbl_PutRef(PVOID Context, grant_ref_t ref);
    3.25  grant_ref_t
    3.26  GntTbl_GetRef(PVOID Context);
    3.27 -
    3.28 +int 
    3.29 +GntTbl_Map(PVOID Context, unsigned int start_idx, unsigned int end_idx);
    3.30  #endif
     4.1 --- a/xenpci/xenpci_fdo.c	Fri May 23 22:59:10 2008 +1000
     4.2 +++ b/xenpci/xenpci_fdo.c	Fri May 23 23:53:02 2008 +1000
     4.3 @@ -304,6 +304,122 @@ XenBus_ShutdownIoCancel(PDEVICE_OBJECT d
     4.4    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
     4.5  }
     4.6  
     4.7 +struct {
     4.8 +  ULONG do_spin;
     4.9 +  ULONG nr_spinning;
    4.10 +} typedef SUSPEND_INFO, *PSUSPEND_INFO;
    4.11 +
    4.12 +static VOID
    4.13 +XenPci_Suspend(
    4.14 +  PRKDPC Dpc,
    4.15 +  PVOID Context,
    4.16 +  PVOID SystemArgument1,
    4.17 +  PVOID SystemArgument2)
    4.18 +{
    4.19 +  PXENPCI_DEVICE_DATA xpdd = Context;
    4.20 +  PSUSPEND_INFO suspend_info = SystemArgument1;
    4.21 +  ULONG ActiveProcessorCount;
    4.22 +  KIRQL OldIrql;
    4.23 +  int cancelled;
    4.24 +  int i;
    4.25 +
    4.26 +  UNREFERENCED_PARAMETER(Dpc);
    4.27 +  UNREFERENCED_PARAMETER(SystemArgument2);
    4.28 +
    4.29 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (CPU = %d)\n", KeGetCurrentProcessorNumber()));
    4.30 +
    4.31 +  if (KeGetCurrentProcessorNumber() != 0)
    4.32 +  {
    4.33 +    KdPrint((__DRIVER_NAME "     spinning...\n"));
    4.34 +    InterlockedIncrement((volatile LONG *)&suspend_info->nr_spinning);
    4.35 +    KeMemoryBarrier();
    4.36 +    while(suspend_info->do_spin)
    4.37 +    {
    4.38 +      /* we should be able to wait more nicely than this... */
    4.39 +    }
    4.40 +    KeMemoryBarrier();
    4.41 +    InterlockedDecrement((volatile LONG *)&suspend_info->nr_spinning);    
    4.42 +    KdPrint((__DRIVER_NAME "     ...done spinning\n"));
    4.43 +    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n", KeGetCurrentProcessorNumber()));
    4.44 +    return;
    4.45 +  }
    4.46 +  ActiveProcessorCount = (ULONG)KeNumberProcessors;
    4.47 +
    4.48 +  KdPrint((__DRIVER_NAME "     waiting for all other processors to spin\n"));
    4.49 +  while (suspend_info->nr_spinning < ActiveProcessorCount - 1)
    4.50 +  {
    4.51 +      /* we should be able to wait more nicely than this... */
    4.52 +  }
    4.53 +  KdPrint((__DRIVER_NAME "     all other processors are spinning\n"));
    4.54 +
    4.55 +  KeRaiseIrql(HIGH_LEVEL, &OldIrql);
    4.56 +  KdPrint((__DRIVER_NAME "     calling suspend\n"));
    4.57 +  cancelled = hvm_shutdown(Context, SHUTDOWN_suspend);
    4.58 +  KdPrint((__DRIVER_NAME "     back from suspend, cancelled = %d\n", cancelled));
    4.59 +  KeLowerIrql(OldIrql);
    4.60 +
    4.61 +  KdPrint((__DRIVER_NAME "     waiting for all other processors to stop spinning\n"));
    4.62 +  suspend_info->do_spin = 0;
    4.63 +  while (suspend_info->nr_spinning != 0)
    4.64 +  {
    4.65 +      /* we should be able to wait more nicely than this... */
    4.66 +  }
    4.67 +  KdPrint((__DRIVER_NAME "     all other processors have stopped spinning\n"));
    4.68 +
    4.69 +  for (i = 0; i < MAX_VIRT_CPUS; i++)
    4.70 +  {
    4.71 +    xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 1;
    4.72 +  }
    4.73 +
    4.74 +  GntTbl_Map(Context, 0, NR_GRANT_FRAMES - 1);
    4.75 +  XenBus_Resume(xpdd);
    4.76 +  // TODO: Enable xenbus
    4.77 +  // TODO: Enable all our devices  
    4.78 +
    4.79 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n", KeGetCurrentProcessorNumber()));
    4.80 +}
    4.81 +
    4.82 +static VOID
    4.83 +XenPci_BeginSuspend(PXENPCI_DEVICE_DATA xpdd)
    4.84 +{
    4.85 +  //KAFFINITY ActiveProcessorMask = 0; // this is for Vista+
    4.86 +  ULONG ActiveProcessorCount;
    4.87 +  ULONG i;
    4.88 +  PSUSPEND_INFO suspend_info;
    4.89 +  PKDPC Dpc;
    4.90 +  KIRQL OldIrql;
    4.91 +
    4.92 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    4.93 +
    4.94 +  if (!xpdd->suspending)
    4.95 +  {
    4.96 +    xpdd->suspending = 1;
    4.97 +    suspend_info = ExAllocatePoolWithTag(NonPagedPool, sizeof(SUSPEND_INFO), XENPCI_POOL_TAG);
    4.98 +    suspend_info->do_spin = 1;
    4.99 +    RtlZeroMemory(suspend_info, sizeof(SUSPEND_INFO));
   4.100 +
   4.101 +    // TODO: Disable all our devices  
   4.102 +    // TODO: Disable xenbus
   4.103 +
   4.104 +    for (i = 0; i < MAX_VIRT_CPUS; i++)
   4.105 +    {
   4.106 +      xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 1;
   4.107 +    }
   4.108 +    //ActiveProcessorCount = KeQueryActiveProcessorCount(&ActiveProcessorMask); // this is for Vista+
   4.109 +    ActiveProcessorCount = (ULONG)KeNumberProcessors;
   4.110 +    KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
   4.111 +    for (i = 0; i < ActiveProcessorCount; i++)
   4.112 +    {
   4.113 +      Dpc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KDPC), XENPCI_POOL_TAG);
   4.114 +      KeInitializeDpc(Dpc, XenPci_Suspend, xpdd);
   4.115 +      KeSetTargetProcessorDpc(Dpc, (CCHAR)i);
   4.116 +      KeInsertQueueDpc(Dpc, suspend_info, NULL);
   4.117 +    }
   4.118 +    KeLowerIrql(OldIrql);
   4.119 +  }
   4.120 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   4.121 +}
   4.122 +
   4.123  static void
   4.124  XenBus_ShutdownHandler(char *path, PVOID context)
   4.125  {
   4.126 @@ -331,7 +447,7 @@ XenBus_ShutdownHandler(char *path, PVOID
   4.127      if (strcmp(value, "suspend") == 0)
   4.128      {
   4.129        KdPrint((__DRIVER_NAME "     Suspend detected\n"));
   4.130 -      //XenPci_BeginSuspend(Device);
   4.131 +      XenPci_BeginSuspend(xpdd);
   4.132      }
   4.133      else
   4.134      {
   4.135 @@ -1094,359 +1210,8 @@ XenPCI_D0EntryPostInterruptsEnabled(WDFD
   4.136    return status;
   4.137  }
   4.138  
   4.139 -static NTSTATUS
   4.140 -XenPCI_D0ExitPreInterruptsDisabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
   4.141 -{
   4.142 -  NTSTATUS status = STATUS_SUCCESS;
   4.143 -
   4.144 -  UNREFERENCED_PARAMETER(TargetState);
   4.145 -
   4.146 -  KdPrint((__DRIVER_NAME " --> D0ExitPreInterruptsDisabled\n"));
   4.147 -
   4.148 -  XenBus_Stop(Device);
   4.149 -
   4.150 -  KdPrint((__DRIVER_NAME " <-- D0ExitPreInterruptsDisabled\n"));
   4.151 -
   4.152 -  return status;
   4.153 -}
   4.154 -
   4.155 -static NTSTATUS
   4.156 -XenPCI_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
   4.157 -{
   4.158 -  NTSTATUS status = STATUS_SUCCESS;
   4.159 -
   4.160 -  UNREFERENCED_PARAMETER(Device);
   4.161 -  UNREFERENCED_PARAMETER(TargetState);
   4.162 -
   4.163 -  KdPrint((__DRIVER_NAME " --> DeviceD0Exit\n"));
   4.164 -
   4.165 -  XenBus_Close(Device);
   4.166 -
   4.167 -  KdPrint((__DRIVER_NAME " <-- DeviceD0Exit\n"));
   4.168 -
   4.169 -  return status;
   4.170 -}
   4.171 -
   4.172 -static VOID 
   4.173 -XenPCI_IoDefault(
   4.174 -    IN WDFQUEUE  Queue,
   4.175 -    IN WDFREQUEST  Request
   4.176 -    )
   4.177 -{
   4.178 -  UNREFERENCED_PARAMETER(Queue);
   4.179 -
   4.180 -  KdPrint((__DRIVER_NAME " --> EvtDeviceIoDefault\n"));
   4.181 -
   4.182 -  WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
   4.183 -
   4.184 -  KdPrint((__DRIVER_NAME " <-- EvtDeviceIoDefault\n"));
   4.185 -}
   4.186 -
   4.187 -static VOID 
   4.188 -XenPCI_IoRead(WDFQUEUE Queue, WDFREQUEST Request, size_t Length)
   4.189 -{
   4.190 -  PSHUTDOWN_MSG_ENTRY Entry;
   4.191 -  size_t Remaining;
   4.192 -  size_t CopyLen;
   4.193 -  PCHAR Buffer;
   4.194 -  size_t BufLen;
   4.195 -  KIRQL OldIrql;
   4.196 -
   4.197 -  UNREFERENCED_PARAMETER(Queue);
   4.198 -  UNREFERENCED_PARAMETER(Length);
   4.199 -
   4.200 -  KdPrint((__DRIVER_NAME " --> IoRead\n"));
   4.201 -
   4.202 -  WdfRequestRetrieveOutputBuffer(Request, 1, &Buffer, &BufLen);
   4.203 -
   4.204 -  KeAcquireSpinLock(&ShutdownMsgLock, &OldIrql);
   4.205 -
   4.206 -  Entry = (PSHUTDOWN_MSG_ENTRY)RemoveHeadList(&ShutdownMsgList);
   4.207 -
   4.208 -  if ((PLIST_ENTRY)Entry == &ShutdownMsgList)
   4.209 -  {
   4.210 -    KdPrint((__DRIVER_NAME " <-- IoRead (Nothing in queue... xenpci is now broken)\n"));
   4.211 -    return;
   4.212 -  }
   4.213 -
   4.214 -  Remaining = strlen(Entry->Buf + Entry->Ptr);
   4.215 -  CopyLen = min(Remaining, BufLen);
   4.216 -
   4.217 -  memcpy(Buffer, Entry->Buf + Entry->Ptr, CopyLen);
   4.218 -
   4.219 -  if (Entry->Buf[Entry->Ptr] == 0)
   4.220 -  {
   4.221 -    KdPrint((__DRIVER_NAME "     All done... stopping queue\n"));
   4.222 -    if (IsListEmpty(&ShutdownMsgList))
   4.223 -      WdfIoQueueStop(ReadQueue, NULL, NULL);
   4.224 -  }
   4.225 -  else
   4.226 -  {    
   4.227 -    KdPrint((__DRIVER_NAME "     More to do...\n"));
   4.228 -    Entry->Ptr += (ULONG)CopyLen;
   4.229 -    InsertHeadList(&ShutdownMsgList, &Entry->ListEntry);
   4.230 -  }
   4.231 -
   4.232 -  KeReleaseSpinLock(&ShutdownMsgLock, OldIrql);
   4.233 -
   4.234 -  WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, CopyLen);
   4.235 -
   4.236 -  KdPrint((__DRIVER_NAME " <-- IoRead\n"));
   4.237 -}
   4.238 -
   4.239 -
   4.240 -static NTSTATUS
   4.241 -XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
   4.242 -{
   4.243 -  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(AssociatedDevice);
   4.244 -
   4.245 -  UNREFERENCED_PARAMETER(Interrupt);
   4.246 -
   4.247 -  KdPrint((__DRIVER_NAME " --> EvtInterruptEnable\n"));
   4.248 -
   4.249 -  xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_mask = 0;
   4.250 -
   4.251 -  KdPrint((__DRIVER_NAME " <-- EvtInterruptEnable\n"));
   4.252 -
   4.253 -  return STATUS_SUCCESS;
   4.254 -}
   4.255 -
   4.256 -static NTSTATUS
   4.257 -XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
   4.258 -{
   4.259 -  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(AssociatedDevice);
   4.260 -
   4.261 -  UNREFERENCED_PARAMETER(Interrupt);
   4.262 -
   4.263 -  //KdPrint((__DRIVER_NAME " --> EvtInterruptDisable\n"));
   4.264 -
   4.265 -  xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_mask = 1;
   4.266 -  // should we kick off any pending interrupts here?
   4.267 -
   4.268 -  //KdPrint((__DRIVER_NAME " <-- EvtInterruptDisable\n"));
   4.269 -
   4.270 -  return STATUS_SUCCESS;
   4.271 -}
   4.272 -
   4.273 -static NTSTATUS
   4.274 -XenPCI_ChildListCreateDevice(
   4.275 -  WDFCHILDLIST ChildList,
   4.276 -  PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription,
   4.277 -  PWDFDEVICE_INIT ChildInit)
   4.278 -{
   4.279 -  NTSTATUS status;
   4.280 -  WDFDEVICE ChildDevice = NULL;
   4.281 -  PXENPCI_IDENTIFICATION_DESCRIPTION XenIdentificationDesc;
   4.282 -  DECLARE_UNICODE_STRING_SIZE(buffer, 20);
   4.283 -  WDF_OBJECT_ATTRIBUTES PdoAttributes;
   4.284 -  DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
   4.285 -  WDF_QUERY_INTERFACE_CONFIG  qiConfig;
   4.286 -  PXENPCI_XEN_DEVICE_DATA ChildDeviceData = NULL;
   4.287 -  UNICODE_STRING DeviceType;
   4.288 -  ANSI_STRING AnsiBuf;
   4.289 -
   4.290 -  UNREFERENCED_PARAMETER(ChildList);
   4.291 -
   4.292 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   4.293 -
   4.294 -  XenIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENPCI_IDENTIFICATION_DESCRIPTION, Header);
   4.295 -
   4.296 -  RtlInitAnsiString(&AnsiBuf, XenIdentificationDesc->DeviceType);
   4.297 -  RtlAnsiStringToUnicodeString(&DeviceType, &AnsiBuf, TRUE);
   4.298 -
   4.299 -  KdPrint((__DRIVER_NAME "     Type = %s\n", XenIdentificationDesc->DeviceType));
   4.300 -
   4.301 -  //DeviceInit = WdfPdoInitAllocate(Device);
   4.302 -  WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_CONTROLLER);
   4.303 -
   4.304 -  status = RtlUnicodeStringPrintf(&buffer, L"Xen\\%wZ\0", &DeviceType);
   4.305 -  status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
   4.306 -  status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
   4.307 -  status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
   4.308 -
   4.309 -  status = RtlUnicodeStringPrintf(&buffer, L"%02d", 0);
   4.310 -  status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
   4.311 -
   4.312 -  status = RtlUnicodeStringPrintf(&buffer, L"%wZ", &DeviceType);
   4.313 -  status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
   4.314 -
   4.315 -  WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
   4.316 -  
   4.317 -  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&PdoAttributes, XENPCI_XEN_DEVICE_DATA);
   4.318 -
   4.319 -//  WDF_PDO_EVENT_CALLBACKS_INIT(&PdoCallbacks);
   4.320 -//  PdoCallbacks.EvtDeviceResourceRequirementsQuery = XenPCI_DeviceResourceRequirementsQuery;
   4.321 -//  WdfPdoInitSetEventCallbacks(ChildInit, &PdoCallbacks);
   4.322 -
   4.323 -  status = WdfDeviceCreate(&ChildInit, &PdoAttributes, &ChildDevice);
   4.324 -  if (!NT_SUCCESS(status))
   4.325 -  {
   4.326 -    KdPrint((__DRIVER_NAME "     WdfDeviceCreate status = %08X\n", status));
   4.327 -  }
   4.328 -
   4.329 -  WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFilePaging, TRUE);
   4.330 -  WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileHibernation, TRUE);
   4.331 -  WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileDump, TRUE);
   4.332 -
   4.333 -  ChildDeviceData = GetXenDeviceData(ChildDevice);
   4.334 -  ChildDeviceData->Magic = XEN_DATA_MAGIC;
   4.335 -  ChildDeviceData->AutoEnumerate = AutoEnumerate;
   4.336 -  ChildDeviceData->WatchHandler = NULL;
   4.337 -  strncpy(ChildDeviceData->Path, XenIdentificationDesc->Path, 128);
   4.338 -  ChildDeviceData->DeviceIndex = XenIdentificationDesc->DeviceIndex;
   4.339 -  memcpy(&ChildDeviceData->InterruptRaw, &InterruptRaw, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
   4.340 -  memcpy(&ChildDeviceData->InterruptTranslated, &InterruptTranslated, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
   4.341 -  
   4.342 -  ChildDeviceData->XenInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->XenInterface);
   4.343 -  ChildDeviceData->XenInterface.InterfaceHeader.Version = 2;
   4.344 -  ChildDeviceData->XenInterface.InterfaceHeader.Context = WdfPdoGetParent(ChildDevice);
   4.345 -  ChildDeviceData->XenInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
   4.346 -  ChildDeviceData->XenInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
   4.347 -
   4.348 -  ChildDeviceData->XenInterface.AllocMMIO = XenPci_AllocMMIO;
   4.349 -  ChildDeviceData->XenInterface.FreeMem = XenPci_FreeMem;
   4.350 -
   4.351 -  ChildDeviceData->XenInterface.EvtChn_Bind = EvtChn_Bind;
   4.352 -  ChildDeviceData->XenInterface.EvtChn_Unbind = EvtChn_Unbind;
   4.353 -  ChildDeviceData->XenInterface.EvtChn_Mask = EvtChn_Mask;
   4.354 -  ChildDeviceData->XenInterface.EvtChn_Unmask = EvtChn_Unmask;
   4.355 -  ChildDeviceData->XenInterface.EvtChn_Notify = EvtChn_Notify;
   4.356 -  ChildDeviceData->XenInterface.EvtChn_AllocUnbound = EvtChn_AllocUnbound;
   4.357 -  ChildDeviceData->XenInterface.EvtChn_BindDpc = EvtChn_BindDpc;
   4.358 -
   4.359 -  ChildDeviceData->XenInterface.GntTbl_GetRef = GntTbl_GetRef;
   4.360 -  ChildDeviceData->XenInterface.GntTbl_PutRef = GntTbl_PutRef;
   4.361 -  ChildDeviceData->XenInterface.GntTbl_GrantAccess = GntTbl_GrantAccess;
   4.362 -  ChildDeviceData->XenInterface.GntTbl_EndAccess = GntTbl_EndAccess;
   4.363 -
   4.364 -  ChildDeviceData->XenInterface.XenBus_Read = XenBus_Read;
   4.365 -  ChildDeviceData->XenInterface.XenBus_Write = XenBus_Write;
   4.366 -  ChildDeviceData->XenInterface.XenBus_Printf = XenBus_Printf;
   4.367 -  ChildDeviceData->XenInterface.XenBus_StartTransaction = XenBus_StartTransaction;
   4.368 -  ChildDeviceData->XenInterface.XenBus_EndTransaction = XenBus_EndTransaction;
   4.369 -  ChildDeviceData->XenInterface.XenBus_List = XenBus_List;
   4.370 -  ChildDeviceData->XenInterface.XenBus_AddWatch = XenBus_AddWatch;
   4.371 -  ChildDeviceData->XenInterface.XenBus_RemWatch = XenBus_RemWatch;
   4.372 -
   4.373 -  WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->XenInterface, &GUID_XEN_IFACE, NULL);
   4.374 -  status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
   4.375 -  if (!NT_SUCCESS(status)) {
   4.376 -    return status;
   4.377 -  }
   4.378 -
   4.379 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   4.380 -
   4.381 -  return status;
   4.382 -}
   4.383 -
   4.384 -struct {
   4.385 -  ULONG do_spin;
   4.386 -  ULONG nr_spinning;
   4.387 -} typedef SUSPEND_INFO, *PSUSPEND_INFO;
   4.388 -
   4.389 -static VOID
   4.390 -XenPci_Suspend(
   4.391 - PRKDPC Dpc,
   4.392 - PVOID Context,
   4.393 - PVOID SystemArgument1,
   4.394 - PVOID SystemArgument2)
   4.395 -{
   4.396 -  WDFDEVICE Device = Context;
   4.397 -//  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
   4.398 -  PSUSPEND_INFO suspend_info = SystemArgument1;
   4.399 -  ULONG ActiveProcessorCount;
   4.400 -  KIRQL OldIrql;
   4.401 -  int cancelled;
   4.402 -
   4.403 -  UNREFERENCED_PARAMETER(Dpc);
   4.404 -  UNREFERENCED_PARAMETER(SystemArgument2);
   4.405 -
   4.406 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (CPU = %d)\n", KeGetCurrentProcessorNumber()));
   4.407 -  KdPrint((__DRIVER_NAME "     Device = %p\n", Device));
   4.408 -
   4.409 -  if (KeGetCurrentProcessorNumber() != 0)
   4.410 -  {
   4.411 -    KdPrint((__DRIVER_NAME "     spinning...\n"));
   4.412 -    InterlockedIncrement((volatile LONG *)&suspend_info->nr_spinning);
   4.413 -    KeMemoryBarrier();
   4.414 -    while(suspend_info->do_spin)
   4.415 -    {
   4.416 -      /* we should be able to wait more nicely than this... */
   4.417 -    }
   4.418 -    KeMemoryBarrier();
   4.419 -    InterlockedDecrement((volatile LONG *)&suspend_info->nr_spinning);    
   4.420 -    KdPrint((__DRIVER_NAME "     ...done spinning\n"));
   4.421 -    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n", KeGetCurrentProcessorNumber()));
   4.422 -    return;
   4.423 -  }
   4.424 -  ActiveProcessorCount = (ULONG)KeNumberProcessors;
   4.425 -
   4.426 -  KdPrint((__DRIVER_NAME "     waiting for all other processors to spin\n"));
   4.427 -  while (suspend_info->nr_spinning < ActiveProcessorCount - 1)
   4.428 -  {
   4.429 -      /* we should be able to wait more nicely than this... */
   4.430 -  }
   4.431 -  KdPrint((__DRIVER_NAME "     all other processors are spinning\n"));
   4.432 -
   4.433 -  KeRaiseIrql(HIGH_LEVEL, &OldIrql);
   4.434 -  KdPrint((__DRIVER_NAME "     calling suspend\n"));
   4.435 -  cancelled = HYPERVISOR_shutdown(Device, SHUTDOWN_suspend);
   4.436 -  KdPrint((__DRIVER_NAME "     back from suspend, cancelled = %d\n", cancelled));
   4.437 -  KeLowerIrql(OldIrql);
   4.438 -
   4.439 -  KdPrint((__DRIVER_NAME "     waiting for all other processors to stop spinning\n"));
   4.440 -  suspend_info->do_spin = 0;
   4.441 -  while (suspend_info->nr_spinning != 0)
   4.442 -  {
   4.443 -      /* we should be able to wait more nicely than this... */
   4.444 -  }
   4.445 -  KdPrint((__DRIVER_NAME "     all other processors have stopped spinning\n"));
   4.446 -
   4.447 -  // TODO: Enable xenbus
   4.448 -  // TODO: Enable our IRQ
   4.449 -
   4.450 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n", KeGetCurrentProcessorNumber()));
   4.451 -}
   4.452 -
   4.453 -static VOID
   4.454 -XenPci_BeginSuspend(WDFDEVICE Device)
   4.455 -{
   4.456 -  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
   4.457 -//  KAFFINITY ActiveProcessorMask = 0;
   4.458 -  ULONG ActiveProcessorCount;
   4.459 -  ULONG i;
   4.460 -  PSUSPEND_INFO suspend_info;
   4.461 -  PKDPC Dpc;
   4.462 -  KIRQL OldIrql;
   4.463 -
   4.464 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   4.465 -  KdPrint((__DRIVER_NAME "     Device = %p\n", Device));
   4.466 -
   4.467 -  if (!xpdd->suspending)
   4.468 -  {
   4.469 -    xpdd->suspending = 1;
   4.470 -    suspend_info = ExAllocatePoolWithTag(NonPagedPool, sizeof(SUSPEND_INFO), XENPCI_POOL_TAG);
   4.471 -    suspend_info->do_spin = 1;
   4.472 -    RtlZeroMemory(suspend_info, sizeof(SUSPEND_INFO));
   4.473 -    // TODO: Disable xenbus
   4.474 -    // TODO: Disable our IRQ
   4.475 -    //ActiveProcessorCount = KeQueryActiveProcessorCount(&ActiveProcessorMask);
   4.476 -    ActiveProcessorCount = (ULONG)KeNumberProcessors;
   4.477 -    KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
   4.478 -    for (i = 0; i < ActiveProcessorCount; i++)
   4.479 -    {
   4.480 -      Dpc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KDPC), XENPCI_POOL_TAG);
   4.481 -      KeInitializeDpc(Dpc, XenPci_Suspend, Device);
   4.482 -      KeSetTargetProcessorDpc(Dpc, (CCHAR)i);
   4.483 -      KeInsertQueueDpc(Dpc, suspend_info, NULL);
   4.484 -    }
   4.485 -    KeLowerIrql(OldIrql);
   4.486 -  }
   4.487 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   4.488 -}
   4.489  #endif
   4.490  
   4.491 -
   4.492  #if 0
   4.493  static VOID
   4.494  XenBus_BalloonHandler(char *Path, PVOID Data)
     5.1 --- a/xenstub/xenstub.c	Fri May 23 22:59:10 2008 +1000
     5.2 +++ b/xenstub/xenstub.c	Fri May 23 23:53:02 2008 +1000
     5.3 @@ -105,7 +105,6 @@ XenStub_Irp_Pnp(PDEVICE_OBJECT device_ob
     5.4      KdPrint((__DRIVER_NAME "     IRP_MN_START_DEVICE\n"));
     5.5      IoMarkIrpPending(irp);
     5.6      status = XenStub_SendAndWaitForIrp(device_object, irp);
     5.7 -    //XenStub_QueueWorkItem(device_object, XenStub_Pnp_StartDeviceCallback, irp);
     5.8      status = irp->IoStatus.Status = STATUS_SUCCESS;
     5.9      IoCompleteRequest(irp, IO_NO_INCREMENT);
    5.10      KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
    5.11 @@ -171,12 +170,7 @@ XenStub_Irp_Pnp(PDEVICE_OBJECT device_ob
    5.12      IoSkipCurrentIrpStackLocation(irp);
    5.13      //irp->IoStatus.Status = STATUS_SUCCESS;
    5.14      break;
    5.15 -/*   
    5.16 -  case IRP_MN_QUERY_CAPABILITIES:
    5.17 -    KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_CAPABILITIES\n"));
    5.18 -    stack->Parameters.DeviceCapabilities.Capabilities->NoDisplayInUI = 1;
    5.19 -    status = irp->IoStatus.Status = STATUS_SUCCESS;
    5.20 -*/  
    5.21 +
    5.22    case IRP_MN_QUERY_PNP_DEVICE_STATE:
    5.23      KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_PNP_DEVICE_STATE\n"));
    5.24      status = XenStub_SendAndWaitForIrp(device_object, irp);