win-pvdrivers

changeset 624:0b55299418ce

Found some bugs caused by the unavailability of the page file during restore from suspend.
author James Harper <james.harper@bendigoit.com.au>
date Sun Aug 09 00:30:57 2009 +1000 (2009-08-09)
parents b79b67b46d0c
children c9fd1186ecce
files xenpci/xenbus.c xenpci/xenpci.c xenpci/xenpci.h xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c
line diff
     1.1 --- a/xenpci/xenbus.c	Sat Aug 08 20:55:53 2009 +1000
     1.2 +++ b/xenpci/xenbus.c	Sun Aug 09 00:30:57 2009 +1000
     1.3 @@ -23,16 +23,13 @@ Foundation, Inc., 51 Franklin Street, Fi
     1.4  #pragma warning( disable : 4204 ) 
     1.5  #pragma warning( disable : 4221 ) 
     1.6  
     1.7 +WDF_DECLARE_CONTEXT_TYPE(xsd_sockmsg_t)
     1.8 +
     1.9  struct write_req {
    1.10      void *data;
    1.11      unsigned len;
    1.12  };
    1.13  
    1.14 -static DDKAPI void
    1.15 -XenBus_ReadThreadProc(PVOID StartContext);
    1.16 -static DDKAPI void
    1.17 -XenBus_WatchThreadProc(PVOID StartContext);
    1.18 -
    1.19  // This routine free's the rep structure if there was an error!!!
    1.20  static char *errmsg(struct xsd_sockmsg *rep)
    1.21  {
    1.22 @@ -79,30 +76,14 @@ static void xb_write(
    1.23    ULONG remaining;
    1.24    
    1.25    //FUNCTION_ENTER();
    1.26 -  //KdPrint((__DRIVER_NAME "     len = %d\n", len));
    1.27  
    1.28    ASSERT(len <= XENSTORE_RING_SIZE);
    1.29 -  /* Wait for the ring to drain to the point where we can send the
    1.30 -     message. */
    1.31    prod = xpdd->xen_store_interface->req_prod;
    1.32 -
    1.33 -  while (prod + len - xpdd->xen_store_interface->req_cons > XENSTORE_RING_SIZE)
    1.34 -  {
    1.35 -    /* Wait for there to be space on the ring */
    1.36 -    /* not sure if I can wait here like this... */
    1.37 -    KeWaitForSingleObject(&xpdd->XenBus_ReadThreadEvent, Executive, KernelMode, FALSE, NULL);
    1.38 -    prod = xpdd->xen_store_interface->req_prod;
    1.39 -  }
    1.40 -
    1.41 -  /* We're now guaranteed to be able to send the message without
    1.42 -     overflowing the ring.  Do so. */
    1.43 -
    1.44    ptr = data;
    1.45    remaining = len;
    1.46    while (remaining)
    1.47    {
    1.48      copy_len = min(remaining, XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod));
    1.49 -    //KdPrint((__DRIVER_NAME "     copy_len = %d\n", copy_len));
    1.50      memcpy((PUCHAR)xpdd->xen_store_interface->req + MASK_XENSTORE_IDX(prod), ptr, copy_len);
    1.51      prod += (XENSTORE_RING_IDX)copy_len;
    1.52      ptr += copy_len;
    1.53 @@ -143,9 +124,7 @@ xenbus_format_msg_reply(
    1.54    for (i = 0; i < nr_reqs; i++)
    1.55      xb_write(xpdd, req[i].data, req[i].len);
    1.56  
    1.57 -  //KdPrint((__DRIVER_NAME "     waiting...\n"));
    1.58    KeWaitForSingleObject(&xpdd->xb_request_complete_event, Executive, KernelMode, FALSE, NULL);
    1.59 -  //KdPrint((__DRIVER_NAME "     ...done waiting\n"));
    1.60    reply = xpdd->xb_reply;
    1.61    xpdd->xb_reply = NULL;
    1.62    ExReleaseFastMutex(&xpdd->xb_request_mutex);
    1.63 @@ -163,7 +142,7 @@ XenBus_Raw(
    1.64  {
    1.65    struct xsd_sockmsg *reply;
    1.66    
    1.67 -  FUNCTION_ENTER();
    1.68 +  //FUNCTION_ENTER();
    1.69  
    1.70    ExAcquireFastMutex(&xpdd->xb_request_mutex);
    1.71    xb_write(xpdd, msg, sizeof(struct xsd_sockmsg) + msg->len);
    1.72 @@ -172,14 +151,12 @@ XenBus_Raw(
    1.73    xpdd->xb_reply = NULL;
    1.74    ExReleaseFastMutex(&xpdd->xb_request_mutex);  
    1.75  
    1.76 -  FUNCTION_EXIT();
    1.77 +  //FUNCTION_EXIT();
    1.78      
    1.79    return reply;
    1.80  }
    1.81  
    1.82 -/*
    1.83 -Called at PASSIVE_LEVEL
    1.84 -*/
    1.85 +/* Called at PASSIVE_LEVEL */
    1.86  char *
    1.87  XenBus_Read(
    1.88    PVOID Context,
    1.89 @@ -214,9 +191,7 @@ XenBus_Read(
    1.90    return NULL;
    1.91  }
    1.92  
    1.93 -/*
    1.94 -Called at PASSIVE_LEVEL
    1.95 -*/
    1.96 +/* Called at PASSIVE_LEVEL */
    1.97  char *
    1.98  XenBus_Write(
    1.99    PVOID Context,
   1.100 @@ -247,21 +222,103 @@ XenBus_Write(
   1.101    return NULL;
   1.102  }
   1.103  
   1.104 +/* Called at PASSIVE_LEVEL */
   1.105 +static VOID
   1.106 +XenBus_WatchWorkItemProc(WDFWORKITEM workitem)
   1.107 +{
   1.108 +  WDFDEVICE device = WdfWorkItemGetParentObject(workitem);
   1.109 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(device);
   1.110 +  xsd_sockmsg_t *msg;
   1.111 +  PCHAR path;
   1.112 +  int index;
   1.113 +  PXENBUS_WATCH_ENTRY entry;
   1.114 +
   1.115 +  //FUNCTION_ENTER();
   1.116 +  msg = WdfObjectGetTypedContext(workitem, xsd_sockmsg_t);
   1.117 +  path = (PCHAR)msg + sizeof(xsd_sockmsg_t);
   1.118 +  index = atoi(path + strlen(path) + 1);
   1.119 +  ExAcquireFastMutex(&xpdd->xb_watch_mutex);
   1.120 +  entry = &xpdd->XenBus_WatchEntries[index];
   1.121 +  if (!entry->Active || !entry->ServiceRoutine)
   1.122 +  {
   1.123 +    KdPrint((__DRIVER_NAME "     No watch for index %d\n", index));
   1.124 +    WdfObjectDelete(workitem);
   1.125 +    return;
   1.126 +  }
   1.127 +  entry->Count++;
   1.128 +  entry->ServiceRoutine(path, entry->ServiceContext);
   1.129 +  ExReleaseFastMutex(&xpdd->xb_watch_mutex);
   1.130 +  WdfObjectDelete(workitem);
   1.131 +  //FUNCTION_ENTER();
   1.132 +}    
   1.133 +
   1.134 +/* Called at DISPATCH_LEVEL */
   1.135  static VOID
   1.136  XenBus_Dpc(PVOID ServiceContext)
   1.137  {
   1.138 +  NTSTATUS status;
   1.139    PXENPCI_DEVICE_DATA xpdd = ServiceContext;
   1.140 -
   1.141 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   1.142 +  xsd_sockmsg_t msg;
   1.143 +  WDF_WORKITEM_CONFIG workitem_config;
   1.144 +  WDF_OBJECT_ATTRIBUTES workitem_attributes;
   1.145 +  WDFWORKITEM workitem;
   1.146  
   1.147 -  KeSetEvent(&xpdd->XenBus_ReadThreadEvent, IO_NO_INCREMENT, FALSE);
   1.148 +  //FUNCTION_ENTER();
   1.149  
   1.150 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.151 +  //KdPrint((__DRIVER_NAME "     rsp_prod = %d, rsp_cons = %d\n", xpdd->xen_store_interface->rsp_prod, xpdd->xen_store_interface->rsp_cons));
   1.152 +  while (xpdd->xen_store_interface->rsp_prod != xpdd->xen_store_interface->rsp_cons)
   1.153 +  {
   1.154 +    if (xpdd->xen_store_interface->rsp_prod - xpdd->xen_store_interface->rsp_cons < sizeof(msg))
   1.155 +    {
   1.156 +      KdPrint((__DRIVER_NAME " +++ Message incomplete (not even a full header)\n"));
   1.157 +      break;
   1.158 +    }
   1.159 +    KeMemoryBarrier();
   1.160 +    memcpy_from_ring(xpdd->xen_store_interface->rsp, &msg,
   1.161 +      MASK_XENSTORE_IDX(xpdd->xen_store_interface->rsp_cons), sizeof(msg));
   1.162 +    if (xpdd->xen_store_interface->rsp_prod - xpdd->xen_store_interface->rsp_cons < sizeof(msg) + msg.len)
   1.163 +    {
   1.164 +      KdPrint((__DRIVER_NAME " +++ Message incomplete (header but not full body)\n"));
   1.165 +      break;
   1.166 +    }
   1.167  
   1.168 -  return;
   1.169 +    if (msg.type != XS_WATCH_EVENT)
   1.170 +    {
   1.171 +      /* process reply - only ever one outstanding */
   1.172 +      xpdd->xb_reply = ExAllocatePoolWithTag(NonPagedPool, sizeof(msg) + msg.len, XENPCI_POOL_TAG);
   1.173 +      memcpy_from_ring(xpdd->xen_store_interface->rsp,
   1.174 +        xpdd->xb_reply,
   1.175 +        MASK_XENSTORE_IDX(xpdd->xen_store_interface->rsp_cons),
   1.176 +        msg.len + sizeof(msg));
   1.177 +      xpdd->xen_store_interface->rsp_cons += msg.len + sizeof(msg);
   1.178 +      KeSetEvent(&xpdd->xb_request_complete_event, IO_NO_INCREMENT, FALSE);
   1.179 +    }
   1.180 +    else
   1.181 +    {
   1.182 +      /* process watch */
   1.183 +      WDF_WORKITEM_CONFIG_INIT(&workitem_config, XenBus_WatchWorkItemProc);
   1.184 +      WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&workitem_attributes, xsd_sockmsg_t);
   1.185 +      workitem_attributes.ParentObject = xpdd->wdf_device;
   1.186 +      workitem_attributes.ContextSizeOverride = sizeof(msg) + msg.len;
   1.187 +      status = WdfWorkItemCreate(&workitem_config, &workitem_attributes, &workitem);
   1.188 +      if (!NT_SUCCESS(status))
   1.189 +      {
   1.190 +        KdPrint((__DRIVER_NAME "     Failed to create work item for watch\n"));
   1.191 +        xpdd->xen_store_interface->rsp_cons += msg.len + sizeof(msg);
   1.192 +        continue;
   1.193 +      }
   1.194 +      memcpy_from_ring(xpdd->xen_store_interface->rsp,
   1.195 +        WdfObjectGetTypedContext(workitem, xsd_sockmsg_t),
   1.196 +        MASK_XENSTORE_IDX(xpdd->xen_store_interface->rsp_cons), msg.len + sizeof(msg));
   1.197 +      xpdd->xen_store_interface->rsp_cons += msg.len + sizeof(msg);
   1.198 +      WdfWorkItemEnqueue(workitem);
   1.199 +    }
   1.200 +  }
   1.201 +  
   1.202 +  //FUNCTION_EXIT();
   1.203  }
   1.204  
   1.205 -NTSTATUS
   1.206 +static NTSTATUS
   1.207  XenBus_Connect(PXENPCI_DEVICE_DATA xpdd)
   1.208  {
   1.209    PHYSICAL_ADDRESS pa_xen_store_interface;
   1.210 @@ -272,7 +329,17 @@ XenBus_Connect(PXENPCI_DEVICE_DATA xpdd)
   1.211    pa_xen_store_interface.QuadPart = (ULONGLONG)xen_store_mfn << PAGE_SHIFT;
   1.212    xpdd->xen_store_interface = MmMapIoSpace(pa_xen_store_interface, PAGE_SIZE, MmNonCached);
   1.213  
   1.214 -  KeMemoryBarrier();
   1.215 +  EvtChn_BindDpc(xpdd, xpdd->xen_store_evtchn, XenBus_Dpc, xpdd);
   1.216 +  
   1.217 +  return STATUS_SUCCESS;
   1.218 +}
   1.219 +
   1.220 +static NTSTATUS
   1.221 +XenBus_Disconnect(PXENPCI_DEVICE_DATA xpdd)
   1.222 +{
   1.223 +  EvtChn_Unbind(xpdd, xpdd->xen_store_evtchn);
   1.224 +
   1.225 +  MmUnmapIoSpace(xpdd->xen_store_interface, PAGE_SIZE);
   1.226    
   1.227    return STATUS_SUCCESS;
   1.228  }
   1.229 @@ -281,10 +348,9 @@ NTSTATUS
   1.230  XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
   1.231  {
   1.232    NTSTATUS status;
   1.233 -  HANDLE thread_handle;
   1.234    int i;
   1.235      
   1.236 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   1.237 +  FUNCTION_ENTER();
   1.238  
   1.239    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
   1.240  
   1.241 @@ -296,8 +362,6 @@ XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
   1.242      xpdd->XenBus_WatchEntries[i].Active = 0;
   1.243    }
   1.244  
   1.245 -  KeInitializeEvent(&xpdd->XenBus_ReadThreadEvent, SynchronizationEvent, FALSE);
   1.246 -  KeInitializeEvent(&xpdd->XenBus_WatchThreadEvent, SynchronizationEvent, FALSE);
   1.247    KeInitializeEvent(&xpdd->xb_request_complete_event, SynchronizationEvent, FALSE);
   1.248  
   1.249    status = XenBus_Connect(xpdd);
   1.250 @@ -305,46 +369,8 @@ XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
   1.251    {
   1.252      return status;
   1.253    }
   1.254 -  EvtChn_BindDpc(xpdd, xpdd->xen_store_evtchn, XenBus_Dpc, xpdd);
   1.255 -
   1.256 -KdPrint((__DRIVER_NAME "     A\n"));
   1.257 -  status = PsCreateSystemThread(&thread_handle, THREAD_ALL_ACCESS, NULL, NULL, NULL, XenBus_ReadThreadProc, xpdd);
   1.258 -  if (!NT_SUCCESS(status))
   1.259 -  {
   1.260 -    KdPrint((__DRIVER_NAME "     Could not start read thread\n"));
   1.261 -    return status;
   1.262 -  }
   1.263 -KdPrint((__DRIVER_NAME "     B\n"));  
   1.264 -  status = ObReferenceObjectByHandle(thread_handle, THREAD_ALL_ACCESS, NULL, KernelMode, &xpdd->XenBus_ReadThread, NULL);
   1.265 -KdPrint((__DRIVER_NAME "     C\n"));
   1.266 -  ZwClose(thread_handle);
   1.267    
   1.268 -KdPrint((__DRIVER_NAME "     D\n"));
   1.269 -  if (!NT_SUCCESS(status))
   1.270 -  {
   1.271 -    KdPrint((__DRIVER_NAME "     ObReferenceObjectByHandle(XenBus_ReadThread) = %08x\n", status));
   1.272 -    return status;
   1.273 -  }
   1.274 -KdPrint((__DRIVER_NAME "     E\n"));
   1.275 -
   1.276 -  status = PsCreateSystemThread(&thread_handle, THREAD_ALL_ACCESS, NULL, NULL, NULL, XenBus_WatchThreadProc, xpdd);
   1.277 -KdPrint((__DRIVER_NAME "     F\n"));
   1.278 -  if (!NT_SUCCESS(status))
   1.279 -  {
   1.280 -    KdPrint((__DRIVER_NAME " Could not start watch thread\n"));
   1.281 -    return status;
   1.282 -  }
   1.283 -KdPrint((__DRIVER_NAME "     G\n"));
   1.284 -  status = ObReferenceObjectByHandle(thread_handle, THREAD_ALL_ACCESS, NULL, KernelMode, &xpdd->XenBus_WatchThread, NULL);
   1.285 -KdPrint((__DRIVER_NAME "     H\n"));
   1.286 -  ZwClose(thread_handle);
   1.287 -KdPrint((__DRIVER_NAME "     I\n"));
   1.288 -  if (!NT_SUCCESS(status))
   1.289 -  {
   1.290 -    KdPrint((__DRIVER_NAME "     ObReferenceObjectByHandle(XenBus_WatchThread) = %08x\n", status));
   1.291 -  }
   1.292 -  
   1.293 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.294 +  FUNCTION_EXIT();
   1.295  
   1.296    return STATUS_SUCCESS;
   1.297  }
   1.298 @@ -382,43 +408,23 @@ XenBus_SendRemWatch(
   1.299  NTSTATUS
   1.300  XenBus_Halt(PXENPCI_DEVICE_DATA xpdd)
   1.301  {
   1.302 -  NTSTATUS status;
   1.303    int i;
   1.304 -  LARGE_INTEGER timeout;
   1.305  
   1.306    FUNCTION_ENTER();
   1.307    
   1.308    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   1.309  
   1.310    /* we need to remove the watches as a watch firing could lead to a XenBus_Read/Write/Printf */
   1.311 -  for (i = 0; i < MAX_WATCH_ENTRIES; i++) {
   1.312 +  for (i = 0; i < MAX_WATCH_ENTRIES; i++)
   1.313 +  {
   1.314      if (xpdd->XenBus_WatchEntries[i].Active)
   1.315 +    {
   1.316 +      xpdd->XenBus_WatchEntries[i].Active = 0;
   1.317        XenBus_SendRemWatch(xpdd, XBT_NIL, xpdd->XenBus_WatchEntries[i].Path, i);
   1.318 +    }
   1.319    }
   1.320  
   1.321 -  xpdd->XenBus_ShuttingDown = TRUE;
   1.322 -  KeMemoryBarrier();
   1.323 -
   1.324 -  KeSetEvent(&xpdd->XenBus_WatchThreadEvent, IO_NO_INCREMENT, FALSE);
   1.325 -  KeSetEvent(&xpdd->XenBus_ReadThreadEvent, IO_NO_INCREMENT, FALSE);
   1.326 -  
   1.327 -  timeout.QuadPart = (LONGLONG)-1 * 1000 * 1000 * 10;
   1.328 -  while ((status = KeWaitForSingleObject(xpdd->XenBus_WatchThread, Executive, KernelMode, FALSE, &timeout)) != STATUS_SUCCESS)
   1.329 -  {
   1.330 -    timeout.QuadPart = (LONGLONG)-1 * 1000 * 1000 * 10;
   1.331 -    KdPrint((__DRIVER_NAME "     Waiting for XenBus_WatchThread to stop\n"));
   1.332 -  }
   1.333 -  ObDereferenceObject(xpdd->XenBus_WatchThread);
   1.334 -
   1.335 -  timeout.QuadPart = (LONGLONG)-1 * 1000 * 1000 * 10;
   1.336 -  while ((status = KeWaitForSingleObject(xpdd->XenBus_ReadThread, Executive, KernelMode, FALSE, &timeout)) != STATUS_SUCCESS)
   1.337 -  {
   1.338 -    timeout.QuadPart = (LONGLONG)-1 * 1000 * 1000 * 10;
   1.339 -    KdPrint((__DRIVER_NAME "     Waiting for XenBus_ReadThread to stop\n"));
   1.340 -  }
   1.341 -  ObDereferenceObject(xpdd->XenBus_ReadThread);
   1.342 -  
   1.343 -  xpdd->XenBus_ShuttingDown = FALSE;
   1.344 +  XenBus_Disconnect(xpdd);
   1.345  
   1.346    FUNCTION_EXIT();
   1.347  
   1.348 @@ -439,8 +445,6 @@ XenBus_List(
   1.349    char **res;
   1.350    char *msg;
   1.351  
   1.352 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   1.353 -
   1.354    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   1.355  
   1.356    repmsg = xenbus_format_msg_reply(xpdd, XS_DIRECTORY, xbt, req, ARRAY_SIZE(req));
   1.357 @@ -448,7 +452,6 @@ XenBus_List(
   1.358    if (msg)
   1.359    {
   1.360      *contents = NULL;
   1.361 -//    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.362      return msg;
   1.363    }
   1.364    reply = repmsg + 1;
   1.365 @@ -468,129 +471,11 @@ XenBus_List(
   1.366    res[i] = NULL;
   1.367    ExFreePoolWithTag(repmsg, XENPCI_POOL_TAG);
   1.368    *contents = res;
   1.369 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.370 +  
   1.371    return NULL;
   1.372  }
   1.373  
   1.374 -static DDKAPI void
   1.375 -XenBus_ReadThreadProc(PVOID StartContext)
   1.376 -{
   1.377 -  int NewWriteIndex;
   1.378 -  struct xsd_sockmsg msg;
   1.379 -  char *payload;
   1.380 -  char *path, *token;
   1.381 -  PXENPCI_DEVICE_DATA xpdd = StartContext;
   1.382 -
   1.383 -  FUNCTION_ENTER();
   1.384 -  for(;;)
   1.385 -  {
   1.386 -    KeWaitForSingleObject(&xpdd->XenBus_ReadThreadEvent, Executive, KernelMode, FALSE, NULL);
   1.387 -    //KdPrint((__DRIVER_NAME " +++ thread woken\n"));
   1.388 -    if (xpdd->XenBus_ShuttingDown)
   1.389 -    {
   1.390 -      KdPrint((__DRIVER_NAME "     Shutdown detected in ReadThreadProc\n"));
   1.391 -      PsTerminateSystemThread(0);
   1.392 -    }
   1.393 -    while (xpdd->xen_store_interface->rsp_prod != xpdd->xen_store_interface->rsp_cons)
   1.394 -    {
   1.395 -      //KdPrint((__DRIVER_NAME "     a - Rsp_cons %d, rsp_prod %d.\n", xpdd->xen_store_interface->rsp_cons, xpdd->xen_store_interface->rsp_prod));
   1.396 -      if (xpdd->xen_store_interface->rsp_prod - xpdd->xen_store_interface->rsp_cons < sizeof(msg))
   1.397 -      {
   1.398 -        //KdPrint((__DRIVER_NAME " +++ Message incomplete (not even a full header)\n"));
   1.399 -        break;
   1.400 -      }
   1.401 -      KeMemoryBarrier();
   1.402 -      memcpy_from_ring(xpdd->xen_store_interface->rsp, &msg,
   1.403 -        MASK_XENSTORE_IDX(xpdd->xen_store_interface->rsp_cons), sizeof(msg));
   1.404 -      if (xpdd->xen_store_interface->rsp_prod - xpdd->xen_store_interface->rsp_cons < sizeof(msg) + msg.len)
   1.405 -      {
   1.406 -        //KdPrint((__DRIVER_NAME " +++ Message incomplete (header but not full body)\n"));
   1.407 -        break;
   1.408 -      }
   1.409 -  
   1.410 -      if (msg.type != XS_WATCH_EVENT)
   1.411 -      {
   1.412 -        xpdd->xb_reply = ExAllocatePoolWithTag(NonPagedPool, sizeof(msg) + msg.len, XENPCI_POOL_TAG);
   1.413 -        memcpy_from_ring(xpdd->xen_store_interface->rsp,
   1.414 -          xpdd->xb_reply,
   1.415 -          MASK_XENSTORE_IDX(xpdd->xen_store_interface->rsp_cons),
   1.416 -          msg.len + sizeof(msg));
   1.417 -        xpdd->xen_store_interface->rsp_cons += msg.len + sizeof(msg);
   1.418 -        //KdPrint((__DRIVER_NAME " +++ Setting event\n"));
   1.419 -        KeSetEvent(&xpdd->xb_request_complete_event, IO_NO_INCREMENT, FALSE);
   1.420 -      }
   1.421 -      else // a watch: add to watch ring and signal watch thread
   1.422 -      {
   1.423 -        payload = ExAllocatePoolWithTag(NonPagedPool, sizeof(msg) + msg.len, XENPCI_POOL_TAG);
   1.424 -        memcpy_from_ring(xpdd->xen_store_interface->rsp, payload,
   1.425 -          MASK_XENSTORE_IDX(xpdd->xen_store_interface->rsp_cons), msg.len + sizeof(msg));
   1.426 -        xpdd->xen_store_interface->rsp_cons += msg.len + sizeof(msg);
   1.427 -        path = payload + sizeof(msg);
   1.428 -        token = path + strlen(path) + 1;
   1.429 -
   1.430 -        NewWriteIndex = (xpdd->XenBus_WatchRingWriteIndex + 1) & 127;
   1.431 -        if (NewWriteIndex != xpdd->XenBus_WatchRingReadIndex)
   1.432 -        {
   1.433 -          strncpy(xpdd->XenBus_WatchRing[NewWriteIndex].Path, path, 128);
   1.434 -          strncpy(xpdd->XenBus_WatchRing[NewWriteIndex].Token, token, 10);
   1.435 -          xpdd->XenBus_WatchRingWriteIndex = NewWriteIndex;
   1.436 -        }
   1.437 -        else
   1.438 -        {
   1.439 -          KdPrint((__DRIVER_NAME " +++ Queue full Path = %s Token = %s\n", path, token));
   1.440 -          // drop the message on the floor
   1.441 -          continue;
   1.442 -        }
   1.443 -
   1.444 -        ExFreePoolWithTag(payload, XENPCI_POOL_TAG);
   1.445 -        KeSetEvent(&xpdd->XenBus_WatchThreadEvent, IO_NO_INCREMENT, FALSE);
   1.446 -      }
   1.447 -    }
   1.448 -  }
   1.449 -  FUNCTION_EXIT();
   1.450 -}
   1.451 -
   1.452 -static DDKAPI void
   1.453 -XenBus_WatchThreadProc(PVOID StartContext)
   1.454 -{
   1.455 -  int index;
   1.456 -  PXENBUS_WATCH_ENTRY entry;
   1.457 -  PXENPCI_DEVICE_DATA xpdd = StartContext;
   1.458 -
   1.459 -  for(;;)
   1.460 -  {
   1.461 -    KeWaitForSingleObject(&xpdd->XenBus_WatchThreadEvent, Executive, KernelMode, FALSE, NULL);
   1.462 -    ExAcquireFastMutex(&xpdd->xb_watch_mutex);
   1.463 -    if (xpdd->XenBus_ShuttingDown)
   1.464 -    {
   1.465 -      KdPrint((__DRIVER_NAME "     Shutdown detected in WatchThreadProc\n"));
   1.466 -      ExReleaseFastMutex(&xpdd->xb_watch_mutex);
   1.467 -      PsTerminateSystemThread(0);
   1.468 -      KdPrint((__DRIVER_NAME "     WatchThreadProc still running... wtf?\n"));
   1.469 -    }
   1.470 -    while (xpdd->XenBus_WatchRingReadIndex != xpdd->XenBus_WatchRingWriteIndex)
   1.471 -    {
   1.472 -      //KdPrint((__DRIVER_NAME " +++ watch triggered\n"));
   1.473 -      xpdd->XenBus_WatchRingReadIndex = 
   1.474 -        (xpdd->XenBus_WatchRingReadIndex + 1) % WATCH_RING_SIZE;
   1.475 -      index = atoi(xpdd->XenBus_WatchRing[xpdd->XenBus_WatchRingReadIndex].Token);
   1.476 -
   1.477 -      entry = &xpdd->XenBus_WatchEntries[index];
   1.478 -      if (!entry->Active || !entry->ServiceRoutine)
   1.479 -      {
   1.480 -        KdPrint((__DRIVER_NAME "     No watch for index %d\n", index));
   1.481 -        continue;
   1.482 -      }
   1.483 -      entry->Count++;
   1.484 -      entry->ServiceRoutine(xpdd->XenBus_WatchRing[xpdd->XenBus_WatchRingReadIndex].Path, entry->ServiceContext);
   1.485 -    }
   1.486 -    ExReleaseFastMutex(&xpdd->xb_watch_mutex);
   1.487 -  }
   1.488 -}    
   1.489 -
   1.490 -/*
   1.491 -Called at PASSIVE_LEVEL
   1.492 -*/
   1.493 +/* Called at PASSIVE_LEVEL */
   1.494  static char *
   1.495  XenBus_SendAddWatch(
   1.496    PVOID Context,
   1.497 @@ -631,10 +516,8 @@ XenBus_Suspend(PXENPCI_DEVICE_DATA xpdd)
   1.498      if (xpdd->XenBus_WatchEntries[i].Active)
   1.499        XenBus_SendRemWatch(xpdd, XBT_NIL, xpdd->XenBus_WatchEntries[i].Path, i);
   1.500    }
   1.501 -
   1.502 -  // need to synchronise with readthread here too to ensure that it won't do anything silly
   1.503 -  MmUnmapIoSpace(xpdd->xen_store_interface, PAGE_SIZE);
   1.504 -
   1.505 +  XenBus_Disconnect(xpdd);
   1.506 +  
   1.507    return STATUS_SUCCESS;
   1.508  }
   1.509  
   1.510 @@ -652,7 +535,6 @@ XenBus_Resume(PXENPCI_DEVICE_DATA xpdd)
   1.511    {
   1.512      return status;
   1.513    }
   1.514 -  EvtChn_BindDpc(xpdd, xpdd->xen_store_evtchn, XenBus_Dpc, xpdd);
   1.515    
   1.516    for (i = 0; i < MAX_WATCH_ENTRIES; i++)
   1.517    {
   1.518 @@ -680,8 +562,6 @@ XenBus_AddWatch(
   1.519    int i;
   1.520    PXENBUS_WATCH_ENTRY w_entry;
   1.521  
   1.522 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   1.523 -
   1.524    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   1.525  
   1.526    ASSERT(strlen(Path) < ARRAY_SIZE(w_entry->Path));
   1.527 @@ -715,12 +595,9 @@ XenBus_AddWatch(
   1.528    if (msg)
   1.529    {
   1.530      xpdd->XenBus_WatchEntries[i].Active = 0;
   1.531 -    //KdPrint((__DRIVER_NAME " <-- XenBus_AddWatch (%s)\n", msg));
   1.532      return msg;
   1.533    }
   1.534  
   1.535 -  //KdPrint((__DRIVER_NAME " <-- XenBus_AddWatch\n"));
   1.536 -
   1.537    return NULL;
   1.538  }
   1.539  
   1.540 @@ -736,7 +613,6 @@ XenBus_RemWatch(
   1.541    char *msg;
   1.542    int i;
   1.543  
   1.544 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   1.545    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   1.546  
   1.547    ExAcquireFastMutex(&xpdd->xb_watch_mutex);
   1.548 @@ -769,12 +645,9 @@ XenBus_RemWatch(
   1.549  
   1.550    msg = XenBus_SendRemWatch(Context, xbt, Path, i);
   1.551    
   1.552 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.553 -
   1.554    return msg;
   1.555  }
   1.556  
   1.557 -
   1.558  char *
   1.559  XenBus_StartTransaction(PVOID Context, xenbus_transaction_t *xbt)
   1.560  {
   1.561 @@ -785,7 +658,6 @@ XenBus_StartTransaction(PVOID Context, x
   1.562    struct xsd_sockmsg *rep;
   1.563    char *err;
   1.564  
   1.565 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   1.566    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   1.567  
   1.568    rep = xenbus_format_msg_reply(xpdd, XS_TRANSACTION_START, 0, &req, 1);
   1.569 @@ -793,11 +665,8 @@ XenBus_StartTransaction(PVOID Context, x
   1.570    if (err)
   1.571      return err;
   1.572    *xbt = atoi((char *)(rep + 1));
   1.573 -  //sscanf((char *)(rep + 1), "%u", xbt);
   1.574    ExFreePoolWithTag(rep, XENPCI_POOL_TAG);
   1.575  
   1.576 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.577 -
   1.578    return NULL;
   1.579  }
   1.580  
   1.581 @@ -813,8 +682,6 @@ XenBus_EndTransaction(
   1.582    struct write_req req;
   1.583    char *err;
   1.584  
   1.585 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   1.586 -
   1.587    *retry = 0;
   1.588  
   1.589    req.data = abort ? "F" : "T";
   1.590 @@ -832,8 +699,6 @@ XenBus_EndTransaction(
   1.591    }
   1.592    ExFreePoolWithTag(rep, XENPCI_POOL_TAG);
   1.593  
   1.594 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.595 -
   1.596    return NULL;
   1.597  }
   1.598  
   1.599 @@ -850,7 +715,6 @@ XenBus_Printf(
   1.600    char buf[512];
   1.601    char *retval;
   1.602  
   1.603 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   1.604    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   1.605  
   1.606    va_start(ap, fmt);
   1.607 @@ -858,7 +722,5 @@ XenBus_Printf(
   1.608    va_end(ap);
   1.609    retval = XenBus_Write(xpdd, xbt, path, buf);
   1.610  
   1.611 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.612 -
   1.613    return retval;
   1.614  }
     2.1 --- a/xenpci/xenpci.c	Sat Aug 08 20:55:53 2009 +1000
     2.2 +++ b/xenpci/xenpci.c	Sun Aug 09 00:30:57 2009 +1000
     2.3 @@ -72,9 +72,11 @@ XenPci_EvtDeviceAdd_XenPci(WDFDRIVER dri
     2.4    WDF_OBJECT_ATTRIBUTES file_attributes;
     2.5    WDF_FILEOBJECT_CONFIG file_config;
     2.6    WDF_IO_QUEUE_CONFIG queue_config;
     2.7 +  WDFCOLLECTION veto_devices;
     2.8    WDFKEY param_key;
     2.9    DECLARE_CONST_UNICODE_STRING(veto_devices_name, L"veto_devices");
    2.10    WDF_DEVICE_POWER_CAPABILITIES power_capabilities;
    2.11 +  int i;
    2.12    
    2.13    UNREFERENCED_PARAMETER(driver);
    2.14  
    2.15 @@ -119,11 +121,11 @@ XenPci_EvtDeviceAdd_XenPci(WDFDRIVER dri
    2.16    xpdd->wdf_device = device;
    2.17    xpdd->child_list = WdfFdoGetDefaultChildList(device);
    2.18  
    2.19 -  WdfCollectionCreate(WDF_NO_OBJECT_ATTRIBUTES, &xpdd->veto_devices);
    2.20 +  WdfCollectionCreate(WDF_NO_OBJECT_ATTRIBUTES, &veto_devices);
    2.21    status = WdfDriverOpenParametersRegistryKey(driver, KEY_QUERY_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &param_key);
    2.22    if (NT_SUCCESS(status))
    2.23    {
    2.24 -    status = WdfRegistryQueryMultiString(param_key, &veto_devices_name, WDF_NO_OBJECT_ATTRIBUTES, xpdd->veto_devices);
    2.25 +    status = WdfRegistryQueryMultiString(param_key, &veto_devices_name, WDF_NO_OBJECT_ATTRIBUTES, veto_devices);
    2.26      if (!NT_SUCCESS(status))
    2.27      {
    2.28        KdPrint(("Error reading parameters/veto_devices value %08x\n", status));
    2.29 @@ -134,7 +136,22 @@ XenPci_EvtDeviceAdd_XenPci(WDFDRIVER dri
    2.30    {
    2.31      KdPrint(("Error opening parameters key %08x\n", status));
    2.32    }
    2.33 -  
    2.34 +
    2.35 +  InitializeListHead(&xpdd->veto_list);
    2.36 +  for (i = 0; i < WdfCollectionGetCount(veto_devices); i++)
    2.37 +  {
    2.38 +    WDFOBJECT ws;
    2.39 +    UNICODE_STRING val;
    2.40 +    ANSI_STRING s;
    2.41 +    PVOID entry;
    2.42 +    ws = WdfCollectionGetItem(veto_devices, i);
    2.43 +    WdfStringGetUnicodeString(ws, &val);
    2.44 +    RtlUnicodeStringToAnsiString(&s, &val, TRUE);
    2.45 +    entry = ExAllocatePoolWithTag(NonPagedPool, sizeof(LIST_ENTRY) + s.Length + 1, XENPCI_POOL_TAG);
    2.46 +    memcpy((PUCHAR)entry + sizeof(LIST_ENTRY), s.Buffer, s.Length + 1);
    2.47 +    RtlFreeAnsiString(&s);
    2.48 +    InsertTailList(&xpdd->veto_list, (PLIST_ENTRY)entry);
    2.49 +  }
    2.50    WDF_DEVICE_POWER_CAPABILITIES_INIT(&power_capabilities);
    2.51    power_capabilities.DeviceD1 = WdfTrue;
    2.52    power_capabilities.WakeFromD1 = WdfTrue;
     3.1 --- a/xenpci/xenpci.h	Sat Aug 08 20:55:53 2009 +1000
     3.2 +++ b/xenpci/xenpci.h	Sun Aug 09 00:30:57 2009 +1000
     3.3 @@ -89,15 +89,14 @@ typedef struct _XENBUS_WATCH_RING
     3.4    char Token[10];
     3.5  } XENBUS_WATCH_RING;
     3.6  
     3.7 +typedef struct xsd_sockmsg xsd_sockmsg_t;
     3.8 +
     3.9  typedef struct _XENBUS_WATCH_ENTRY {
    3.10    char Path[128];
    3.11    PXENBUS_WATCH_CALLBACK ServiceRoutine;
    3.12    PVOID ServiceContext;
    3.13    int Count;
    3.14    int Active;
    3.15 -  //int RemovePending;
    3.16 -  //int Running;
    3.17 -  //KEVENT CompleteEvent;
    3.18  } XENBUS_WATCH_ENTRY, *PXENBUS_WATCH_ENTRY;
    3.19  
    3.20  #define NR_EVENTS 1024
    3.21 @@ -117,8 +116,6 @@ typedef struct _XENBUS_WATCH_ENTRY {
    3.22  typedef struct {  
    3.23    WDFDEVICE wdf_device;
    3.24    
    3.25 -  BOOLEAN XenBus_ShuttingDown;
    3.26 -  
    3.27    BOOLEAN tpr_patched;
    3.28  
    3.29    WDFINTERRUPT interrupt;
    3.30 @@ -161,18 +158,10 @@ typedef struct {
    3.31    ev_action_t ev_actions[NR_EVENTS];
    3.32  //  unsigned long bound_ports[NR_EVENTS/(8*sizeof(unsigned long))];
    3.33  
    3.34 -  PKTHREAD XenBus_ReadThread;
    3.35 -  KEVENT XenBus_ReadThreadEvent;
    3.36 -  PKTHREAD XenBus_WatchThread;
    3.37 -  KEVENT XenBus_WatchThreadEvent;
    3.38 -
    3.39 -  XENBUS_WATCH_RING XenBus_WatchRing[WATCH_RING_SIZE];
    3.40 -  int XenBus_WatchRingReadIndex;
    3.41 -  int XenBus_WatchRingWriteIndex;
    3.42 -
    3.43 +  BOOLEAN xb_state;
    3.44 +  
    3.45    struct xenstore_domain_interface *xen_store_interface;
    3.46  
    3.47 -
    3.48  #define BALLOON_UNITS (1024 * 1024) /* 1MB */
    3.49    PKTHREAD balloon_thread;
    3.50    KEVENT balloon_event;
    3.51 @@ -204,7 +193,8 @@ typedef struct {
    3.52    
    3.53    WDFQUEUE io_queue;
    3.54  
    3.55 -  WDFCOLLECTION veto_devices;
    3.56 +  //WDFCOLLECTION veto_devices;
    3.57 +  LIST_ENTRY veto_list;
    3.58  #if 0
    3.59    KSPIN_LOCK mmio_freelist_lock;
    3.60    PPFN_NUMBER mmio_freelist_base;
    3.61 @@ -229,6 +219,7 @@ typedef struct {
    3.62    //PVOID xenbus_request;
    3.63    KEVENT backend_state_event;
    3.64    ULONG backend_state;
    3.65 +  FAST_MUTEX backend_state_mutex;
    3.66    ULONG frontend_state;
    3.67    PMDL config_page_mdl;
    3.68    PHYSICAL_ADDRESS config_page_phys;
     4.1 --- a/xenpci/xenpci_fdo.c	Sat Aug 08 20:55:53 2009 +1000
     4.2 +++ b/xenpci/xenpci_fdo.c	Sun Aug 09 00:30:57 2009 +1000
     4.3 @@ -60,18 +60,6 @@ XenPci_MapHalThenPatchKernel(PXENPCI_DEV
     4.4    FUNCTION_EXIT();
     4.5  }
     4.6  
     4.7 -#if 0
     4.8 -PMDL
     4.9 -XenPCI_AllocMMIO(WDFDEVICE device, ULONG len)
    4.10 -{
    4.11 -  PMDL mdl = ExAllocatePoolWithTag(NonPagedPool, MmSizeOfMdl(0, len), XENPCI_POOL_TAG);
    4.12 -  PVOID va = MmAllocateMappingAddress(len, XENPCI_POOL_TAG);
    4.13 -  
    4.14 -  for (i = 0; i < ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, len);
    4.15 -  
    4.16 -}
    4.17 -#endif
    4.18 -
    4.19  /*
    4.20   * Alloc MMIO from the device's MMIO region. There is no corresponding free() fn
    4.21   */
    4.22 @@ -251,7 +239,6 @@ XenPci_BalloonThreadProc(PVOID StartCont
    4.23      KeWaitForSingleObject(&xpdd->balloon_event, Executive, KernelMode, FALSE, ptimeout);
    4.24      if (xpdd->balloon_shutdown)
    4.25        PsTerminateSystemThread(0);
    4.26 -//TODO: initiate shutdown here
    4.27      KdPrint((__DRIVER_NAME "     Got balloon event, current = %d, target = %d\n", xpdd->current_memory, xpdd->target_memory));
    4.28      /* not really worried about races here, but cache target so we only read it once */
    4.29      new_target = xpdd->target_memory;
    4.30 @@ -350,8 +337,6 @@ XenPci_BalloonHandler(char *Path, PVOID 
    4.31  
    4.32    KeSetEvent(&xpdd->balloon_event, IO_NO_INCREMENT, FALSE);
    4.33    
    4.34 -  // start a thread to allocate memory up to the required amount
    4.35 -
    4.36    FUNCTION_EXIT();
    4.37  }
    4.38  
    4.39 @@ -539,7 +524,7 @@ XenPci_DeviceWatchHandler(char *path, PV
    4.40    char *value;
    4.41    PXENPCI_DEVICE_DATA xpdd = context;
    4.42  
    4.43 -  //FUNCTION_ENTER();
    4.44 +  FUNCTION_ENTER();
    4.45  
    4.46    bits = SplitString(path, '/', 4, &count);
    4.47    if (count == 3)
    4.48 @@ -560,7 +545,7 @@ XenPci_DeviceWatchHandler(char *path, PV
    4.49    }
    4.50    FreeSplitString(bits, count);
    4.51  
    4.52 -  //FUNCTION_EXIT();
    4.53 +  FUNCTION_EXIT();
    4.54  }
    4.55  
    4.56  NTSTATUS
    4.57 @@ -646,7 +631,6 @@ XenPci_EvtDeviceD0Entry(WDFDEVICE device
    4.58    FUNCTION_ENTER();
    4.59  
    4.60    xpdd->hibernated = FALSE;
    4.61 -
    4.62    switch (previous_state)
    4.63    {
    4.64    case WdfPowerDeviceD0:
    4.65 @@ -676,23 +660,25 @@ XenPci_EvtDeviceD0Entry(WDFDEVICE device
    4.66    {
    4.67      XenPci_HideQemuDevices();
    4.68      ASSERT(qemu_filtered_by_qemu);
    4.69 -  } 
    4.70 +  }
    4.71    
    4.72 -  XenPci_Init(xpdd);
    4.73 -  if (tpr_patch_requested && !xpdd->tpr_patched)
    4.74 +  if (previous_state == WdfPowerDeviceD3Final)
    4.75    {
    4.76 -    XenPci_MapHalThenPatchKernel(xpdd);
    4.77 -    xpdd->tpr_patched = TRUE;
    4.78 -  }
    4.79 -  if (previous_state == WdfPowerDevicePrepareForHibernation)
    4.80 -  {
    4.81 -    GntTbl_Resume(xpdd);
    4.82 +    XenPci_Init(xpdd);
    4.83 +    if (tpr_patch_requested && !xpdd->tpr_patched)
    4.84 +    {
    4.85 +      XenPci_MapHalThenPatchKernel(xpdd);
    4.86 +      xpdd->tpr_patched = TRUE;
    4.87 +    }
    4.88 +    GntTbl_Init(xpdd);
    4.89 +    EvtChn_Init(xpdd);
    4.90    }
    4.91    else
    4.92    {
    4.93 -    GntTbl_Init(xpdd);
    4.94 +    XenPci_Resume(xpdd);
    4.95 +    GntTbl_Resume(xpdd);
    4.96 +    EvtChn_Resume(xpdd);
    4.97    }
    4.98 -  EvtChn_Init(xpdd);
    4.99  
   4.100    FUNCTION_EXIT();
   4.101  
   4.102 @@ -714,47 +700,54 @@ XenPci_EvtDeviceD0EntryPostInterruptsEna
   4.103    UNREFERENCED_PARAMETER(previous_state);
   4.104  
   4.105    FUNCTION_ENTER();
   4.106 -  
   4.107 -  XenBus_Init(xpdd);
   4.108 -
   4.109 -  XenPci_ConnectSuspendEvt(xpdd);
   4.110 -  
   4.111 -  response = XenBus_AddWatch(xpdd, XBT_NIL, SYSRQ_PATH, XenPci_SysrqHandler, xpdd);
   4.112 -  
   4.113 -  response = XenBus_AddWatch(xpdd, XBT_NIL, SHUTDOWN_PATH, XenPci_ShutdownHandler, device);
   4.114  
   4.115 -  response = XenBus_AddWatch(xpdd, XBT_NIL, "device", XenPci_DeviceWatchHandler, xpdd);
   4.116 +  if (previous_state == WdfPowerDeviceD3Final)
   4.117 +  {  
   4.118 +    XenBus_Init(xpdd);
   4.119  
   4.120 -  ret = HYPERVISOR_memory_op(xpdd, XENMEM_current_reservation, &domid);
   4.121 -  KdPrint((__DRIVER_NAME "     XENMEM_current_reservation = %d\n", ret));
   4.122 -  ret = HYPERVISOR_memory_op(xpdd, XENMEM_maximum_reservation, &domid);
   4.123 -  KdPrint((__DRIVER_NAME "     XENMEM_maximum_reservation = %d\n", ret));
   4.124 -  ret = HYPERVISOR_memory_op(xpdd, XENMEM_maximum_ram_page, &max_ram_page);
   4.125 -  KdPrint((__DRIVER_NAME "     XENMEM_maximum_ram_page = %d\n", ret));
   4.126 +    XenPci_ConnectSuspendEvt(xpdd);
   4.127 +    
   4.128 +    response = XenBus_AddWatch(xpdd, XBT_NIL, SYSRQ_PATH, XenPci_SysrqHandler, xpdd);
   4.129 +    
   4.130 +    response = XenBus_AddWatch(xpdd, XBT_NIL, SHUTDOWN_PATH, XenPci_ShutdownHandler, device);
   4.131  
   4.132 -  if (!xpdd->initial_memory)
   4.133 +    response = XenBus_AddWatch(xpdd, XBT_NIL, "device", XenPci_DeviceWatchHandler, xpdd);
   4.134 +
   4.135 +    ret = HYPERVISOR_memory_op(xpdd, XENMEM_current_reservation, &domid);
   4.136 +    KdPrint((__DRIVER_NAME "     XENMEM_current_reservation = %d\n", ret));
   4.137 +    ret = HYPERVISOR_memory_op(xpdd, XENMEM_maximum_reservation, &domid);
   4.138 +    KdPrint((__DRIVER_NAME "     XENMEM_maximum_reservation = %d\n", ret));
   4.139 +    ret = HYPERVISOR_memory_op(xpdd, XENMEM_maximum_ram_page, &max_ram_page);
   4.140 +    KdPrint((__DRIVER_NAME "     XENMEM_maximum_ram_page = %d\n", ret));
   4.141 +
   4.142 +    if (!xpdd->initial_memory)
   4.143 +    {
   4.144 +      XenBus_Read(xpdd, XBT_NIL, BALLOON_PATH, &value);
   4.145 +      if (atoi(value) > 0)
   4.146 +      {
   4.147 +        xpdd->initial_memory = atoi(value) >> 10; /* convert to MB */
   4.148 +        xpdd->current_memory = xpdd->initial_memory;
   4.149 +        xpdd->target_memory = xpdd->initial_memory;
   4.150 +      }
   4.151 +      KdPrint((__DRIVER_NAME "     Initial Memory Value = %d (%s)\n", xpdd->initial_memory, value));
   4.152 +      KeInitializeEvent(&xpdd->balloon_event, SynchronizationEvent, FALSE);
   4.153 +      xpdd->balloon_shutdown = FALSE;
   4.154 +      status = PsCreateSystemThread(&thread_handle, THREAD_ALL_ACCESS, NULL, NULL, NULL, XenPci_BalloonThreadProc, xpdd);
   4.155 +      if (!NT_SUCCESS(status))
   4.156 +      {
   4.157 +        KdPrint((__DRIVER_NAME "     Could not start balloon thread\n"));
   4.158 +        return status;
   4.159 +      }
   4.160 +      status = ObReferenceObjectByHandle(thread_handle, THREAD_ALL_ACCESS, NULL, KernelMode, &xpdd->balloon_thread, NULL);
   4.161 +      ZwClose(thread_handle);
   4.162 +    }
   4.163 +    response = XenBus_AddWatch(xpdd, XBT_NIL, BALLOON_PATH, XenPci_BalloonHandler, device);
   4.164 +  }
   4.165 +  else
   4.166    {
   4.167 -    XenBus_Read(xpdd, XBT_NIL, BALLOON_PATH, &value);
   4.168 -    if (atoi(value) > 0)
   4.169 -    {
   4.170 -      xpdd->initial_memory = atoi(value) >> 10; /* convert to MB */
   4.171 -      xpdd->current_memory = xpdd->initial_memory;
   4.172 -      xpdd->target_memory = xpdd->initial_memory;
   4.173 -    }
   4.174 -    KdPrint((__DRIVER_NAME "     Initial Memory Value = %d (%s)\n", xpdd->initial_memory, value));
   4.175 -    KeInitializeEvent(&xpdd->balloon_event, SynchronizationEvent, FALSE);
   4.176 -    xpdd->balloon_shutdown = FALSE;
   4.177 -    status = PsCreateSystemThread(&thread_handle, THREAD_ALL_ACCESS, NULL, NULL, NULL, XenPci_BalloonThreadProc, xpdd);
   4.178 -    if (!NT_SUCCESS(status))
   4.179 -    {
   4.180 -      KdPrint((__DRIVER_NAME "     Could not start balloon thread\n"));
   4.181 -      return status;
   4.182 -    }
   4.183 -    status = ObReferenceObjectByHandle(thread_handle, THREAD_ALL_ACCESS, NULL, KernelMode, &xpdd->balloon_thread, NULL);
   4.184 -    ZwClose(thread_handle);
   4.185 +    XenBus_Resume(xpdd);
   4.186 +    XenPci_ConnectSuspendEvt(xpdd);
   4.187    }
   4.188 -  response = XenBus_AddWatch(xpdd, XBT_NIL, BALLOON_PATH, XenPci_BalloonHandler, device);
   4.189 -
   4.190    FUNCTION_EXIT();
   4.191    
   4.192    return status;
   4.193 @@ -793,19 +786,28 @@ XenPci_EvtDeviceD0ExitPreInterruptsDisab
   4.194      KdPrint((__DRIVER_NAME "     Unknown WdfPowerDevice state %d\n", target_state));
   4.195      break;  
   4.196    }
   4.197 -  
   4.198 -  xpdd->balloon_shutdown = TRUE;
   4.199 -  KeSetEvent(&xpdd->balloon_event, IO_NO_INCREMENT, FALSE);
   4.200 +
   4.201 +  if (target_state == WdfPowerDeviceD3Final)
   4.202 +  {
   4.203 +    KdPrint((__DRIVER_NAME "     Shutting down threads\n"));
   4.204 +
   4.205 +    xpdd->balloon_shutdown = TRUE;
   4.206 +    KeSetEvent(&xpdd->balloon_event, IO_NO_INCREMENT, FALSE);
   4.207    
   4.208 -  timeout.QuadPart = (LONGLONG)-1 * 1000 * 1000 * 10;
   4.209 -  while ((status = KeWaitForSingleObject(xpdd->balloon_thread, Executive, KernelMode, FALSE, &timeout)) != STATUS_SUCCESS)
   4.210 -  {
   4.211      timeout.QuadPart = (LONGLONG)-1 * 1000 * 1000 * 10;
   4.212 -    KdPrint((__DRIVER_NAME "     Waiting for balloon thread to stop\n"));
   4.213 +    while ((status = KeWaitForSingleObject(xpdd->balloon_thread, Executive, KernelMode, FALSE, &timeout)) != STATUS_SUCCESS)
   4.214 +    {
   4.215 +      timeout.QuadPart = (LONGLONG)-1 * 1000 * 1000 * 10;
   4.216 +      KdPrint((__DRIVER_NAME "     Waiting for balloon thread to stop\n"));
   4.217 +    }
   4.218 +    ObDereferenceObject(xpdd->balloon_thread);
   4.219 +
   4.220 +    XenBus_Halt(xpdd);
   4.221    }
   4.222 -  ObDereferenceObject(xpdd->balloon_thread);
   4.223 -
   4.224 -  XenBus_Halt(xpdd);
   4.225 +  else
   4.226 +  {
   4.227 +    XenBus_Suspend(xpdd);
   4.228 +  }
   4.229    
   4.230    FUNCTION_EXIT();
   4.231    
   4.232 @@ -846,7 +848,11 @@ XenPci_EvtDeviceD0Exit(WDFDEVICE device,
   4.233      break;  
   4.234    }
   4.235    
   4.236 -  if (target_state == WdfPowerDevicePrepareForHibernation)
   4.237 +  if (target_state == WdfPowerDeviceD3Final)
   4.238 +  {
   4.239 +    /* we don't really support exit here */
   4.240 +  }
   4.241 +  else
   4.242    {
   4.243      GntTbl_Suspend(xpdd);
   4.244    }
   4.245 @@ -870,6 +876,7 @@ XenPci_EvtDeviceReleaseHardware(WDFDEVIC
   4.246    return status;
   4.247  }
   4.248  
   4.249 +/* Called at PASSIVE_LEVEL but with pagefile unavailable */
   4.250  VOID
   4.251  XenPci_EvtChildListScanForChildren(WDFCHILDLIST child_list)
   4.252  {
   4.253 @@ -881,6 +888,7 @@ XenPci_EvtChildListScanForChildren(WDFCH
   4.254    ULONG i, j;
   4.255    CHAR path[128];
   4.256    XENPCI_PDO_IDENTIFICATION_DESCRIPTION child_description;
   4.257 +  PVOID entry;
   4.258    
   4.259    FUNCTION_ENTER();
   4.260  
   4.261 @@ -892,22 +900,12 @@ XenPci_EvtChildListScanForChildren(WDFCH
   4.262      for (i = 0; devices[i]; i++)
   4.263      {
   4.264        RtlStringCbPrintfA(path, ARRAY_SIZE(path), "device/%s", devices[i]);
   4.265 -      
   4.266 -      for (j = 0; j < WdfCollectionGetCount(xpdd->veto_devices); j++)
   4.267 +      for (entry = xpdd->veto_list.Flink; entry != &xpdd->veto_list; entry = ((PLIST_ENTRY)entry)->Flink)
   4.268        {
   4.269 -        WDFOBJECT ws = WdfCollectionGetItem(xpdd->veto_devices, j);
   4.270 -        UNICODE_STRING val;
   4.271 -        ANSI_STRING s;
   4.272 -        WdfStringGetUnicodeString(ws, &val);
   4.273 -        RtlUnicodeStringToAnsiString(&s, &val, TRUE);
   4.274 -        if (!strcmp(devices[i], s.Buffer))
   4.275 -        {
   4.276 -          RtlFreeAnsiString(&s);
   4.277 +        if (!strcmp(devices[i], (PCHAR)entry + sizeof(LIST_ENTRY)))
   4.278            break;
   4.279 -        }
   4.280 -        RtlFreeAnsiString(&s);
   4.281        }
   4.282 -      if (j < WdfCollectionGetCount(xpdd->veto_devices))
   4.283 +      if (entry != &xpdd->veto_list)
   4.284        {
   4.285          XenPci_FreeMem(devices[i]);
   4.286          continue;
   4.287 @@ -950,6 +948,6 @@ XenPci_EvtChildListScanForChildren(WDFCH
   4.288    }
   4.289  
   4.290    WdfChildListEndScan(child_list);
   4.291 -  
   4.292 +
   4.293    FUNCTION_EXIT();
   4.294  }
     5.1 --- a/xenpci/xenpci_pdo.c	Sat Aug 08 20:55:53 2009 +1000
     5.2 +++ b/xenpci/xenpci_pdo.c	Sun Aug 09 00:30:57 2009 +1000
     5.3 @@ -684,14 +684,6 @@ XenPci_DOP_BuildScatterGatherListButDont
     5.4    {    
     5.5      for (curr_mdl = Mdl, sglist->NumberOfElements = 0, total_remaining = Length, active = FALSE; total_remaining > 0; curr_mdl = curr_mdl->Next)
     5.6      {
     5.7 -      if (!curr_mdl)
     5.8 -      {
     5.9 -      KdPrint((__DRIVER_NAME "     CurrentVa = %p, Length = %d\n", CurrentVa, Length));
    5.10 -for (curr_mdl = Mdl; curr_mdl; curr_mdl = curr_mdl->Next)
    5.11 -{
    5.12 -  KdPrint((__DRIVER_NAME "     Mdl = %p, VirtualAddress = %p, ByteCount = %d\n", Mdl, MmGetMdlVirtualAddress(curr_mdl), MmGetMdlByteCount(curr_mdl)));
    5.13 -}
    5.14 -      }
    5.15        ASSERT(curr_mdl);
    5.16        mdl_start_va = MmGetMdlVirtualAddress(curr_mdl);
    5.17        mdl_byte_count = MmGetMdlByteCount(curr_mdl);
    5.18 @@ -1126,7 +1118,6 @@ XenPci_BIS_GetBusData(PVOID context, ULO
    5.19  Called at PASSIVE_LEVEL(?)
    5.20  Called during restore
    5.21  */
    5.22 -
    5.23  static ULONG
    5.24  XenPci_ReadBackendState(PXENPCI_PDO_DEVICE_DATA xppdd)
    5.25  {
    5.26 @@ -1167,7 +1158,7 @@ XenPciPdo_ReconfigureCompletionRoutine(
    5.27  }
    5.28  
    5.29  static VOID
    5.30 -XenPci_BackEndStateHandler(char *path, PVOID context)
    5.31 +XenPci_UpdateBackendState(PVOID context)
    5.32  {
    5.33    WDFDEVICE device = context;
    5.34    PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
    5.35 @@ -1175,27 +1166,26 @@ XenPci_BackEndStateHandler(char *path, P
    5.36    ULONG new_backend_state;
    5.37    CHAR tmp_path[128];
    5.38  
    5.39 -#if !DBG
    5.40 -  UNREFERENCED_PARAMETER(path);
    5.41 -#endif
    5.42 -  
    5.43 -  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    5.44 +  FUNCTION_ENTER();
    5.45  
    5.46 -  /* check that path == device/id/state */
    5.47 -  //RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
    5.48 +  ExAcquireFastMutex(&xppdd->backend_state_mutex);
    5.49 +
    5.50    new_backend_state = XenPci_ReadBackendState(xppdd);
    5.51    if (new_backend_state == XenbusStateUnknown)
    5.52    {
    5.53      if (xpdd->suspend_state != SUSPEND_STATE_NONE)
    5.54 +    {
    5.55 +      ExReleaseFastMutex(&xppdd->backend_state_mutex);
    5.56        return;
    5.57 -    KdPrint(("Failed to read %s, assuming closed\n", path));
    5.58 +    }
    5.59 +    KdPrint(("Failed to read path, assuming closed\n"));
    5.60      new_backend_state = XenbusStateClosed;
    5.61    }
    5.62  
    5.63    if (xppdd->backend_state == new_backend_state)
    5.64    {
    5.65      KdPrint((__DRIVER_NAME "     state unchanged\n"));
    5.66 -    //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    5.67 +    ExReleaseFastMutex(&xppdd->backend_state_mutex);
    5.68      return;
    5.69    }
    5.70  
    5.71 @@ -1204,27 +1194,27 @@ XenPci_BackEndStateHandler(char *path, P
    5.72    switch (xppdd->backend_state)
    5.73    {
    5.74    case XenbusStateUnknown:
    5.75 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Unknown (%s)\n", path));  
    5.76 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Unknown\n"));
    5.77      break;
    5.78  
    5.79    case XenbusStateInitialising:
    5.80 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialising (%s)\n", path));  
    5.81 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialising\n"));
    5.82      break;
    5.83  
    5.84    case XenbusStateInitWait:
    5.85 -    KdPrint((__DRIVER_NAME "     Backend State Changed to InitWait (%s)\n", path));  
    5.86 +    KdPrint((__DRIVER_NAME "     Backend State Changed to InitWait\n"));
    5.87      break;
    5.88  
    5.89    case XenbusStateInitialised:
    5.90 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialised (%s)\n", path));  
    5.91 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialised\n"));
    5.92      break;
    5.93  
    5.94    case XenbusStateConnected:
    5.95 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Connected (%s)\n", path));    
    5.96 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Connected\n"));  
    5.97      break;
    5.98  
    5.99    case XenbusStateClosing:
   5.100 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Closing (%s)\n", path));
   5.101 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Closing\n"));
   5.102      if (xppdd->frontend_state == XenbusStateConnected)
   5.103      {
   5.104        KdPrint((__DRIVER_NAME "     Requesting eject\n"));
   5.105 @@ -1233,18 +1223,18 @@ XenPci_BackEndStateHandler(char *path, P
   5.106      break;
   5.107  
   5.108    case XenbusStateClosed:
   5.109 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Closed (%s)\n", path));  
   5.110 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Closed\n"));
   5.111      break;
   5.112  
   5.113    case XenbusStateReconfiguring:
   5.114 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Reconfiguring (%s)\n", path));  
   5.115 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Reconfiguring\n"));
   5.116      RtlStringCbPrintfA(tmp_path, ARRAY_SIZE(tmp_path), "%s/state", xppdd->path);
   5.117      KdPrint((__DRIVER_NAME "     Setting %s to %d\n", tmp_path, XenbusStateReconfiguring));
   5.118      XenBus_Printf(xpdd, XBT_NIL, tmp_path, "%d", XenbusStateReconfiguring);
   5.119      break;
   5.120  
   5.121    case XenbusStateReconfigured:
   5.122 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Reconfigured (%s)\n", path));
   5.123 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Reconfigured\n"));
   5.124    {
   5.125      PDEVICE_OBJECT fdo;
   5.126      PIRP irp;
   5.127 @@ -1289,17 +1279,29 @@ XenPci_BackEndStateHandler(char *path, P
   5.128    }
   5.129    
   5.130    default:
   5.131 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Undefined = %d (%s)\n", xppdd->backend_state, path));
   5.132 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Undefined = %d\n", xppdd->backend_state));
   5.133      break;
   5.134    }
   5.135  
   5.136    KeSetEvent(&xppdd->backend_state_event, 1, FALSE);
   5.137  
   5.138 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.139 +  ExReleaseFastMutex(&xppdd->backend_state_mutex);
   5.140 +  FUNCTION_EXIT();
   5.141  
   5.142    return;
   5.143  }
   5.144  
   5.145 +static VOID
   5.146 +XenPci_BackendStateHandler(char *path, PVOID context)
   5.147 +{
   5.148 +  UNREFERENCED_PARAMETER(path);
   5.149 +
   5.150 +  /* check that path == device/id/state */
   5.151 +  //RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
   5.152 +
   5.153 +  XenPci_UpdateBackendState(context);
   5.154 +}
   5.155 +
   5.156  static NTSTATUS
   5.157  XenPci_GetBackendAndAddWatch(WDFDEVICE device)
   5.158  {
   5.159 @@ -1309,6 +1311,7 @@ XenPci_GetBackendAndAddWatch(WDFDEVICE d
   5.160    PCHAR res;
   5.161    PCHAR value;
   5.162  
   5.163 +  FUNCTION_ENTER();
   5.164    /* Get backend path */
   5.165    RtlStringCbPrintfA(path, ARRAY_SIZE(path),
   5.166      "%s/backend", xppdd->path);
   5.167 @@ -1324,8 +1327,9 @@ XenPci_GetBackendAndAddWatch(WDFDEVICE d
   5.168  
   5.169    /* Add watch on backend state */
   5.170    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
   5.171 -  XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, device);
   5.172 -  
   5.173 +  XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackendStateHandler, device);
   5.174 +
   5.175 +  FUNCTION_EXIT();  
   5.176    return STATUS_SUCCESS;
   5.177  }
   5.178  
   5.179 @@ -1612,7 +1616,7 @@ XenPci_ChangeFrontendState(WDFDEVICE dev
   5.180    ULONG thiswait;
   5.181    char path[128];
   5.182    
   5.183 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   5.184 +  FUNCTION_ENTER();
   5.185    
   5.186    xppdd->frontend_state = frontend_state_set;
   5.187  
   5.188 @@ -1627,6 +1631,8 @@ XenPci_ChangeFrontendState(WDFDEVICE dev
   5.189      timeout.QuadPart = (LONGLONG)-1 * thiswait * 1000 * 10;
   5.190      if (KeWaitForSingleObject(&xppdd->backend_state_event, Executive, KernelMode, FALSE, &timeout) == STATUS_TIMEOUT)
   5.191      {
   5.192 +      /* it's possible that the workitems are blocked because the pagefile isn't available. Lets just re-read the backend value for now */
   5.193 +      XenPci_UpdateBackendState(device);
   5.194        remaining -= thiswait;
   5.195        if (remaining == 0)
   5.196        {
   5.197 @@ -1636,7 +1642,7 @@ XenPci_ChangeFrontendState(WDFDEVICE dev
   5.198        KdPrint((__DRIVER_NAME "     Still waiting for %d (currently %d)...\n", backend_state_response, xppdd->backend_state));
   5.199      }
   5.200    }
   5.201 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.202 +  FUNCTION_EXIT();
   5.203    return STATUS_SUCCESS;
   5.204  }
   5.205  
   5.206 @@ -1774,7 +1780,6 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
   5.207    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_VECTORS, NULL, &vectors, NULL);
   5.208    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_STATE_PTR, NULL, &xppdd->device_state, NULL);
   5.209  
   5.210 -
   5.211    if (!qemu_filtered)
   5.212      active = FALSE;
   5.213  
   5.214 @@ -1842,7 +1847,6 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
   5.215    in_ptr = src;
   5.216    while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
   5.217    {
   5.218 -  
   5.219      if (!done_xenbus_init)
   5.220      {
   5.221        if (XenPci_ChangeFrontendState(device, XenbusStateInitialising, XenbusStateInitWait, 2000) != STATUS_SUCCESS)
   5.222 @@ -2103,7 +2107,7 @@ XenPciPdo_EvtDeviceWdmIrpPreprocess_STAR
   5.223          if (!NT_SUCCESS(status))
   5.224          {
   5.225            RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
   5.226 -          XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, device);
   5.227 +          XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackendStateHandler, device);
   5.228            FUNCTION_ERROR_EXIT();
   5.229            return status;
   5.230          }
   5.231 @@ -2237,7 +2241,7 @@ XenPciPdo_EvtDeviceD0Entry(WDFDEVICE dev
   5.232    if (!NT_SUCCESS(status))
   5.233    {
   5.234      RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
   5.235 -    XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, device);
   5.236 +    XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackendStateHandler, device);
   5.237      WdfDeviceSetFailed(device, WdfDeviceFailedNoRestart);
   5.238      FUNCTION_ERROR_EXIT();
   5.239      return status;
   5.240 @@ -2299,7 +2303,7 @@ XenPciPdo_EvtDeviceD0Exit(WDFDEVICE devi
   5.241      status = XenPci_XenShutdownDevice(device);
   5.242      /* Remove watch on backend state */
   5.243      RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
   5.244 -    XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, device);
   5.245 +    XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackendStateHandler, device);
   5.246    }
   5.247    FUNCTION_EXIT();
   5.248    
   5.249 @@ -2515,6 +2519,7 @@ XenPci_EvtChildListCreateDevice(WDFCHILD
   5.250    RtlStringCbCopyA(xppdd->device, ARRAY_SIZE(xppdd->device), identification->device);
   5.251    xppdd->index = identification->index;
   5.252    KeInitializeEvent(&xppdd->backend_state_event, SynchronizationEvent, FALSE);
   5.253 +  ExInitializeFastMutex(&xppdd->backend_state_mutex);
   5.254    xppdd->backend_state = XenbusStateUnknown;
   5.255    xppdd->frontend_state = XenbusStateUnknown;
   5.256    xppdd->backend_path[0] = '\0';
   5.257 @@ -2591,7 +2596,7 @@ XenPci_Pdo_Suspend(WDFDEVICE device)
   5.258      }
   5.259  
   5.260      RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
   5.261 -    XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);  
   5.262 +    XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackendStateHandler, xppdd);  
   5.263    }
   5.264    else
   5.265    {