win-pvdrivers

changeset 551:a88fe72e3597

Tidied up gnttbl code. Better detection of crash dumps. Better behaviour when qemu hiding doesn't work.
author James Harper <james.harper@bendigoit.com.au>
date Sat Mar 28 10:07:53 2009 +1100 (2009-03-28)
parents ba13311350b9
children 069658b9c8ee
files xenpci/gnttbl.c xenpci/xenpci.h xenpci/xenpci.inx xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c
line diff
     1.1 --- a/xenpci/gnttbl.c	Sat Mar 28 10:06:11 2009 +1100
     1.2 +++ b/xenpci/gnttbl.c	Sat Mar 28 10:07:53 2009 +1100
     1.3 @@ -23,18 +23,18 @@ VOID
     1.4  GntTbl_PutRef(PVOID Context, grant_ref_t ref)
     1.5  {
     1.6    PXENPCI_DEVICE_DATA xpdd = Context;
     1.7 -  KIRQL OldIrql = PASSIVE_LEVEL;
     1.8 +  KIRQL old_irql = 0; /* prevents compiler warnings due to Acquire done in if statement */
     1.9  
    1.10    if (xpdd->suspend_state != SUSPEND_STATE_HIGH_IRQL)
    1.11    {
    1.12      ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    1.13 -    KeAcquireSpinLock(&xpdd->grant_lock, &OldIrql);
    1.14 +    KeAcquireSpinLock(&xpdd->grant_lock, &old_irql);
    1.15    }
    1.16    xpdd->gnttab_list[xpdd->gnttab_list_free] = ref;
    1.17    xpdd->gnttab_list_free++;
    1.18    if (xpdd->suspend_state != SUSPEND_STATE_HIGH_IRQL)
    1.19    {
    1.20 -    KeReleaseSpinLock(&xpdd->grant_lock, OldIrql);
    1.21 +    KeReleaseSpinLock(&xpdd->grant_lock, old_irql);
    1.22    }
    1.23  }
    1.24  
    1.25 @@ -43,27 +43,25 @@ GntTbl_GetRef(PVOID Context)
    1.26  {
    1.27    PXENPCI_DEVICE_DATA xpdd = Context;
    1.28    unsigned int ref;
    1.29 -  KIRQL OldIrql = PASSIVE_LEVEL;
    1.30 +  KIRQL old_irql = 0; /* prevents compiler warnings due to Acquire done in if statement */
    1.31    int suspend_state = xpdd->suspend_state;
    1.32    
    1.33 -  UNREFERENCED_PARAMETER(OldIrql);
    1.34 -
    1.35    if (suspend_state != SUSPEND_STATE_HIGH_IRQL)
    1.36    {
    1.37      ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    1.38 -    KeAcquireSpinLock(&xpdd->grant_lock, &OldIrql);
    1.39 +    KeAcquireSpinLock(&xpdd->grant_lock, &old_irql);
    1.40    }
    1.41    if (!xpdd->gnttab_list_free)
    1.42    {
    1.43      if (suspend_state != SUSPEND_STATE_HIGH_IRQL)
    1.44 -      KeReleaseSpinLock(&xpdd->grant_lock, OldIrql);
    1.45 +      KeReleaseSpinLock(&xpdd->grant_lock, old_irql);
    1.46      KdPrint((__DRIVER_NAME "     No free grant refs\n"));    
    1.47      return INVALID_GRANT_REF;
    1.48    }
    1.49    xpdd->gnttab_list_free--;
    1.50    ref = xpdd->gnttab_list[xpdd->gnttab_list_free];
    1.51    if (suspend_state != SUSPEND_STATE_HIGH_IRQL)
    1.52 -    KeReleaseSpinLock(&xpdd->grant_lock, OldIrql);
    1.53 +    KeReleaseSpinLock(&xpdd->grant_lock, old_irql);
    1.54  
    1.55    return ref;
    1.56  }
     2.1 --- a/xenpci/xenpci.h	Sat Mar 28 10:06:11 2009 +1100
     2.2 +++ b/xenpci/xenpci.h	Sat Mar 28 10:07:53 2009 +1100
     2.3 @@ -222,6 +222,7 @@ typedef struct {
     2.4    KEVENT backend_state_event;
     2.5    ULONG backend_state;
     2.6    ULONG frontend_state;
     2.7 +  PMDL config_page_mdl;
     2.8    PHYSICAL_ADDRESS config_page_phys;
     2.9    ULONG config_page_length;
    2.10    PUCHAR requested_resources_start;
     3.1 --- a/xenpci/xenpci.inx	Sat Mar 28 10:06:11 2009 +1100
     3.2 +++ b/xenpci/xenpci.inx	Sat Mar 28 10:07:53 2009 +1100
     3.3 @@ -61,6 +61,7 @@ DelReg         = XenHide_Service_DelReg
     3.4  [XenPci_Service_AddReg]
     3.5  HKR,"Parameters", "veto_devices", 0x00010008, "console"
     3.6  HKR,"Parameters", "veto_devices", 0x00010008, "vfb"
     3.7 +HKR,"Parameters", "veto_devices", 0x00010008, "vkbd"
     3.8  
     3.9  [XenHide_Service_DelReg]
    3.10  HKLM,SYSTEM\CurrentControlSet\Control\Class\{4D36E97D-E325-11CE-BFC1-08002BE10318},UpperFilters
     4.1 --- a/xenpci/xenpci_fdo.c	Sat Mar 28 10:06:11 2009 +1100
     4.2 +++ b/xenpci/xenpci_fdo.c	Sat Mar 28 10:07:53 2009 +1100
     4.3 @@ -239,7 +239,7 @@ XenPci_Suspend0(PVOID context)
     4.4    {
     4.5      XenPci_HideQemuDevices();
     4.6      ASSERT(qemu_filtered_by_qemu);
     4.7 -  } 
     4.8 +  }
     4.9  
    4.10    XenPci_Resume(xpdd);
    4.11    GntTbl_Resume(xpdd);
    4.12 @@ -330,6 +330,7 @@ XenPci_ShutdownHandler(char *path, PVOID
    4.13    {
    4.14      KdPrint(("Error reading shutdown path - %s\n", res));
    4.15      XenPci_FreeMem(res);
    4.16 +    FUNCTION_EXIT();
    4.17      return;
    4.18    }
    4.19  
    4.20 @@ -495,6 +496,12 @@ XenPci_EvtDeviceD0Entry(WDFDEVICE device
    4.21      KdPrint((__DRIVER_NAME "     Unknown WdfPowerDevice state %d\n", previous_state));
    4.22      break;  
    4.23    }
    4.24 +
    4.25 +  if (previous_state == WdfPowerDevicePrepareForHibernation && qemu_filtered_by_qemu)
    4.26 +  {
    4.27 +    XenPci_HideQemuDevices();
    4.28 +    ASSERT(qemu_filtered_by_qemu);
    4.29 +  } 
    4.30    
    4.31    XenPci_Init(xpdd);
    4.32    if (tpr_patch_requested && !xpdd->tpr_patched)
    4.33 @@ -502,7 +509,14 @@ XenPci_EvtDeviceD0Entry(WDFDEVICE device
    4.34      XenPci_MapHalThenPatchKernel(xpdd);
    4.35      xpdd->tpr_patched = TRUE;
    4.36    }
    4.37 -  GntTbl_Init(xpdd);
    4.38 +  if (previous_state == WdfPowerDevicePrepareForHibernation)
    4.39 +  {
    4.40 +    GntTbl_Resume(xpdd);
    4.41 +  }
    4.42 +  else
    4.43 +  {
    4.44 +    GntTbl_Init(xpdd);
    4.45 +  }
    4.46    EvtChn_Init(xpdd);
    4.47  
    4.48    FUNCTION_EXIT();
    4.49 @@ -625,6 +639,11 @@ XenPci_EvtDeviceD0Exit(WDFDEVICE device,
    4.50      KdPrint((__DRIVER_NAME "     Unknown WdfPowerDevice state %d\n", target_state));
    4.51      break;  
    4.52    }
    4.53 +  
    4.54 +  if (target_state == WdfPowerDevicePrepareForHibernation)
    4.55 +  {
    4.56 +    GntTbl_Suspend(xpdd);
    4.57 +  }
    4.58  
    4.59    FUNCTION_EXIT();
    4.60    
     5.1 --- a/xenpci/xenpci_pdo.c	Sat Mar 28 10:06:11 2009 +1100
     5.2 +++ b/xenpci/xenpci_pdo.c	Sat Mar 28 10:07:53 2009 +1100
     5.3 @@ -113,7 +113,9 @@ XenPci_DOP_AllocateCommonBuffer(
     5.4  
     5.5    pfn = (PFN_NUMBER)(MmGetPhysicalAddress(buffer).QuadPart >> PAGE_SHIFT);
     5.6    ASSERT(pfn); /* lazy */
     5.7 +  //KdPrint((__DRIVER_NAME "     A Requesting Grant Ref\n"));
     5.8    gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, INVALID_GRANT_REF);
     5.9 +  //KdPrint((__DRIVER_NAME "     A Got Grant Ref %d\n", gref));
    5.10    ASSERT(gref); /* lazy */
    5.11    LogicalAddress->QuadPart = (gref << PAGE_SHIFT) | (PtrToUlong(buffer) & (PAGE_SIZE - 1));
    5.12    
    5.13 @@ -142,7 +144,9 @@ XenPci_DOP_FreeCommonBuffer(
    5.14  
    5.15    xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
    5.16    gref = (grant_ref_t)(logical_address.QuadPart >> PAGE_SHIFT);
    5.17 +  //KdPrint((__DRIVER_NAME "     F Releasing Grant Ref %d\n", gref));
    5.18    GntTbl_EndAccess(xpdd, gref, FALSE);
    5.19 +  //KdPrint((__DRIVER_NAME "     F Released Grant Ref\n"));
    5.20    ExFreePoolWithTag(virtual_address, XENPCI_POOL_TAG);
    5.21  
    5.22  //  FUNCTION_EXIT();
    5.23 @@ -270,12 +274,16 @@ XenPci_DOP_FreeMapRegisters(
    5.24      {
    5.25      case MAP_TYPE_REMAPPED:
    5.26        gref = (grant_ref_t)(map_register->logical.QuadPart >> PAGE_SHIFT);
    5.27 +      //KdPrint((__DRIVER_NAME "     D Releasing Grant Ref %d\n", gref));
    5.28        GntTbl_EndAccess(xpdd, gref, FALSE);
    5.29 +      //KdPrint((__DRIVER_NAME "     D Released Grant Ref\n"));
    5.30        ExFreePoolWithTag(map_register->aligned_buffer, XENPCI_POOL_TAG);
    5.31        break;
    5.32      case MAP_TYPE_MDL:
    5.33        gref = (grant_ref_t)(map_register->logical.QuadPart >> PAGE_SHIFT);
    5.34 +      //KdPrint((__DRIVER_NAME "     E Releasing Grant Ref %d\n", gref));
    5.35        GntTbl_EndAccess(xpdd, gref, FALSE);
    5.36 +      //KdPrint((__DRIVER_NAME "     E Released Grant Ref\n"));
    5.37        break;
    5.38      case MAP_TYPE_VIRTUAL:
    5.39        break;
    5.40 @@ -350,22 +358,30 @@ XenPci_DOP_MapTransfer(
    5.41      //KdPrint((__DRIVER_NAME "     mdl_offset = %d, page_offset = %d, length = %d, pfn_index = %d\n",
    5.42      //  mdl_offset, page_offset, *Length, pfn_index));
    5.43      pfn = MmGetMdlPfnArray(mdl)[pfn_index];
    5.44 +    //KdPrint((__DRIVER_NAME "     B Requesting Grant Ref\n"));
    5.45      gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, INVALID_GRANT_REF);
    5.46 +    //KdPrint((__DRIVER_NAME "     B Got Grant Ref %d\n", gref));
    5.47      map_register->logical.QuadPart = (LONGLONG)(gref << PAGE_SHIFT) | page_offset;
    5.48      map_register_base->count++;
    5.49      break;
    5.50    case MAP_TYPE_REMAPPED:
    5.51 -    //KdPrint((__DRIVER_NAME "     MAP_TYPE_REMAPPED\n"));
    5.52 +    //KdPrint((__DRIVER_NAME "     MAP_TYPE_REMAPPED (MapTransfer)\n"));
    5.53 +    //KdPrint((__DRIVER_NAME "     Mdl = %p, MapRegisterBase = %p, MdlVa = %p, CurrentVa = %p, Length = %d\n",
    5.54 +    //  mdl, MapRegisterBase, MmGetMdlVirtualAddress(mdl), CurrentVa, *Length));
    5.55 +    mdl_offset = (ULONG)((ULONGLONG)CurrentVa - (ULONGLONG)MmGetMdlVirtualAddress(mdl));
    5.56      *Length = min(*Length, PAGE_SIZE);
    5.57      map_register->aligned_buffer = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
    5.58      ASSERT(map_register->aligned_buffer);
    5.59      map_register->unaligned_buffer = MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority);
    5.60      ASSERT(map_register->unaligned_buffer); /* lazy */
    5.61 +    map_register->unaligned_buffer = (PUCHAR)map_register->unaligned_buffer + mdl_offset;
    5.62      map_register->copy_length = *Length;
    5.63      if (WriteToDevice)
    5.64        memcpy(map_register->aligned_buffer, map_register->unaligned_buffer, map_register->copy_length);
    5.65      pfn = (PFN_NUMBER)(MmGetPhysicalAddress(map_register->aligned_buffer).QuadPart >> PAGE_SHIFT);
    5.66 +    //KdPrint((__DRIVER_NAME "     C Requesting Grant Ref\n"));
    5.67      gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, INVALID_GRANT_REF);
    5.68 +    //KdPrint((__DRIVER_NAME "     C Got Grant Ref %d\n", gref));
    5.69      map_register->logical.QuadPart = (LONGLONG)(gref << PAGE_SHIFT);
    5.70      map_register_base->count++;
    5.71      break;
    5.72 @@ -430,7 +446,7 @@ XenPci_DOP_GetScatterGatherList(
    5.73  
    5.74    FUNCTION_ENTER();
    5.75    FUNCTION_EXIT();
    5.76 -  return STATUS_SUCCESS;
    5.77 +  return STATUS_UNSUCCESSFUL;
    5.78  }
    5.79  
    5.80  static VOID
    5.81 @@ -1009,13 +1025,13 @@ XenPci_GetBackendAndAddWatch(WDFDEVICE d
    5.82    return STATUS_SUCCESS;
    5.83  }
    5.84  
    5.85 -static PMDL
    5.86 -XenConfig_MakeConfigPage(WDFDEVICE device)
    5.87 +static NTSTATUS
    5.88 +XenConfig_InitConfigPage(WDFDEVICE device)
    5.89  {
    5.90 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
    5.91    //PXENCONFIG_DEVICE_DATA xcdd = (PXENCONFIG_DEVICE_DATA)device_object->DeviceExtension;
    5.92    //PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
    5.93    //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    5.94 -  PMDL mdl;
    5.95    PUCHAR ptr;
    5.96    PDEVICE_OBJECT curr, prev;
    5.97    PDRIVER_OBJECT fdo_driver_object;
    5.98 @@ -1023,8 +1039,7 @@ XenConfig_MakeConfigPage(WDFDEVICE devic
    5.99    
   5.100    FUNCTION_ENTER();
   5.101    
   5.102 -  mdl = AllocateUncachedPage();
   5.103 -  ptr = MmGetMdlVirtualAddress(mdl);
   5.104 +  ptr = MmGetMdlVirtualAddress(xppdd->config_page_mdl);
   5.105    curr = IoGetAttachedDeviceReference(WdfDeviceWdmGetDeviceObject(device));
   5.106    //curr = WdfDeviceWdmGetAttachedDevice(device);
   5.107    while (curr != NULL)
   5.108 @@ -1049,7 +1064,7 @@ XenConfig_MakeConfigPage(WDFDEVICE devic
   5.109    
   5.110    FUNCTION_EXIT();
   5.111    
   5.112 -  return mdl;
   5.113 +  return STATUS_SUCCESS;
   5.114  }
   5.115  
   5.116  static NTSTATUS
   5.117 @@ -1402,8 +1417,8 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
   5.118    PCHAR res;
   5.119    PVOID address;
   5.120    UCHAR type;
   5.121 -  PUCHAR in_ptr; //, in_start;
   5.122 -  PUCHAR out_ptr; //, out_start;
   5.123 +  PUCHAR in_ptr;
   5.124 +  PUCHAR out_ptr;
   5.125    XENPCI_VECTORS vectors;
   5.126    ULONG event_channel;
   5.127    ULONG run_type = 0;
   5.128 @@ -1411,6 +1426,8 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
   5.129    grant_ref_t gref;
   5.130    BOOLEAN done_xenbus_init = FALSE;
   5.131    PVOID value2;
   5.132 +  BOOLEAN active = TRUE;
   5.133 +  BOOLEAN dont_config = FALSE;
   5.134   
   5.135    FUNCTION_ENTER();
   5.136  
   5.137 @@ -1447,21 +1464,83 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
   5.138    vectors.XenBus_AddWatch = XenPci_XenBus_AddWatch;
   5.139    vectors.XenBus_RemWatch = XenPci_XenBus_RemWatch;
   5.140  
   5.141 -  if (qemu_filtered)
   5.142 -    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_ACTIVE, NULL, NULL, NULL);
   5.143 -
   5.144    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION, NULL, UlongToPtr(qemu_protocol_version), NULL);
   5.145    
   5.146    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_VECTORS, NULL, &vectors, NULL);
   5.147    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_STATE_PTR, NULL, &xppdd->device_state, NULL);
   5.148  
   5.149 +
   5.150 +  if (!qemu_filtered)
   5.151 +    active = FALSE;
   5.152 +
   5.153 +  while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
   5.154 +  {
   5.155 +    BOOLEAN condition;
   5.156 +    PCHAR xb_value;
   5.157 +    switch (type)
   5.158 +    {
   5.159 +    case XEN_INIT_TYPE_MATCH_FRONT:
   5.160 +    case XEN_INIT_TYPE_MATCH_BACK:
   5.161 +      if (type == XEN_INIT_TYPE_MATCH_FRONT)
   5.162 +      {
   5.163 +        RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
   5.164 +      }
   5.165 +      else
   5.166 +      {
   5.167 +        RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->backend_path, setting);
   5.168 +      }
   5.169 +      KdPrint((__DRIVER_NAME "     testing path = %s\n", path));
   5.170 +      res = XenBus_Read(xpdd, XBT_NIL, path, &xb_value);
   5.171 +      if (res)
   5.172 +      {
   5.173 +        KdPrint((__DRIVER_NAME "     read failed (%s)\n", res));
   5.174 +        XenPci_FreeMem(res);
   5.175 +      }
   5.176 +      else
   5.177 +      {
   5.178 +        KdPrint((__DRIVER_NAME "     testing %s vs %s\n", xb_value, value));
   5.179 +        if (PtrToUlong(value2) & XEN_INIT_MATCH_TYPE_IF_MATCH)
   5.180 +          condition = (strcmp(xb_value, value) == 0)?TRUE:FALSE;
   5.181 +        else
   5.182 +          condition = (strcmp(xb_value, value) != 0)?TRUE:FALSE;
   5.183 +        KdPrint((__DRIVER_NAME "     condition = %d\n", condition));
   5.184 +  
   5.185 +        if ((PtrToUlong(value2) & XEN_INIT_MATCH_TYPE_ONLY_IF_QEMU_HIDE) && qemu_protocol_version && condition)
   5.186 +          condition = FALSE;
   5.187 +          
   5.188 +        if (condition)
   5.189 +        {
   5.190 +          if (PtrToUlong(value2) & XEN_INIT_MATCH_TYPE_SET_INACTIVE)
   5.191 +          {
   5.192 +            active = FALSE;
   5.193 +            KdPrint((__DRIVER_NAME "     set inactive\n"));
   5.194 +          }
   5.195 +          if (PtrToUlong(value2) & XEN_INIT_MATCH_TYPE_DONT_CONFIG)
   5.196 +          {
   5.197 +            dont_config = TRUE;
   5.198 +            KdPrint((__DRIVER_NAME "     set inactive with dont config\n"));
   5.199 +          }
   5.200 +        }
   5.201 +        XenPci_FreeMem(xb_value);
   5.202 +      }
   5.203 +      break;
   5.204 +    }
   5.205 +  }
   5.206 +  if (dont_config)
   5.207 +  {
   5.208 +    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
   5.209 +    FUNCTION_EXIT();
   5.210 +    return status;
   5.211 +  }
   5.212 +  
   5.213    // first pass, possibly before state == Connected
   5.214 +  in_ptr = src;
   5.215    while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
   5.216    {
   5.217    
   5.218      if (!done_xenbus_init)
   5.219      {
   5.220 -      if (XenPci_ChangeFrontendState(device, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
   5.221 +      if (XenPci_ChangeFrontendState(device, XenbusStateInitialising, XenbusStateInitWait, 2000) != STATUS_SUCCESS)
   5.222        {
   5.223          status = STATUS_UNSUCCESSFUL;
   5.224          goto error;
   5.225 @@ -1547,7 +1626,7 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
   5.226    // If XEN_INIT_TYPE_RUN was specified more than once then we skip XenbusStateInitialised here and go straight to XenbusStateConnected at the end
   5.227    if (run_type == 1)
   5.228    {
   5.229 -    if (XenPci_ChangeFrontendState(device, XenbusStateInitialised, XenbusStateConnected, 30000) != STATUS_SUCCESS)
   5.230 +    if (XenPci_ChangeFrontendState(device, XenbusStateInitialised, XenbusStateConnected, 2000) != STATUS_SUCCESS)
   5.231      {
   5.232        status = STATUS_UNSUCCESSFUL;
   5.233        goto error;
   5.234 @@ -1598,11 +1677,15 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
   5.235        break;
   5.236      }
   5.237    }
   5.238 +  if (active)
   5.239 +  {
   5.240 +    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_ACTIVE, NULL, NULL, NULL);
   5.241 +  }
   5.242    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
   5.243  
   5.244    if (run_type)
   5.245    {
   5.246 -    if (XenPci_ChangeFrontendState(device, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
   5.247 +    if (XenPci_ChangeFrontendState(device, XenbusStateConnected, XenbusStateConnected, 2000) != STATUS_SUCCESS)
   5.248      {
   5.249        status = STATUS_UNSUCCESSFUL;
   5.250        goto error;
   5.251 @@ -1610,11 +1693,10 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
   5.252    }
   5.253    FUNCTION_EXIT();
   5.254    return status;
   5.255 -  
   5.256 +
   5.257  error:
   5.258 -  XenPci_ChangeFrontendState(device, XenbusStateInitialising, XenbusStateInitWait, 30000);
   5.259 +  XenPci_ChangeFrontendState(device, XenbusStateInitialising, XenbusStateInitWait, 2000);
   5.260    FUNCTION_EXIT_STATUS(status);
   5.261 -
   5.262    return status;
   5.263  }
   5.264  
   5.265 @@ -1640,29 +1722,20 @@ XenPci_XenConfigDevice(WDFDEVICE device)
   5.266  static NTSTATUS
   5.267  XenPciPdo_EvtDeviceWdmIrpPreprocess_START_DEVICE(WDFDEVICE device, PIRP irp)
   5.268  {
   5.269 -  NTSTATUS status = STATUS_SUCCESS;
   5.270    PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
   5.271    PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
   5.272    PIO_STACK_LOCATION stack;
   5.273    PCM_PARTIAL_RESOURCE_LIST prl;
   5.274    PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
   5.275    ULONG i;
   5.276 -  char path[128];
   5.277 -  PMDL mdl;
   5.278 +  //char path[128];
   5.279 +  //PMDL mdl;
   5.280   
   5.281    FUNCTION_ENTER();
   5.282    KdPrint((__DRIVER_NAME "     %s\n", xppdd->path));
   5.283  
   5.284    stack = IoGetCurrentIrpStackLocation(irp);
   5.285  
   5.286 -  status = XenPci_GetBackendAndAddWatch(device);
   5.287 -  if (!NT_SUCCESS(status)) {
   5.288 -    FUNCTION_ERROR_EXIT();
   5.289 -    return status;
   5.290 -  }
   5.291 -
   5.292 -  mdl = XenConfig_MakeConfigPage(device);
   5.293 -  
   5.294    prl = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
   5.295    for (i = 0; i < prl->Count; i++)
   5.296    {
   5.297 @@ -1672,8 +1745,8 @@ XenPciPdo_EvtDeviceWdmIrpPreprocess_STAR
   5.298      case CmResourceTypeMemory:
   5.299        if (prd->u.Memory.Start.QuadPart == xpdd->platform_mmio_addr.QuadPart && prd->u.Memory.Length == 0)
   5.300        {
   5.301 -        prd->u.Memory.Start.QuadPart = MmGetMdlPfnArray(mdl)[0] << PAGE_SHIFT;
   5.302 -        prd->u.Memory.Length = MmGetMdlByteCount(mdl);
   5.303 +        prd->u.Memory.Start.QuadPart = MmGetMdlPfnArray(xppdd->config_page_mdl)[0] << PAGE_SHIFT;
   5.304 +        prd->u.Memory.Length = MmGetMdlByteCount(xppdd->config_page_mdl);
   5.305        }
   5.306        else if (prd->u.Memory.Start.QuadPart == xpdd->platform_mmio_addr.QuadPart + 1 && prd->u.Memory.Length == 0)
   5.307        {
   5.308 @@ -1703,9 +1776,9 @@ XenPciPdo_EvtDeviceWdmIrpPreprocess_STAR
   5.309        {
   5.310          if (prd->u.Memory.Length == 0)
   5.311          {
   5.312 -          KdPrint((__DRIVER_NAME "     pfn[0] = %08x\n", (ULONG)MmGetMdlPfnArray(mdl)[0]));
   5.313 -          prd->u.Memory.Start.QuadPart = (ULONGLONG)MmGetMdlPfnArray(mdl)[0] << PAGE_SHIFT;
   5.314 -          prd->u.Memory.Length = MmGetMdlByteCount(mdl);
   5.315 +          KdPrint((__DRIVER_NAME "     pfn[0] = %08x\n", (ULONG)MmGetMdlPfnArray(xppdd->config_page_mdl)[0]));
   5.316 +          prd->u.Memory.Start.QuadPart = (ULONGLONG)MmGetMdlPfnArray(xppdd->config_page_mdl)[0] << PAGE_SHIFT;
   5.317 +          prd->u.Memory.Length = MmGetMdlByteCount(xppdd->config_page_mdl);
   5.318            KdPrint((__DRIVER_NAME "     New Start = %08x%08x, Length = %d\n", prd->u.Memory.Start.HighPart, prd->u.Memory.Start.LowPart, prd->u.Memory.Length));
   5.319          }
   5.320          xppdd->config_page_phys = prd->u.Memory.Start;
   5.321 @@ -1713,6 +1786,7 @@ XenPciPdo_EvtDeviceWdmIrpPreprocess_STAR
   5.322          xppdd->requested_resources_start = xppdd->requested_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
   5.323          xppdd->assigned_resources_start = xppdd->assigned_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
   5.324          
   5.325 +#if 0
   5.326          status = XenPci_XenConfigDevice(device);
   5.327          if (!NT_SUCCESS(status))
   5.328          {
   5.329 @@ -1721,6 +1795,7 @@ XenPciPdo_EvtDeviceWdmIrpPreprocess_STAR
   5.330            FUNCTION_ERROR_EXIT();
   5.331            return status;
   5.332          }
   5.333 +#endif
   5.334        }
   5.335        else if (prd->u.Memory.Start.QuadPart == xpdd->platform_mmio_addr.QuadPart + 1 && prd->u.Memory.Length == 0)
   5.336        {
   5.337 @@ -1796,9 +1871,9 @@ NTSTATUS
   5.338  XenPciPdo_EvtDeviceD0Entry(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
   5.339  {
   5.340    NTSTATUS status = STATUS_SUCCESS;
   5.341 -  
   5.342 -  UNREFERENCED_PARAMETER(device);
   5.343 -  UNREFERENCED_PARAMETER(previous_state);
   5.344 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
   5.345 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
   5.346 +  CHAR path[128];
   5.347    
   5.348    FUNCTION_ENTER();
   5.349  
   5.350 @@ -1826,6 +1901,34 @@ XenPciPdo_EvtDeviceD0Entry(WDFDEVICE dev
   5.351      KdPrint((__DRIVER_NAME "     Unknown WdfPowerDevice state %d\n", previous_state));
   5.352      break;  
   5.353    }
   5.354 +  
   5.355 +  if (previous_state == WdfPowerDevicePrepareForHibernation
   5.356 +      || (previous_state == WdfPowerDeviceD3 && xppdd->hiber_usage_kludge))
   5.357 +  {
   5.358 +    KdPrint((__DRIVER_NAME "     starting up from hibernation\n"));
   5.359 +  }
   5.360 +  else
   5.361 +  {
   5.362 +  }
   5.363 +
   5.364 +  XenConfig_InitConfigPage(device);
   5.365 +
   5.366 +  status = XenPci_GetBackendAndAddWatch(device);
   5.367 +  if (!NT_SUCCESS(status))
   5.368 +  {
   5.369 +    WdfDeviceSetFailed(device, WdfDeviceFailedNoRestart);
   5.370 +    FUNCTION_ERROR_EXIT();
   5.371 +    return status;
   5.372 +  }
   5.373 +  status = XenPci_XenConfigDevice(device);
   5.374 +  if (!NT_SUCCESS(status))
   5.375 +  {
   5.376 +    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
   5.377 +    XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, device);
   5.378 +    WdfDeviceSetFailed(device, WdfDeviceFailedNoRestart);
   5.379 +    FUNCTION_ERROR_EXIT();
   5.380 +    return status;
   5.381 +  }
   5.382  
   5.383    FUNCTION_EXIT();
   5.384    
   5.385 @@ -1891,10 +1994,10 @@ XenPciPdo_EvtDeviceD0Exit(WDFDEVICE devi
   5.386  }
   5.387  
   5.388  NTSTATUS
   5.389 -XenPciPdo_EvtDevicePrepareHardware (WDFDEVICE device, WDFCMRESLIST resources_raw, WDFCMRESLIST resources_translated)
   5.390 +XenPciPdo_EvtDevicePrepareHardware(WDFDEVICE device, WDFCMRESLIST resources_raw, WDFCMRESLIST resources_translated)
   5.391  {
   5.392    NTSTATUS status = STATUS_SUCCESS;
   5.393 -  
   5.394 +
   5.395    UNREFERENCED_PARAMETER(device);
   5.396    UNREFERENCED_PARAMETER(resources_raw);
   5.397    UNREFERENCED_PARAMETER(resources_translated);
   5.398 @@ -2045,6 +2148,8 @@ XenPci_EvtChildListCreateDevice(WDFCHILD
   5.399    xppdd->wdf_device = child_device;
   5.400    xppdd->wdf_device_bus_fdo = WdfChildListGetDevice(child_list);
   5.401  
   5.402 +  xppdd->config_page_mdl = AllocateUncachedPage();
   5.403 +
   5.404    xppdd->device_state.magic = XEN_DEVICE_STATE_MAGIC;
   5.405    xppdd->device_state.length = sizeof(XENPCI_DEVICE_STATE);
   5.406    xppdd->device_state.suspend_resume_state_pdo = SR_STATE_RUNNING;
   5.407 @@ -3179,7 +3284,7 @@ XenPci_DumpPdoConfig(PDEVICE_OBJECT devi
   5.408  }
   5.409  
   5.410  static PMDL
   5.411 -XenConfig_MakeConfigPage(PDEVICE_OBJECT device_object)
   5.412 +XenConfig_MakeConfigPage(PDEVICE_OBJECT device_object, PMDL mdl)
   5.413  {
   5.414    //PXENCONFIG_DEVICE_DATA xcdd = (PXENCONFIG_DEVICE_DATA)device_object->DeviceExtension;
   5.415    //PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
   5.416 @@ -3190,7 +3295,6 @@ XenConfig_MakeConfigPage(PDEVICE_OBJECT 
   5.417    PDRIVER_OBJECT fdo_driver_object;
   5.418    PUCHAR fdo_driver_extension;
   5.419    
   5.420 -  mdl = AllocateUncachedPage();
   5.421    ptr = MmGetMdlVirtualAddress(mdl);
   5.422    curr = IoGetAttachedDeviceReference(device_object);
   5.423    while (curr != NULL)