win-pvdrivers

changeset 685:c13ccf5a629b

Fixed a bug in the dma routines which was causing memory corruption. In some cases when Windows gave an MDL that was longer than the buffer to be dma'd, the end of the buffer would be overwritten. The only time I am aware of this occuring is on one particular map in Call Of Duty 4.

Split out the dma routines from xenpci_pdo.c into xenpci_dma.c
author James Harper <james.harper@bendigoit.com.au>
date Wed Oct 14 14:46:39 2009 +1100 (2009-10-14)
parents ff8518224fff
children c548d9eb5107
files xenpci/sources xenpci/xenpci.h xenpci/xenpci_dma.c xenpci/xenpci_pdo.c
line diff
     1.1 --- a/xenpci/sources	Sun Oct 11 14:57:13 2009 +1100
     1.2 +++ b/xenpci/sources	Wed Oct 14 14:46:39 2009 +1100
     1.3 @@ -7,4 +7,4 @@ TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)
     1.4  AMD64_SOURCES=hypercall.asm
     1.5  I386_SOURCES=tpr_emulate.asm
     1.6  
     1.7 -SOURCES=xenpci.rc xenpci.c xenpci_fdo.c xenpci_pdo.c evtchn.c gnttbl.c xenbus.c memory.c xenpci_device_interface.c xenbus_device_interface.c xenpci_highsync.c xenpci_patch_kernel.c
     1.8 +SOURCES=xenpci.rc xenpci.c xenpci_fdo.c xenpci_pdo.c xenpci_dma.c evtchn.c gnttbl.c xenbus.c memory.c xenpci_device_interface.c xenbus_device_interface.c xenpci_highsync.c xenpci_patch_kernel.c
     2.1 --- a/xenpci/xenpci.h	Sun Oct 11 14:57:13 2009 +1100
     2.2 +++ b/xenpci/xenpci.h	Wed Oct 14 14:46:39 2009 +1100
     2.3 @@ -544,9 +544,14 @@ VOID
     2.4  GntTbl_PutRef(PVOID Context, grant_ref_t ref);
     2.5  grant_ref_t
     2.6  GntTbl_GetRef(PVOID Context);
     2.7 -#if 0
     2.8 -int 
     2.9 -GntTbl_Map(PVOID Context, unsigned int start_idx, unsigned int end_idx);
    2.10 -#endif
    2.11 +
    2.12 +BOOLEAN
    2.13 +XenPci_BIS_TranslateBusAddress(PVOID context, PHYSICAL_ADDRESS bus_address, ULONG length, PULONG address_space, PPHYSICAL_ADDRESS translated_address);
    2.14 +PDMA_ADAPTER
    2.15 +XenPci_BIS_GetDmaAdapter(PVOID context, PDEVICE_DESCRIPTION device_description, PULONG number_of_map_registers);
    2.16 +ULONG
    2.17 +XenPci_BIS_SetBusData(PVOID context, ULONG data_type, PVOID buffer, ULONG offset, ULONG length);
    2.18 +ULONG
    2.19 +XenPci_BIS_GetBusData(PVOID context, ULONG data_type, PVOID buffer, ULONG offset, ULONG length);
    2.20  
    2.21  #endif
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xenpci/xenpci_dma.c	Wed Oct 14 14:46:39 2009 +1100
     3.3 @@ -0,0 +1,1130 @@
     3.4 +/*
     3.5 +PV Drivers for Windows Xen HVM Domains
     3.6 +Copyright (C) 2009 James Harper
     3.7 +
     3.8 +This program is free software; you can redistribute it and/or
     3.9 +modify it under the terms of the GNU General Public License
    3.10 +as published by the Free Software Foundation; either version 2
    3.11 +of the License, or (at your option) any later version.
    3.12 +
    3.13 +This program is distributed in the hope that it will be useful,
    3.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.16 +GNU General Public License for more details.
    3.17 +
    3.18 +You should have received a copy of the GNU General Public License
    3.19 +along with this program; if not, write to the Free Software
    3.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    3.21 +*/
    3.22 +
    3.23 +#include "xenpci.h"
    3.24 +#include <stdlib.h>
    3.25 +#include <io/ring.h>
    3.26 +
    3.27 +#pragma warning(disable : 4200) // zero-sized array
    3.28 +#pragma warning(disable: 4127) // conditional expression is constant
    3.29 +
    3.30 +#define MAP_TYPE_VIRTUAL  1
    3.31 +#define MAP_TYPE_MDL      2
    3.32 +#define MAP_TYPE_REMAPPED 3
    3.33 +
    3.34 +typedef struct {
    3.35 +  ULONG map_type;
    3.36 +  PVOID aligned_buffer;
    3.37 +  ULONG copy_length;
    3.38 +  PMDL mdl;
    3.39 +  PVOID currentva;
    3.40 +  BOOLEAN allocated_by_me;
    3.41 +} sg_extra_t;
    3.42 +
    3.43 +typedef struct {
    3.44 +  ULONG map_type;
    3.45 +  PVOID aligned_buffer;
    3.46 +  PVOID unaligned_buffer;
    3.47 +  ULONG copy_length;
    3.48 +  PHYSICAL_ADDRESS logical;
    3.49 +} map_register_t;
    3.50 +
    3.51 +typedef struct {
    3.52 +  PDEVICE_OBJECT device_object;
    3.53 +  ULONG total_map_registers;
    3.54 +  ULONG count;
    3.55 +  map_register_t regs[1];
    3.56 +} map_register_base_t;  
    3.57 +
    3.58 +BOOLEAN
    3.59 +XenPci_BIS_TranslateBusAddress(PVOID context, PHYSICAL_ADDRESS bus_address, ULONG length, PULONG address_space, PPHYSICAL_ADDRESS translated_address)
    3.60 +{
    3.61 +  UNREFERENCED_PARAMETER(context);
    3.62 +  UNREFERENCED_PARAMETER(length);
    3.63 +  /* actually this isn't right - should look up the gref for the physical address and work backwards from that */
    3.64 +  FUNCTION_ENTER();
    3.65 +  if (*address_space != 0)
    3.66 +  {
    3.67 +    KdPrint((__DRIVER_NAME "      Cannot map I/O space\n"));
    3.68 +    FUNCTION_EXIT();
    3.69 +    return FALSE;
    3.70 +  }
    3.71 +  *translated_address = bus_address;
    3.72 +  FUNCTION_EXIT();
    3.73 +  return TRUE;
    3.74 +}
    3.75 +
    3.76 +static VOID
    3.77 +XenPci_DOP_PutDmaAdapter(PDMA_ADAPTER dma_adapter)
    3.78 +{
    3.79 +  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
    3.80 +  
    3.81 +  FUNCTION_ENTER();
    3.82 +
    3.83 +  if (xen_dma_adapter->dma_extension)
    3.84 +    ObDereferenceObject(xen_dma_adapter->dma_extension_driver);
    3.85 +  ExFreePoolWithTag(xen_dma_adapter->adapter_object.DmaHeader.DmaOperations, XENPCI_POOL_TAG);
    3.86 +  ExFreePoolWithTag(xen_dma_adapter, XENPCI_POOL_TAG);
    3.87 +  
    3.88 +  FUNCTION_EXIT();
    3.89 +
    3.90 +  return;
    3.91 +}
    3.92 +
    3.93 +static PVOID
    3.94 +XenPci_DOP_AllocateCommonBuffer(
    3.95 +  PDMA_ADAPTER DmaAdapter,
    3.96 +  ULONG Length,
    3.97 +  PPHYSICAL_ADDRESS LogicalAddress,
    3.98 +  BOOLEAN CacheEnabled
    3.99 +)
   3.100 +{
   3.101 +  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
   3.102 +  PXENPCI_DEVICE_DATA xpdd;
   3.103 +  PVOID buffer;
   3.104 +  PFN_NUMBER pfn;
   3.105 +  grant_ref_t gref;
   3.106 +  
   3.107 +  UNREFERENCED_PARAMETER(DmaAdapter);
   3.108 +  UNREFERENCED_PARAMETER(CacheEnabled);
   3.109 +  
   3.110 +  //FUNCTION_ENTER();
   3.111 +
   3.112 +  xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   3.113 +
   3.114 +  //KdPrint((__DRIVER_NAME "     Length = %d\n", Length));
   3.115 +  
   3.116 +  buffer = ExAllocatePoolWithTag(NonPagedPool, Length, XENPCI_POOL_TAG);
   3.117 +  ASSERT(buffer); /* lazy */
   3.118 +
   3.119 +  pfn = (PFN_NUMBER)(MmGetPhysicalAddress(buffer).QuadPart >> PAGE_SHIFT);
   3.120 +  ASSERT(pfn); /* lazy */
   3.121 +  gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, INVALID_GRANT_REF);
   3.122 +  ASSERT(gref != INVALID_GRANT_REF); /* lazy */
   3.123 +  LogicalAddress->QuadPart = (gref << PAGE_SHIFT) | (PtrToUlong(buffer) & (PAGE_SIZE - 1));
   3.124 +  
   3.125 +  //FUNCTION_EXIT();
   3.126 +  return buffer;
   3.127 +}
   3.128 +
   3.129 +static VOID
   3.130 +XenPci_DOP_FreeCommonBuffer(
   3.131 +  PDMA_ADAPTER dma_adapter,
   3.132 +  ULONG length,
   3.133 +  PHYSICAL_ADDRESS logical_address,
   3.134 +  PVOID virtual_address,
   3.135 +  BOOLEAN cache_enabled
   3.136 +)
   3.137 +{
   3.138 +  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
   3.139 +  PXENPCI_DEVICE_DATA xpdd;
   3.140 +  grant_ref_t gref;
   3.141 +
   3.142 +  UNREFERENCED_PARAMETER(dma_adapter);
   3.143 +  UNREFERENCED_PARAMETER(length);
   3.144 +  UNREFERENCED_PARAMETER(cache_enabled);
   3.145 +
   3.146 +//  FUNCTION_ENTER();
   3.147 +
   3.148 +  xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   3.149 +  gref = (grant_ref_t)(logical_address.QuadPart >> PAGE_SHIFT);
   3.150 +  //KdPrint((__DRIVER_NAME "     F Releasing Grant Ref %d\n", gref));
   3.151 +  GntTbl_EndAccess(xpdd, gref, FALSE);
   3.152 +  //KdPrint((__DRIVER_NAME "     F Released Grant Ref\n"));
   3.153 +  ExFreePoolWithTag(virtual_address, XENPCI_POOL_TAG);
   3.154 +
   3.155 +//  FUNCTION_EXIT();
   3.156 +}
   3.157 +
   3.158 +static NTSTATUS
   3.159 +XenPci_DOP_AllocateAdapterChannel(
   3.160 +    IN PDMA_ADAPTER dma_adapter,
   3.161 +    IN PDEVICE_OBJECT device_object,
   3.162 +    IN ULONG NumberOfMapRegisters,
   3.163 +    IN PDRIVER_CONTROL ExecutionRoutine,
   3.164 +    IN PVOID Context
   3.165 +    )
   3.166 +{
   3.167 +  //xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
   3.168 +  //PXENPCI_DEVICE_DATA xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   3.169 +  IO_ALLOCATION_ACTION action;
   3.170 +  map_register_base_t *map_register_base;
   3.171 +  
   3.172 +  UNREFERENCED_PARAMETER(dma_adapter);
   3.173 +  
   3.174 +  //FUNCTION_ENTER();
   3.175 +
   3.176 +  map_register_base = ExAllocatePoolWithTag(NonPagedPool, 
   3.177 +    FIELD_OFFSET(map_register_base_t, regs) + NumberOfMapRegisters * sizeof(map_register_t), XENPCI_POOL_TAG);
   3.178 +  if (!map_register_base)
   3.179 +  {
   3.180 +    KdPrint((__DRIVER_NAME "     Cannot allocate memory for map_register_base\n"));
   3.181 +    //FUNCTION_EXIT();
   3.182 +    return STATUS_INSUFFICIENT_RESOURCES;
   3.183 +  }
   3.184 +  /* we should also allocate a single page of memory here for remap purposes as once we allocate the map registers there is no failure allowed */
   3.185 +  map_register_base->device_object = device_object;
   3.186 +  map_register_base->total_map_registers = NumberOfMapRegisters;
   3.187 +  map_register_base->count = 0;
   3.188 +  
   3.189 +  action = ExecutionRoutine(device_object, device_object->CurrentIrp, map_register_base, Context);
   3.190 +  
   3.191 +  switch (action)
   3.192 +  {
   3.193 +  case KeepObject:
   3.194 +    KdPrint((__DRIVER_NAME "     KeepObject\n"));
   3.195 +    ASSERT(FALSE);
   3.196 +    break;
   3.197 +  case DeallocateObject:
   3.198 +    KdPrint((__DRIVER_NAME "     DeallocateObject\n"));
   3.199 +    ASSERT(FALSE);
   3.200 +    break;
   3.201 +  case DeallocateObjectKeepRegisters:
   3.202 +    //KdPrint((__DRIVER_NAME "     DeallocateObjectKeepRegisters\n"));
   3.203 +    break;
   3.204 +  default:
   3.205 +    KdPrint((__DRIVER_NAME "     Unknown action %d\n", action));
   3.206 +    ASSERT(FALSE);
   3.207 +    break;
   3.208 +  }
   3.209 +  //FUNCTION_EXIT();
   3.210 +  return STATUS_SUCCESS;
   3.211 +}
   3.212 +
   3.213 +static BOOLEAN
   3.214 +XenPci_DOP_FlushAdapterBuffers(
   3.215 +  PDMA_ADAPTER dma_adapter,
   3.216 +  PMDL mdl,
   3.217 +  PVOID MapRegisterBase,
   3.218 +  PVOID CurrentVa,
   3.219 +  ULONG Length,
   3.220 +  BOOLEAN write_to_device)
   3.221 +{
   3.222 +  //xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
   3.223 +  //PXENPCI_DEVICE_DATA xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   3.224 +  map_register_base_t *map_register_base = MapRegisterBase;
   3.225 +  map_register_t *map_register;
   3.226 +  ULONG i;
   3.227 +  
   3.228 +  UNREFERENCED_PARAMETER(dma_adapter);
   3.229 +  UNREFERENCED_PARAMETER(mdl);
   3.230 +  UNREFERENCED_PARAMETER(CurrentVa);
   3.231 +  UNREFERENCED_PARAMETER(Length);
   3.232 +
   3.233 +  //FUNCTION_ENTER();
   3.234 +  
   3.235 +  for (i = 0; i < map_register_base->count; i++)
   3.236 +  {
   3.237 +    map_register = &map_register_base->regs[i];
   3.238 +    if (map_register->map_type == MAP_TYPE_REMAPPED && !write_to_device)
   3.239 +      memcpy(map_register->unaligned_buffer, map_register->aligned_buffer, map_register->copy_length);
   3.240 +  }
   3.241 +  //FUNCTION_EXIT();
   3.242 +  
   3.243 +  return TRUE;
   3.244 +}
   3.245 +
   3.246 +static VOID
   3.247 +XenPci_DOP_FreeAdapterChannel(
   3.248 +    IN PDMA_ADAPTER  DmaAdapter
   3.249 +    )
   3.250 +{
   3.251 +  UNREFERENCED_PARAMETER(DmaAdapter);
   3.252 +
   3.253 +  FUNCTION_ENTER();
   3.254 +  FUNCTION_EXIT();
   3.255 +}
   3.256 +
   3.257 +static VOID
   3.258 +XenPci_DOP_FreeMapRegisters(
   3.259 +  PDMA_ADAPTER dma_adapter,
   3.260 +  PVOID MapRegisterBase,
   3.261 +  ULONG NumberOfMapRegisters)
   3.262 +{
   3.263 +  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
   3.264 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   3.265 +  map_register_base_t *map_register_base = MapRegisterBase;
   3.266 +  map_register_t *map_register;
   3.267 +  ULONG i;
   3.268 +  grant_ref_t gref;
   3.269 +
   3.270 +  //FUNCTION_ENTER();
   3.271 +  if (!map_register_base)
   3.272 +  {
   3.273 +    /* i'm not sure if this is ideal here, but NDIS definitely does it */
   3.274 +    return;
   3.275 +  }
   3.276 +  ASSERT(map_register_base->total_map_registers == NumberOfMapRegisters);
   3.277 +
   3.278 +  for (i = 0; i < map_register_base->count; i++)
   3.279 +  {
   3.280 +    map_register = &map_register_base->regs[i];
   3.281 +    switch (map_register->map_type)
   3.282 +    {
   3.283 +    case MAP_TYPE_REMAPPED:
   3.284 +      gref = (grant_ref_t)(map_register->logical.QuadPart >> PAGE_SHIFT);
   3.285 +      GntTbl_EndAccess(xpdd, gref, FALSE);
   3.286 +      ExFreePoolWithTag(map_register->aligned_buffer, XENPCI_POOL_TAG);
   3.287 +      break;
   3.288 +    case MAP_TYPE_MDL:
   3.289 +      gref = (grant_ref_t)(map_register->logical.QuadPart >> PAGE_SHIFT);
   3.290 +      GntTbl_EndAccess(xpdd, gref, FALSE);
   3.291 +      break;
   3.292 +    case MAP_TYPE_VIRTUAL:
   3.293 +      break;
   3.294 +    }
   3.295 +  }
   3.296 +  ExFreePoolWithTag(map_register_base, XENPCI_POOL_TAG);
   3.297 +
   3.298 +  //FUNCTION_EXIT();
   3.299 +}
   3.300 +
   3.301 +static PHYSICAL_ADDRESS
   3.302 +XenPci_DOP_MapTransfer(
   3.303 +    PDMA_ADAPTER dma_adapter,
   3.304 +    PMDL mdl,
   3.305 +    PVOID MapRegisterBase,
   3.306 +    PVOID CurrentVa,
   3.307 +    PULONG Length,
   3.308 +    BOOLEAN WriteToDevice)
   3.309 +{
   3.310 +  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
   3.311 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   3.312 +  map_register_base_t *map_register_base = MapRegisterBase;
   3.313 +  map_register_t *map_register = &map_register_base->regs[map_register_base->count];
   3.314 +  PDEVICE_OBJECT device_object = map_register_base->device_object;
   3.315 +  ULONG page_offset;
   3.316 +  PFN_NUMBER pfn;
   3.317 +  grant_ref_t gref;
   3.318 +  PUCHAR ptr;
   3.319 +  ULONG mdl_offset;
   3.320 +  ULONG pfn_index;
   3.321 +
   3.322 +  //FUNCTION_ENTER();
   3.323 +
   3.324 +  //KdPrint((__DRIVER_NAME "     Mdl = %p, MapRegisterBase = %p, MdlVa = %p, CurrentVa = %p, Length = %d\n",
   3.325 +  //  mdl, MapRegisterBase, MmGetMdlVirtualAddress(mdl), CurrentVa, *Length));
   3.326 +
   3.327 +  ASSERT(mdl);
   3.328 +  ASSERT(map_register_base);
   3.329 +  ASSERT(map_register_base->count < map_register_base->total_map_registers);
   3.330 +  
   3.331 +  if (xen_dma_adapter->dma_extension)
   3.332 +  {
   3.333 +    if (xen_dma_adapter->dma_extension->need_virtual_address && xen_dma_adapter->dma_extension->need_virtual_address(device_object->CurrentIrp))
   3.334 +    {
   3.335 +      map_register->map_type = MAP_TYPE_VIRTUAL;
   3.336 +    }
   3.337 +    else
   3.338 +    {
   3.339 +      if (xen_dma_adapter->dma_extension->get_alignment)
   3.340 +      {
   3.341 +        ULONG alignment = xen_dma_adapter->dma_extension->get_alignment(device_object->CurrentIrp);
   3.342 +        if ((MmGetMdlByteOffset(mdl) & (alignment - 1)) || (MmGetMdlByteCount(mdl) & (alignment - 1)))
   3.343 +        {
   3.344 +          map_register->map_type = MAP_TYPE_REMAPPED;
   3.345 +        }
   3.346 +        else
   3.347 +        {
   3.348 +          map_register->map_type = MAP_TYPE_MDL;
   3.349 +        }
   3.350 +      }
   3.351 +      else
   3.352 +      {
   3.353 +        map_register->map_type = MAP_TYPE_MDL;
   3.354 +      }
   3.355 +    }
   3.356 +  }
   3.357 +  else
   3.358 +  {
   3.359 +    map_register->map_type = MAP_TYPE_MDL;
   3.360 +  }
   3.361 +
   3.362 +  switch (map_register->map_type)
   3.363 +  {
   3.364 +  case MAP_TYPE_MDL:
   3.365 +    //KdPrint((__DRIVER_NAME "     MAP_TYPE_MDL\n"));
   3.366 +    mdl_offset = (ULONG)((UINT_PTR)CurrentVa - (UINT_PTR)MmGetMdlVirtualAddress(mdl));
   3.367 +    page_offset = PtrToUlong(CurrentVa) & (PAGE_SIZE - 1);
   3.368 +    *Length = min(*Length, PAGE_SIZE - page_offset);
   3.369 +    pfn_index = (ULONG)(((UINT_PTR)CurrentVa >> PAGE_SHIFT) - ((UINT_PTR)MmGetMdlVirtualAddress(mdl) >> PAGE_SHIFT));
   3.370 +    //KdPrint((__DRIVER_NAME "     mdl_offset = %d, page_offset = %d, length = %d, pfn_index = %d\n",
   3.371 +    //  mdl_offset, page_offset, *Length, pfn_index));
   3.372 +    pfn = MmGetMdlPfnArray(mdl)[pfn_index];
   3.373 +    //KdPrint((__DRIVER_NAME "     B Requesting Grant Ref\n"));
   3.374 +    gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, INVALID_GRANT_REF);
   3.375 +    //KdPrint((__DRIVER_NAME "     B Got Grant Ref %d\n", gref));
   3.376 +    map_register->logical.QuadPart = (LONGLONG)(gref << PAGE_SHIFT) | page_offset;
   3.377 +    map_register_base->count++;
   3.378 +    break;
   3.379 +  case MAP_TYPE_REMAPPED:
   3.380 +    //KdPrint((__DRIVER_NAME "     MAP_TYPE_REMAPPED (MapTransfer)\n"));
   3.381 +    //KdPrint((__DRIVER_NAME "     Mdl = %p, MapRegisterBase = %p, MdlVa = %p, CurrentVa = %p, Length = %d\n",
   3.382 +    //  mdl, MapRegisterBase, MmGetMdlVirtualAddress(mdl), CurrentVa, *Length));
   3.383 +    mdl_offset = (ULONG)((UINT_PTR)CurrentVa - (UINT_PTR)MmGetMdlVirtualAddress(mdl));
   3.384 +    *Length = min(*Length, PAGE_SIZE);
   3.385 +    map_register->aligned_buffer = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
   3.386 +    ASSERT(map_register->aligned_buffer);
   3.387 +    map_register->unaligned_buffer = MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority);
   3.388 +    ASSERT(map_register->unaligned_buffer); /* lazy */
   3.389 +    map_register->unaligned_buffer = (PUCHAR)map_register->unaligned_buffer + mdl_offset;
   3.390 +    map_register->copy_length = *Length;
   3.391 +    if (WriteToDevice)
   3.392 +      memcpy(map_register->aligned_buffer, map_register->unaligned_buffer, map_register->copy_length);
   3.393 +    pfn = (PFN_NUMBER)(MmGetPhysicalAddress(map_register->aligned_buffer).QuadPart >> PAGE_SHIFT);
   3.394 +    //KdPrint((__DRIVER_NAME "     C Requesting Grant Ref\n"));
   3.395 +    gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, INVALID_GRANT_REF);
   3.396 +    //KdPrint((__DRIVER_NAME "     C Got Grant Ref %d\n", gref));
   3.397 +    map_register->logical.QuadPart = (LONGLONG)(gref << PAGE_SHIFT);
   3.398 +    map_register_base->count++;
   3.399 +    break;
   3.400 +  case MAP_TYPE_VIRTUAL:
   3.401 +    //KdPrint((__DRIVER_NAME "     MAP_TYPE_VIRTUAL\n"));
   3.402 +    ptr = MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority);
   3.403 +    ASSERT(ptr); /* lazy */
   3.404 +    map_register->logical.QuadPart = (ULONGLONG)ptr;
   3.405 +    map_register_base->count++;
   3.406 +    break;
   3.407 +  default:
   3.408 +    ASSERT(FALSE);
   3.409 +    break;
   3.410 +  }
   3.411 +  
   3.412 +  //KdPrint((__DRIVER_NAME "     logical = %08x:%08x\n", map_register->logical.HighPart, map_register->logical.LowPart));
   3.413 +  //FUNCTION_EXIT();
   3.414 +  return map_register->logical;
   3.415 +}
   3.416 +
   3.417 +static ULONG
   3.418 +XenPci_DOP_GetDmaAlignment(
   3.419 +  PDMA_ADAPTER DmaAdapter)
   3.420 +{
   3.421 +  UNREFERENCED_PARAMETER(DmaAdapter);
   3.422 +
   3.423 +  FUNCTION_ENTER();
   3.424 +  FUNCTION_EXIT();
   3.425 +  return 0;
   3.426 +}
   3.427 +
   3.428 +static ULONG
   3.429 +XenPci_DOP_ReadDmaCounter(
   3.430 +  PDMA_ADAPTER DmaAdapter)
   3.431 +{
   3.432 +  UNREFERENCED_PARAMETER(DmaAdapter);
   3.433 +
   3.434 +  FUNCTION_ENTER();
   3.435 +  FUNCTION_EXIT();
   3.436 +  return 0;
   3.437 +}
   3.438 +
   3.439 +static VOID
   3.440 +XenPci_DOP_PutScatterGatherList(
   3.441 +    IN PDMA_ADAPTER DmaAdapter,
   3.442 +    IN PSCATTER_GATHER_LIST sg_list,
   3.443 +    IN BOOLEAN WriteToDevice
   3.444 +    )
   3.445 +{
   3.446 +  xen_dma_adapter_t *xen_dma_adapter;
   3.447 +  PXENPCI_DEVICE_DATA xpdd;
   3.448 +  ULONG i;
   3.449 +  sg_extra_t *sg_extra;
   3.450 +  PMDL curr_mdl;
   3.451 +  ULONG offset;
   3.452 +  BOOLEAN active;
   3.453 +
   3.454 +  UNREFERENCED_PARAMETER(WriteToDevice);
   3.455 +  
   3.456 +  //FUNCTION_ENTER();
   3.457 +
   3.458 +  xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
   3.459 +  ASSERT(xen_dma_adapter);
   3.460 +  xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   3.461 +  
   3.462 +  sg_extra = (sg_extra_t *)((PUCHAR)sg_list + FIELD_OFFSET(SCATTER_GATHER_LIST, Elements) +
   3.463 +    (sizeof(SCATTER_GATHER_ELEMENT)) * sg_list->NumberOfElements);
   3.464 +
   3.465 +  switch (sg_extra->map_type)
   3.466 +  {
   3.467 +  case MAP_TYPE_REMAPPED:
   3.468 +    for (i = 0; i < sg_list->NumberOfElements; i++)
   3.469 +    {
   3.470 +      grant_ref_t gref;
   3.471 +      gref = (grant_ref_t)(sg_list->Elements[i].Address.QuadPart >> PAGE_SHIFT);
   3.472 +      GntTbl_EndAccess(xpdd, gref, FALSE);
   3.473 +      sg_list->Elements[i].Address.QuadPart = -1;
   3.474 +    }
   3.475 +    ASSERT(sg_extra->mdl);
   3.476 +    if (!WriteToDevice)
   3.477 +    {
   3.478 +      for (curr_mdl = sg_extra->mdl, offset = 0, active = FALSE; curr_mdl && offset < sg_extra->copy_length; curr_mdl = curr_mdl->Next)
   3.479 +      {
   3.480 +        PVOID mdl_start_va = MmGetMdlVirtualAddress(curr_mdl);
   3.481 +        ULONG mdl_byte_count = MmGetMdlByteCount(curr_mdl);
   3.482 +        ULONG mdl_offset = 0;
   3.483 +        /* need to use <= va + len - 1 to avoid ptr wraparound */
   3.484 +        if ((UINT_PTR)sg_extra->currentva >= (UINT_PTR)mdl_start_va && (UINT_PTR)sg_extra->currentva <= (UINT_PTR)mdl_start_va + mdl_byte_count - 1)
   3.485 +        {
   3.486 +          active = TRUE;
   3.487 +          mdl_byte_count -= (ULONG)((UINT_PTR)sg_extra->currentva - (UINT_PTR)mdl_start_va);
   3.488 +          if (offset + mdl_byte_count > sg_extra->copy_length)
   3.489 +            mdl_byte_count = sg_extra->copy_length - offset;
   3.490 +          mdl_offset = (ULONG)((UINT_PTR)sg_extra->currentva - (UINT_PTR)mdl_start_va);
   3.491 +          mdl_start_va = sg_extra->currentva;
   3.492 +        }
   3.493 +        if (active)
   3.494 +        {
   3.495 +          PVOID unaligned_buffer;
   3.496 +          unaligned_buffer = MmGetSystemAddressForMdlSafe(curr_mdl, NormalPagePriority);
   3.497 +          ASSERT(unaligned_buffer); /* lazy */
   3.498 +          memcpy((PUCHAR)unaligned_buffer + mdl_offset, (PUCHAR)sg_extra->aligned_buffer + offset, mdl_byte_count);
   3.499 +          offset += mdl_byte_count;
   3.500 +        }
   3.501 +      }
   3.502 +      ASSERT(offset == sg_extra->copy_length);
   3.503 +    }
   3.504 +    ExFreePoolWithTag(sg_extra->aligned_buffer, XENPCI_POOL_TAG);
   3.505 +    break;
   3.506 +  case MAP_TYPE_MDL:
   3.507 +    for (i = 0; i < sg_list->NumberOfElements; i++)
   3.508 +    {
   3.509 +      grant_ref_t gref;
   3.510 +      gref = (grant_ref_t)(sg_list->Elements[i].Address.QuadPart >> PAGE_SHIFT);
   3.511 +      GntTbl_EndAccess(xpdd, gref, FALSE);
   3.512 +      sg_list->Elements[i].Address.QuadPart = -1;
   3.513 +    }
   3.514 +    break;
   3.515 +  case MAP_TYPE_VIRTUAL:
   3.516 +    break;
   3.517 +  }
   3.518 +  if (sg_extra->allocated_by_me)
   3.519 +    ExFreePoolWithTag(sg_list, XENPCI_POOL_TAG);
   3.520 +  //FUNCTION_EXIT();
   3.521 +}
   3.522 +
   3.523 +static NTSTATUS
   3.524 +XenPci_DOP_CalculateScatterGatherList(
   3.525 +  PDMA_ADAPTER DmaAdapter,
   3.526 +  PMDL Mdl,
   3.527 +  PVOID CurrentVa,
   3.528 +  ULONG Length,
   3.529 +  PULONG ScatterGatherListSize,
   3.530 +  PULONG NumberOfMapRegisters
   3.531 +  )
   3.532 +{
   3.533 +  xen_dma_adapter_t *xen_dma_adapter;
   3.534 +  ULONG elements;
   3.535 +  PMDL curr_mdl;
   3.536 +  
   3.537 +  UNREFERENCED_PARAMETER(CurrentVa);
   3.538 +    
   3.539 +  //FUNCTION_ENTER();
   3.540 +  
   3.541 +  //KdPrint((__DRIVER_NAME "     Mdl = %p\n", Mdl));
   3.542 +  //KdPrint((__DRIVER_NAME "     CurrentVa = %p\n", CurrentVa));
   3.543 +  //KdPrint((__DRIVER_NAME "     Length = %d\n", Length));
   3.544 +
   3.545 +  xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
   3.546 +
   3.547 +  if (Mdl)
   3.548 +  {
   3.549 +    //if (CurrentVa != MmGetMdlVirtualAddress(Mdl))
   3.550 +    //{
   3.551 +    //  KdPrint((__DRIVER_NAME "     CurrentVa (%p) != MdlVa (%p)\n", CurrentVa, MmGetMdlVirtualAddress(Mdl)));
   3.552 +    //
   3.553 +
   3.554 +    //KdPrint((__DRIVER_NAME "     CurrentVa = %p, MdlVa = %p\n", CurrentVa, MmGetMdlVirtualAddress(Mdl)));
   3.555 +
   3.556 +    for (curr_mdl = Mdl, elements = 0; curr_mdl; curr_mdl = curr_mdl->Next)
   3.557 +    {
   3.558 +      //KdPrint((__DRIVER_NAME "     curr_mdlVa = %p, curr_mdl size = %d\n", MmGetMdlVirtualAddress(curr_mdl), MmGetMdlByteCount(curr_mdl)));
   3.559 +      elements += ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(curr_mdl), MmGetMdlByteCount(curr_mdl));
   3.560 +    }
   3.561 +  }
   3.562 +  else
   3.563 +  {
   3.564 +    elements = ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, Length); // + 1;
   3.565 +  }
   3.566 +
   3.567 +  if (elements > xen_dma_adapter->adapter_object.MapRegistersPerChannel)
   3.568 +  {
   3.569 +    //KdPrint((__DRIVER_NAME "     elements = %d - too many\n", elements));
   3.570 +    if (NumberOfMapRegisters)
   3.571 +      *NumberOfMapRegisters = 0;
   3.572 +    *ScatterGatherListSize = 0;
   3.573 +    
   3.574 +    return STATUS_INSUFFICIENT_RESOURCES;
   3.575 +  }
   3.576 +  
   3.577 +  *ScatterGatherListSize = FIELD_OFFSET(SCATTER_GATHER_LIST, Elements)
   3.578 +    + sizeof(SCATTER_GATHER_ELEMENT) * elements
   3.579 +    + sizeof(sg_extra_t);
   3.580 +  if (NumberOfMapRegisters)
   3.581 +    *NumberOfMapRegisters = elements;
   3.582 +
   3.583 +  //KdPrint((__DRIVER_NAME "     ScatterGatherListSize = %d, NumberOfMapRegisters = %d\n", *ScatterGatherListSize, elements));
   3.584 +
   3.585 +  //FUNCTION_EXIT();
   3.586 +  return STATUS_SUCCESS;
   3.587 +}
   3.588 +
   3.589 +static NTSTATUS
   3.590 +XenPci_DOP_BuildScatterGatherListButDontExecute(
   3.591 +  IN PDMA_ADAPTER DmaAdapter,
   3.592 +  IN PDEVICE_OBJECT DeviceObject,
   3.593 +  IN PMDL Mdl,
   3.594 +  IN PVOID CurrentVa,
   3.595 +  IN ULONG Length,
   3.596 +  IN BOOLEAN WriteToDevice,
   3.597 +  IN PVOID ScatterGatherBuffer,
   3.598 +  IN ULONG ScatterGatherBufferLength,
   3.599 +  BOOLEAN allocated_by_me)
   3.600 +{
   3.601 +  ULONG i;
   3.602 +  PSCATTER_GATHER_LIST sglist = ScatterGatherBuffer;
   3.603 +  PUCHAR ptr;
   3.604 +  ULONG remaining = Length;
   3.605 +  ULONG total_remaining;
   3.606 +  xen_dma_adapter_t *xen_dma_adapter;
   3.607 +  PXENPCI_DEVICE_DATA xpdd;
   3.608 +  sg_extra_t *sg_extra;
   3.609 +  PMDL curr_mdl;
   3.610 +  ULONG map_type;
   3.611 +  ULONG sg_element;
   3.612 +  ULONG offset;
   3.613 +  PFN_NUMBER pfn;
   3.614 +  grant_ref_t gref;
   3.615 +  BOOLEAN active;
   3.616 +  PVOID mdl_start_va;
   3.617 +  ULONG mdl_byte_count;
   3.618 +  ULONG mdl_offset;
   3.619 +  ULONG remapped_bytes = 0;
   3.620 +  
   3.621 +  //FUNCTION_ENTER();
   3.622 +  
   3.623 +  if (!ScatterGatherBuffer)
   3.624 +  {
   3.625 +    KdPrint((__DRIVER_NAME "     NULL ScatterGatherBuffer\n"));
   3.626 +    return STATUS_INVALID_PARAMETER;
   3.627 +  }
   3.628 +  //if (MmGetMdlVirtualAddress(Mdl) != CurrentVa)
   3.629 +  //{
   3.630 +  //  KdPrint((__DRIVER_NAME "     MmGetMdlVirtualAddress = %p, CurrentVa = %p, Length = %d\n", MmGetMdlVirtualAddress(Mdl), CurrentVa, Length));
   3.631 +  //}
   3.632 +
   3.633 +  xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
   3.634 +  xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   3.635 +
   3.636 +  ASSERT(Mdl);
   3.637 +  
   3.638 +  if (xen_dma_adapter->dma_extension)
   3.639 +  {
   3.640 +    if (xen_dma_adapter->dma_extension->need_virtual_address && xen_dma_adapter->dma_extension->need_virtual_address(DeviceObject->CurrentIrp))
   3.641 +    {
   3.642 +      ASSERT(!Mdl->Next); /* can only virtual a single buffer */
   3.643 +      //ASSERT(MmGetMdlVirtualAddress(Mdl) == CurrentVa);
   3.644 +      map_type = MAP_TYPE_VIRTUAL;
   3.645 +      sglist->NumberOfElements = 1;
   3.646 +    }
   3.647 +    else
   3.648 +    {
   3.649 +      if (xen_dma_adapter->dma_extension->get_alignment)
   3.650 +      {
   3.651 +        ULONG alignment = xen_dma_adapter->dma_extension->get_alignment(DeviceObject->CurrentIrp);
   3.652 +
   3.653 +        map_type = MAP_TYPE_MDL;
   3.654 +        sglist->NumberOfElements = 0;
   3.655 +        for (curr_mdl = Mdl, remapped_bytes = 0, active = FALSE; remapped_bytes < Length && curr_mdl; curr_mdl = curr_mdl->Next)
   3.656 +        {
   3.657 +          mdl_start_va = MmGetMdlVirtualAddress(curr_mdl);
   3.658 +          mdl_byte_count = MmGetMdlByteCount(curr_mdl);
   3.659 +          /* need to use <= va + len - 1 to avoid ptr wraparound */
   3.660 +          if ((UINT_PTR)CurrentVa >= (UINT_PTR)mdl_start_va && (UINT_PTR)CurrentVa <= (UINT_PTR)mdl_start_va + mdl_byte_count - 1)
   3.661 +          {
   3.662 +            active = TRUE;
   3.663 +            mdl_byte_count -= (ULONG)((UINT_PTR)CurrentVa - (UINT_PTR)mdl_start_va);
   3.664 +            if (remapped_bytes + mdl_byte_count > Length)
   3.665 +              mdl_byte_count = Length - remapped_bytes;
   3.666 +            mdl_start_va = CurrentVa;
   3.667 +          }
   3.668 +          if (active)
   3.669 +          {
   3.670 +            if (((UINT_PTR)mdl_start_va & (alignment - 1)) || (mdl_byte_count & (alignment - 1)))
   3.671 +              map_type = MAP_TYPE_REMAPPED;
   3.672 +            remapped_bytes += mdl_byte_count;
   3.673 +            if (remapped_bytes > Length)
   3.674 +              remapped_bytes = Length;
   3.675 +          }
   3.676 +        }
   3.677 +        if (remapped_bytes != Length)
   3.678 +        {
   3.679 +          KdPrint((__DRIVER_NAME "     remapped_bytes = %d, Length = %d\n", remapped_bytes, Length));
   3.680 +        }
   3.681 +        //ASSERT(remapped_bytes == Length);
   3.682 +        sglist->NumberOfElements += ADDRESS_AND_SIZE_TO_SPAN_PAGES(NULL, remapped_bytes);
   3.683 +      }
   3.684 +      else
   3.685 +      {
   3.686 +        map_type = MAP_TYPE_MDL;
   3.687 +      }
   3.688 +    }
   3.689 +  }
   3.690 +  else
   3.691 +  {
   3.692 +    map_type = MAP_TYPE_MDL;
   3.693 +  }
   3.694 +  if (map_type == MAP_TYPE_MDL)
   3.695 +  {    
   3.696 +    for (curr_mdl = Mdl, sglist->NumberOfElements = 0, total_remaining = Length, active = FALSE; total_remaining > 0; curr_mdl = curr_mdl->Next)
   3.697 +    {
   3.698 +      ASSERT(curr_mdl);
   3.699 +      mdl_start_va = MmGetMdlVirtualAddress(curr_mdl);
   3.700 +      mdl_byte_count = MmGetMdlByteCount(curr_mdl);
   3.701 +      /* need to use <= va + len - 1 to avoid ptr wraparound */
   3.702 +      if ((UINT_PTR)CurrentVa >= (UINT_PTR)mdl_start_va && (UINT_PTR)CurrentVa <= (UINT_PTR)mdl_start_va + mdl_byte_count - 1)
   3.703 +      {
   3.704 +        active = TRUE;
   3.705 +        mdl_byte_count -= (ULONG)((UINT_PTR)CurrentVa - (UINT_PTR)mdl_start_va);
   3.706 +        mdl_start_va = CurrentVa;
   3.707 +      }
   3.708 +      mdl_byte_count = min(mdl_byte_count, total_remaining);
   3.709 +      if (active && mdl_byte_count)
   3.710 +      {
   3.711 +        sglist->NumberOfElements += ADDRESS_AND_SIZE_TO_SPAN_PAGES(
   3.712 +          mdl_start_va, mdl_byte_count);
   3.713 +        total_remaining -= mdl_byte_count;
   3.714 +      }
   3.715 +    }
   3.716 +  }
   3.717 +  if (ScatterGatherBufferLength < FIELD_OFFSET(SCATTER_GATHER_LIST, Elements) +
   3.718 +    sizeof(SCATTER_GATHER_ELEMENT) * sglist->NumberOfElements + sizeof(sg_extra_t))
   3.719 +  {
   3.720 +    //KdPrint((__DRIVER_NAME "     STATUS_BUFFER_TOO_SMALL (%d < %d)\n", ScatterGatherBufferLength, FIELD_OFFSET(SCATTER_GATHER_LIST, Elements) +
   3.721 +    //  sizeof(SCATTER_GATHER_ELEMENT) * sglist->NumberOfElements + sizeof(sg_extra_t)));
   3.722 +    return STATUS_BUFFER_TOO_SMALL;
   3.723 +  }
   3.724 +  
   3.725 +  sg_extra = (sg_extra_t *)((PUCHAR)sglist + FIELD_OFFSET(SCATTER_GATHER_LIST, Elements) +
   3.726 +    (sizeof(SCATTER_GATHER_ELEMENT)) * sglist->NumberOfElements);
   3.727 +
   3.728 +  sg_extra->allocated_by_me = allocated_by_me;
   3.729 +  
   3.730 +  sg_extra->map_type = map_type;
   3.731 +  switch (map_type)
   3.732 +  {
   3.733 +  case MAP_TYPE_MDL:
   3.734 +    //KdPrint((__DRIVER_NAME "     MAP_TYPE_MDL - %p\n", MmGetMdlVirtualAddress(Mdl)));
   3.735 +    total_remaining = Length;
   3.736 +    for (sg_element = 0, curr_mdl = Mdl, active = FALSE; total_remaining > 0; curr_mdl = curr_mdl->Next)
   3.737 +    {
   3.738 +      ASSERT(curr_mdl);
   3.739 +      mdl_start_va = MmGetMdlVirtualAddress(curr_mdl);
   3.740 +      mdl_byte_count = MmGetMdlByteCount(curr_mdl);
   3.741 +      /* need to use <= va + len - 1 to avoid ptr wraparound */
   3.742 +      if ((UINT_PTR)CurrentVa >= (UINT_PTR)mdl_start_va && (UINT_PTR)CurrentVa <= (UINT_PTR)mdl_start_va + mdl_byte_count - 1)
   3.743 +      {
   3.744 +        active = TRUE;
   3.745 +        mdl_byte_count -= (ULONG)((UINT_PTR)CurrentVa - (UINT_PTR)mdl_start_va);
   3.746 +        mdl_start_va = CurrentVa;
   3.747 +      }
   3.748 +      if (active && mdl_byte_count)
   3.749 +      {
   3.750 +        ULONG pfn_offset;
   3.751 +        remaining = min(mdl_byte_count, total_remaining);
   3.752 +        offset = (ULONG)((UINT_PTR)mdl_start_va & (PAGE_SIZE - 1));
   3.753 +        pfn_offset = (ULONG)(((UINT_PTR)mdl_start_va >> PAGE_SHIFT) - ((UINT_PTR)MmGetMdlVirtualAddress(curr_mdl) >> PAGE_SHIFT));
   3.754 +        //for (i = 0; i < ADDRESS_AND_SIZE_TO_SPAN_PAGES(mdl_start_va, mdl_byte_count); i++)
   3.755 +        for (i = 0; remaining > 0; i++)
   3.756 +        {
   3.757 +          pfn = MmGetMdlPfnArray(curr_mdl)[pfn_offset + i];
   3.758 +          ASSERT(pfn);
   3.759 +          gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, INVALID_GRANT_REF);
   3.760 +          ASSERT(gref != INVALID_GRANT_REF);
   3.761 +          sglist->Elements[sg_element].Address.QuadPart = (LONGLONG)(gref << PAGE_SHIFT) | offset;
   3.762 +          sglist->Elements[sg_element].Length = min(min(PAGE_SIZE - offset, remaining), total_remaining);
   3.763 +          total_remaining -= sglist->Elements[sg_element].Length;
   3.764 +          remaining -= sglist->Elements[sg_element].Length;
   3.765 +          offset = 0;
   3.766 +          sg_element++;
   3.767 +        }
   3.768 +      }
   3.769 +    }
   3.770 +    if (sg_element != sglist->NumberOfElements)
   3.771 +    {
   3.772 +      KdPrint((__DRIVER_NAME "     sg_element = %d, sglist->NumberOfElements = %d\n", sg_element, sglist->NumberOfElements));
   3.773 +      KdPrint((__DRIVER_NAME "     CurrentVa = %p, Length = %d\n", CurrentVa, Length));
   3.774 +for (curr_mdl = Mdl; curr_mdl; curr_mdl = curr_mdl->Next)
   3.775 +{
   3.776 +  KdPrint((__DRIVER_NAME "     Mdl = %p, VirtualAddress = %p, ByteCount = %d\n", Mdl, MmGetMdlVirtualAddress(curr_mdl), MmGetMdlByteCount(curr_mdl)));
   3.777 +}
   3.778 +    }
   3.779 +    ASSERT(sg_element == sglist->NumberOfElements);
   3.780 +    break;
   3.781 +  case MAP_TYPE_REMAPPED:
   3.782 +    sg_extra->aligned_buffer = ExAllocatePoolWithTag(NonPagedPool, max(remapped_bytes, PAGE_SIZE), XENPCI_POOL_TAG);
   3.783 +    if (!sg_extra->aligned_buffer)
   3.784 +    {
   3.785 +      KdPrint((__DRIVER_NAME "     MAP_TYPE_REMAPPED buffer allocation failed - requested va = %p, length = %d\n", MmGetMdlVirtualAddress(Mdl), remapped_bytes));
   3.786 +      return STATUS_INSUFFICIENT_RESOURCES;
   3.787 +    }
   3.788 +//KdPrint((__DRIVER_NAME "     MAP_TYPE_REMAPPED - %p, %d\n", sg_extra->aligned_buffer, remapped_bytes));
   3.789 +//KdPrint((__DRIVER_NAME "     CurrentVa = %p, Length = %d\n", CurrentVa, Length));
   3.790 +//for (curr_mdl = Mdl; curr_mdl; curr_mdl = curr_mdl->Next)
   3.791 +//{
   3.792 +//  KdPrint((__DRIVER_NAME "     Mdl = %p, VirtualAddress = %p, ByteCount = %d\n", Mdl, MmGetMdlVirtualAddress(curr_mdl), MmGetMdlByteCount(curr_mdl)));
   3.793 +//}
   3.794 +    sg_extra->mdl = Mdl;
   3.795 +    sg_extra->currentva = CurrentVa;
   3.796 +    sg_extra->copy_length = remapped_bytes;
   3.797 +
   3.798 +    if (WriteToDevice)
   3.799 +    {
   3.800 +      for (curr_mdl = Mdl, offset = 0, active = FALSE; curr_mdl && offset < Length; curr_mdl = curr_mdl->Next)
   3.801 +      {
   3.802 +        mdl_start_va = MmGetMdlVirtualAddress(curr_mdl);
   3.803 +        mdl_byte_count = MmGetMdlByteCount(curr_mdl);
   3.804 +        mdl_offset = 0;
   3.805 +        /* need to use <= va + len - 1 to avoid ptr wraparound */
   3.806 +        if ((UINT_PTR)CurrentVa >= (UINT_PTR)mdl_start_va && (UINT_PTR)CurrentVa <= (UINT_PTR)mdl_start_va + mdl_byte_count - 1)
   3.807 +        {
   3.808 +          active = TRUE;
   3.809 +          mdl_byte_count -= (ULONG)((UINT_PTR)CurrentVa - (UINT_PTR)mdl_start_va);
   3.810 +          if (offset + mdl_byte_count > Length)
   3.811 +            mdl_byte_count = Length - offset;            
   3.812 +          mdl_offset = (ULONG)((UINT_PTR)CurrentVa - (UINT_PTR)mdl_start_va);
   3.813 +          mdl_start_va = CurrentVa;
   3.814 +        }
   3.815 +        if (active)
   3.816 +        {
   3.817 +          PVOID unaligned_buffer;
   3.818 +          unaligned_buffer = (PUCHAR)MmGetSystemAddressForMdlSafe(curr_mdl, NormalPagePriority);
   3.819 +          ASSERT(unaligned_buffer); /* lazy */
   3.820 +          memcpy((PUCHAR)sg_extra->aligned_buffer + offset, (PUCHAR)unaligned_buffer + mdl_offset, mdl_byte_count);
   3.821 +          offset += mdl_byte_count;
   3.822 +        }
   3.823 +      }
   3.824 +    }
   3.825 +    for (sg_element = 0, remaining = remapped_bytes; 
   3.826 +      sg_element < ADDRESS_AND_SIZE_TO_SPAN_PAGES(sg_extra->aligned_buffer, remapped_bytes); sg_element++)
   3.827 +    {
   3.828 +      pfn = (PFN_NUMBER)(MmGetPhysicalAddress((PUCHAR)sg_extra->aligned_buffer + (sg_element << PAGE_SHIFT)).QuadPart >> PAGE_SHIFT);
   3.829 +      ASSERT(pfn);
   3.830 +      gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, INVALID_GRANT_REF);
   3.831 +      ASSERT(gref != INVALID_GRANT_REF);
   3.832 +      sglist->Elements[sg_element].Address.QuadPart = (ULONGLONG)gref << PAGE_SHIFT;
   3.833 +      sglist->Elements[sg_element].Length = min(PAGE_SIZE, remaining);
   3.834 +      remaining -= sglist->Elements[sg_element].Length;
   3.835 +    }
   3.836 +    break;
   3.837 +  case MAP_TYPE_VIRTUAL:
   3.838 +    ptr = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
   3.839 +    ASSERT(ptr); /* lazy */
   3.840 +    sglist->Elements[0].Address.QuadPart = (ULONGLONG)ptr + ((UINT_PTR)CurrentVa - (UINT_PTR)MmGetMdlVirtualAddress(Mdl));
   3.841 +    sglist->Elements[0].Length = Length;
   3.842 +    //KdPrint((__DRIVER_NAME "     MAP_TYPE_VIRTUAL - %08x\n", sglist->Elements[0].Address.LowPart));
   3.843 +    break;
   3.844 +  default:
   3.845 +    KdPrint((__DRIVER_NAME "     map_type = %d\n", map_type));
   3.846 +    break;
   3.847 +  }
   3.848 +  //FUNCTION_EXIT();
   3.849 +  return STATUS_SUCCESS;
   3.850 +}
   3.851 +
   3.852 +static NTSTATUS
   3.853 +XenPci_DOP_BuildScatterGatherList(
   3.854 +  IN PDMA_ADAPTER DmaAdapter,
   3.855 +  IN PDEVICE_OBJECT DeviceObject,
   3.856 +  IN PMDL Mdl,
   3.857 +  IN PVOID CurrentVa,
   3.858 +  IN ULONG Length,
   3.859 +  IN PDRIVER_LIST_CONTROL ExecutionRoutine,
   3.860 +  IN PVOID Context,
   3.861 +  IN BOOLEAN WriteToDevice,
   3.862 +  IN PVOID ScatterGatherBuffer,
   3.863 +  IN ULONG ScatterGatherBufferLength)
   3.864 +{
   3.865 +  NTSTATUS status;
   3.866 +  
   3.867 +  status = XenPci_DOP_BuildScatterGatherListButDontExecute(DmaAdapter, DeviceObject, Mdl, CurrentVa, Length, WriteToDevice, ScatterGatherBuffer, ScatterGatherBufferLength, FALSE);
   3.868 +  
   3.869 +  if (NT_SUCCESS(status))
   3.870 +    ExecutionRoutine(DeviceObject, DeviceObject->CurrentIrp, ScatterGatherBuffer, Context);
   3.871 +
   3.872 +  //FUNCTION_EXIT();
   3.873 +  
   3.874 +  return status;
   3.875 +}
   3.876 +
   3.877 +static NTSTATUS
   3.878 +XenPci_DOP_GetScatterGatherList(
   3.879 +  PDMA_ADAPTER DmaAdapter,
   3.880 +  PDEVICE_OBJECT DeviceObject,
   3.881 +  PMDL Mdl,
   3.882 +  PVOID CurrentVa,
   3.883 +  ULONG Length,
   3.884 +  PDRIVER_LIST_CONTROL ExecutionRoutine,
   3.885 +  PVOID Context,
   3.886 +  BOOLEAN WriteToDevice)
   3.887 +{
   3.888 +  NTSTATUS status;
   3.889 +  ULONG list_size;
   3.890 +  ULONG map_registers;
   3.891 +  PSCATTER_GATHER_LIST sg_list;
   3.892 +  
   3.893 +  //FUNCTION_ENTER();
   3.894 +
   3.895 +  status = XenPci_DOP_CalculateScatterGatherList(DmaAdapter, Mdl, CurrentVa, Length, &list_size, &map_registers);
   3.896 +  if (!NT_SUCCESS(status))
   3.897 +  {
   3.898 +    //FUNCTION_EXIT();
   3.899 +    return status;
   3.900 +  }
   3.901 +
   3.902 +  sg_list = ExAllocatePoolWithTag(NonPagedPool, list_size, XENPCI_POOL_TAG);
   3.903 +  if (!sg_list)
   3.904 +  {
   3.905 +    KdPrint((__DRIVER_NAME "     Cannot allocate memory for sg_list\n"));
   3.906 +    //FUNCTION_EXIT();
   3.907 +    return STATUS_INSUFFICIENT_RESOURCES;
   3.908 +  }
   3.909 +    
   3.910 +  status = XenPci_DOP_BuildScatterGatherListButDontExecute(DmaAdapter, DeviceObject, Mdl, CurrentVa, Length, WriteToDevice, sg_list, list_size, TRUE);
   3.911 +  
   3.912 +  if (NT_SUCCESS(status))
   3.913 +    ExecutionRoutine(DeviceObject, DeviceObject->CurrentIrp, sg_list, Context);
   3.914 +  
   3.915 +  //FUNCTION_EXIT();
   3.916 +  
   3.917 +  return status;
   3.918 +}
   3.919 +
   3.920 +static NTSTATUS
   3.921 +XenPci_DOP_BuildMdlFromScatterGatherList(
   3.922 +  PDMA_ADAPTER DmaAdapter,
   3.923 +  PSCATTER_GATHER_LIST ScatterGather,
   3.924 +  PMDL OriginalMdl,
   3.925 +  PMDL *TargetMdl)
   3.926 +{
   3.927 +  NTSTATUS status = STATUS_SUCCESS;
   3.928 +  UNREFERENCED_PARAMETER(DmaAdapter);
   3.929 +  UNREFERENCED_PARAMETER(ScatterGather);
   3.930 +  UNREFERENCED_PARAMETER(OriginalMdl);
   3.931 +  UNREFERENCED_PARAMETER(TargetMdl);
   3.932 +
   3.933 +  FUNCTION_ENTER();
   3.934 +  
   3.935 +  if (OriginalMdl)
   3.936 +  {
   3.937 +    *TargetMdl = OriginalMdl;
   3.938 +  }
   3.939 +  else
   3.940 +  {
   3.941 +    *TargetMdl = NULL;
   3.942 +    status = STATUS_INVALID_PARAMETER;
   3.943 +  }
   3.944 +  
   3.945 +  FUNCTION_EXIT();
   3.946 +  
   3.947 +  return status;
   3.948 +}
   3.949 +
   3.950 +PDMA_ADAPTER
   3.951 +XenPci_BIS_GetDmaAdapter(PVOID context, PDEVICE_DESCRIPTION device_description, PULONG number_of_map_registers)
   3.952 +{
   3.953 +  xen_dma_adapter_t *xen_dma_adapter;
   3.954 +  PDEVICE_OBJECT curr, prev;
   3.955 +  PDRIVER_OBJECT fdo_driver_object;
   3.956 +  PVOID fdo_driver_extension;
   3.957 +  
   3.958 +  UNREFERENCED_PARAMETER(device_description);
   3.959 +  
   3.960 +  FUNCTION_ENTER();
   3.961 +
   3.962 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   3.963 +  KdPrint((__DRIVER_NAME "     Device Description = %p:\n", device_description));
   3.964 +  KdPrint((__DRIVER_NAME "      Version  = %d\n", device_description->Version));
   3.965 +  KdPrint((__DRIVER_NAME "      Master = %d\n", device_description->Master));
   3.966 +  KdPrint((__DRIVER_NAME "      ScatterGather = %d\n", device_description->ScatterGather));
   3.967 +  KdPrint((__DRIVER_NAME "      DemandMode = %d\n", device_description->DemandMode));
   3.968 +  KdPrint((__DRIVER_NAME "      AutoInitialize = %d\n", device_description->AutoInitialize));
   3.969 +  KdPrint((__DRIVER_NAME "      Dma32BitAddresses = %d\n", device_description->Dma32BitAddresses));
   3.970 +  KdPrint((__DRIVER_NAME "      IgnoreCount = %d\n", device_description->IgnoreCount));
   3.971 +  KdPrint((__DRIVER_NAME "      Dma64BitAddresses = %d\n", device_description->Dma64BitAddresses));
   3.972 +  KdPrint((__DRIVER_NAME "      BusNumber = %d\n", device_description->BusNumber));
   3.973 +  KdPrint((__DRIVER_NAME "      DmaChannel = %d\n", device_description->DmaChannel));
   3.974 +  KdPrint((__DRIVER_NAME "      InterfaceType = %d\n", device_description->InterfaceType));
   3.975 +  KdPrint((__DRIVER_NAME "      DmaWidth = %d\n", device_description->DmaWidth));
   3.976 +  KdPrint((__DRIVER_NAME "      DmaSpeed = %d\n", device_description->DmaSpeed));
   3.977 +  KdPrint((__DRIVER_NAME "      MaximumLength = %d\n", device_description->MaximumLength));
   3.978 +  KdPrint((__DRIVER_NAME "      DmaPort = %d\n", device_description->DmaPort));
   3.979 +  
   3.980 +  if (!device_description->Master)
   3.981 +    return NULL;
   3.982 +/*
   3.983 +we have to allocate PAGE_SIZE bytes here because Windows thinks this is
   3.984 +actually an ADAPTER_OBJECT, and then the verifier crashes because
   3.985 +Windows accessed beyond the end of the structure :(
   3.986 +*/
   3.987 +  xen_dma_adapter = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
   3.988 +  ASSERT(xen_dma_adapter);
   3.989 +  RtlZeroMemory(xen_dma_adapter, PAGE_SIZE);
   3.990 +  
   3.991 +  switch(device_description->Version)
   3.992 +  {
   3.993 +  case DEVICE_DESCRIPTION_VERSION1:
   3.994 +    xen_dma_adapter->adapter_object.DmaHeader.Version = 1;
   3.995 +    break;
   3.996 +  case DEVICE_DESCRIPTION_VERSION: /* ignore what the docs say here - DEVICE_DESCRIPTION_VERSION appears to mean the latest version */
   3.997 +  case DEVICE_DESCRIPTION_VERSION2:
   3.998 +    xen_dma_adapter->adapter_object.DmaHeader.Version = 2;
   3.999 +    break;
  3.1000 +  default:
  3.1001 +    KdPrint((__DRIVER_NAME "     Unsupported device description version %d\n", device_description->Version));
  3.1002 +    ExFreePoolWithTag(xen_dma_adapter, XENPCI_POOL_TAG);
  3.1003 +    return NULL;
  3.1004 +  }
  3.1005 +    
  3.1006 +  xen_dma_adapter->xppdd = context;
  3.1007 +  xen_dma_adapter->dma_extension = NULL;
  3.1008 +
  3.1009 +  KdPrint((__DRIVER_NAME "     About to call IoGetAttachedDeviceReference\n"));
  3.1010 +  curr = IoGetAttachedDeviceReference(WdfDeviceWdmGetDeviceObject(xen_dma_adapter->xppdd->wdf_device));
  3.1011 +  KdPrint((__DRIVER_NAME "     Before start of loop - curr = %p\n", curr));
  3.1012 +  while (curr != NULL)
  3.1013 +  {
  3.1014 +    fdo_driver_object = curr->DriverObject;
  3.1015 +    if (fdo_driver_object)
  3.1016 +    {
  3.1017 +      ObReferenceObject(fdo_driver_object);
  3.1018 +      fdo_driver_extension = IoGetDriverObjectExtension(fdo_driver_object, UlongToPtr(XEN_DMA_DRIVER_EXTENSION_MAGIC));
  3.1019 +      if (fdo_driver_extension)
  3.1020 +      {
  3.1021 +        xen_dma_adapter->dma_extension_driver = fdo_driver_object; /* so we can dereference it on putdmaadapter */
  3.1022 +        xen_dma_adapter->dma_extension = (dma_driver_extension_t *)fdo_driver_extension;
  3.1023 +        ObDereferenceObject(curr);
  3.1024 +        break;
  3.1025 +      }
  3.1026 +      else
  3.1027 +      {
  3.1028 +        ObDereferenceObject(fdo_driver_object);
  3.1029 +      }
  3.1030 +    }
  3.1031 +    prev = curr;
  3.1032 +    curr = IoGetLowerDeviceObject(curr);
  3.1033 +    ObDereferenceObject(prev);
  3.1034 +  }
  3.1035 +  KdPrint((__DRIVER_NAME "     End of loop\n"));
  3.1036 +
  3.1037 +  xen_dma_adapter->adapter_object.DmaHeader.Size = sizeof(X_ADAPTER_OBJECT); //xen_dma_adapter_t);
  3.1038 +  xen_dma_adapter->adapter_object.MasterAdapter = NULL;
  3.1039 +  if (xen_dma_adapter->dma_extension && xen_dma_adapter->dma_extension->max_sg_elements)
  3.1040 +  {
  3.1041 +    xen_dma_adapter->adapter_object.MapRegistersPerChannel = xen_dma_adapter->dma_extension->max_sg_elements;
  3.1042 +  }
  3.1043 +  else
  3.1044 +  {
  3.1045 +    xen_dma_adapter->adapter_object.MapRegistersPerChannel = 256;
  3.1046 +  }
  3.1047 +  xen_dma_adapter->adapter_object.AdapterBaseVa = NULL;
  3.1048 +  xen_dma_adapter->adapter_object.MapRegisterBase = NULL;
  3.1049 +  xen_dma_adapter->adapter_object.NumberOfMapRegisters = 0;
  3.1050 +  xen_dma_adapter->adapter_object.CommittedMapRegisters = 0;
  3.1051 +  xen_dma_adapter->adapter_object.CurrentWcb = NULL;
  3.1052 +  KeInitializeDeviceQueue(&xen_dma_adapter->adapter_object.ChannelWaitQueue);
  3.1053 +  xen_dma_adapter->adapter_object.RegisterWaitQueue = NULL;
  3.1054 +  InitializeListHead(&xen_dma_adapter->adapter_object.AdapterQueue);
  3.1055 +  KeInitializeSpinLock(&xen_dma_adapter->adapter_object.SpinLock);
  3.1056 +  xen_dma_adapter->adapter_object.MapRegisters = NULL;
  3.1057 +  xen_dma_adapter->adapter_object.PagePort = NULL;
  3.1058 +  xen_dma_adapter->adapter_object.ChannelNumber = 0xff;
  3.1059 +  xen_dma_adapter->adapter_object.AdapterNumber = 0;
  3.1060 +  xen_dma_adapter->adapter_object.DmaPortAddress = 0;
  3.1061 +  xen_dma_adapter->adapter_object.AdapterMode = 0;
  3.1062 +  xen_dma_adapter->adapter_object.NeedsMapRegisters = FALSE; /* when true this causes a crash in the crash dump path */
  3.1063 +  xen_dma_adapter->adapter_object.MasterDevice = 1;
  3.1064 +  xen_dma_adapter->adapter_object.Width16Bits = 0;
  3.1065 +  xen_dma_adapter->adapter_object.ScatterGather = device_description->ScatterGather;
  3.1066 +  xen_dma_adapter->adapter_object.IgnoreCount = device_description->IgnoreCount;
  3.1067 +  xen_dma_adapter->adapter_object.Dma32BitAddresses = device_description->Dma32BitAddresses;
  3.1068 +  xen_dma_adapter->adapter_object.Dma64BitAddresses = device_description->Dma64BitAddresses;
  3.1069 +  InitializeListHead(&xen_dma_adapter->adapter_object.AdapterList);  
  3.1070 +  
  3.1071 +  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DMA_OPERATIONS), XENPCI_POOL_TAG);
  3.1072 +  ASSERT(xen_dma_adapter->adapter_object.DmaHeader.DmaOperations);
  3.1073 +  if (xen_dma_adapter->adapter_object.DmaHeader.Version == 1)
  3.1074 +  {
  3.1075 +    xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->Size = FIELD_OFFSET(DMA_OPERATIONS, CalculateScatterGatherList);
  3.1076 +  }
  3.1077 +  else
  3.1078 +  {
  3.1079 +    xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->Size = sizeof(DMA_OPERATIONS);
  3.1080 +  }
  3.1081 +  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->PutDmaAdapter = XenPci_DOP_PutDmaAdapter;
  3.1082 +  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->AllocateCommonBuffer = XenPci_DOP_AllocateCommonBuffer;
  3.1083 +  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->FreeCommonBuffer = XenPci_DOP_FreeCommonBuffer;
  3.1084 +  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->AllocateAdapterChannel = XenPci_DOP_AllocateAdapterChannel;
  3.1085 +  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->FlushAdapterBuffers = XenPci_DOP_FlushAdapterBuffers;
  3.1086 +  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->FreeAdapterChannel = XenPci_DOP_FreeAdapterChannel;
  3.1087 +  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->FreeMapRegisters = XenPci_DOP_FreeMapRegisters;
  3.1088 +  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->MapTransfer = XenPci_DOP_MapTransfer;
  3.1089 +  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->GetDmaAlignment = XenPci_DOP_GetDmaAlignment;
  3.1090 +  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->ReadDmaCounter = XenPci_DOP_ReadDmaCounter;
  3.1091 +  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->GetScatterGatherList = XenPci_DOP_GetScatterGatherList;
  3.1092 +  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->PutScatterGatherList = XenPci_DOP_PutScatterGatherList;
  3.1093 +  if (xen_dma_adapter->adapter_object.DmaHeader.Version == 2)
  3.1094 +  {
  3.1095 +    xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->CalculateScatterGatherList = XenPci_DOP_CalculateScatterGatherList;
  3.1096 +    xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->BuildScatterGatherList = XenPci_DOP_BuildScatterGatherList;
  3.1097 +    xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->BuildMdlFromScatterGatherList = XenPci_DOP_BuildMdlFromScatterGatherList;
  3.1098 +  }
  3.1099 +
  3.1100 +  *number_of_map_registers = xen_dma_adapter->adapter_object.MapRegistersPerChannel; //1024; /* why not... */
  3.1101 +
  3.1102 +  FUNCTION_EXIT();
  3.1103 +
  3.1104 +  return &xen_dma_adapter->adapter_object.DmaHeader;
  3.1105 +}
  3.1106 +
  3.1107 +ULONG
  3.1108 +XenPci_BIS_SetBusData(PVOID context, ULONG data_type, PVOID buffer, ULONG offset, ULONG length)
  3.1109 +{
  3.1110 +  UNREFERENCED_PARAMETER(context);
  3.1111 +  UNREFERENCED_PARAMETER(data_type);
  3.1112 +  UNREFERENCED_PARAMETER(buffer);
  3.1113 +  UNREFERENCED_PARAMETER(offset);
  3.1114 +  UNREFERENCED_PARAMETER(length);
  3.1115 +  
  3.1116 +  FUNCTION_ENTER();
  3.1117 +  FUNCTION_EXIT();
  3.1118 +  return 0;
  3.1119 +}
  3.1120 +
  3.1121 +ULONG
  3.1122 +XenPci_BIS_GetBusData(PVOID context, ULONG data_type, PVOID buffer, ULONG offset, ULONG length)
  3.1123 +{
  3.1124 +  UNREFERENCED_PARAMETER(context);
  3.1125 +  UNREFERENCED_PARAMETER(data_type);
  3.1126 +  UNREFERENCED_PARAMETER(buffer);
  3.1127 +  UNREFERENCED_PARAMETER(offset);
  3.1128 +  UNREFERENCED_PARAMETER(length);
  3.1129 +  
  3.1130 +  FUNCTION_ENTER();
  3.1131 +  FUNCTION_EXIT();
  3.1132 +  return 0;
  3.1133 +}
     4.1 --- a/xenpci/xenpci_pdo.c	Sun Oct 11 14:57:13 2009 +1100
     4.2 +++ b/xenpci/xenpci_pdo.c	Wed Oct 14 14:46:39 2009 +1100
     4.3 @@ -24,1096 +24,6 @@ Foundation, Inc., 51 Franklin Street, Fi
     4.4  #pragma warning(disable : 4200) // zero-sized array
     4.5  #pragma warning(disable: 4127) // conditional expression is constant
     4.6  
     4.7 -#define MAP_TYPE_VIRTUAL  1
     4.8 -#define MAP_TYPE_MDL      2
     4.9 -#define MAP_TYPE_REMAPPED 3
    4.10 -
    4.11 -typedef struct {
    4.12 -  ULONG map_type;
    4.13 -  PVOID aligned_buffer;
    4.14 -  ULONG copy_length;
    4.15 -  PMDL mdl;
    4.16 -  PVOID currentva;
    4.17 -  BOOLEAN allocated_by_me;
    4.18 -} sg_extra_t;
    4.19 -
    4.20 -typedef struct {
    4.21 -  ULONG map_type;
    4.22 -  PVOID aligned_buffer;
    4.23 -  PVOID unaligned_buffer;
    4.24 -  ULONG copy_length;
    4.25 -  PHYSICAL_ADDRESS logical;
    4.26 -} map_register_t;
    4.27 -
    4.28 -typedef struct {
    4.29 -  PDEVICE_OBJECT device_object;
    4.30 -  ULONG total_map_registers;
    4.31 -  ULONG count;
    4.32 -  map_register_t regs[1];
    4.33 -} map_register_base_t;  
    4.34 -
    4.35 -static BOOLEAN
    4.36 -XenPci_BIS_TranslateBusAddress(PVOID context, PHYSICAL_ADDRESS bus_address, ULONG length, PULONG address_space, PPHYSICAL_ADDRESS translated_address)
    4.37 -{
    4.38 -  UNREFERENCED_PARAMETER(context);
    4.39 -  UNREFERENCED_PARAMETER(length);
    4.40 -  /* actually this isn't right - should look up the gref for the physical address and work backwards from that */
    4.41 -  FUNCTION_ENTER();
    4.42 -  if (*address_space != 0)
    4.43 -  {
    4.44 -    KdPrint((__DRIVER_NAME "      Cannot map I/O space\n"));
    4.45 -    FUNCTION_EXIT();
    4.46 -    return FALSE;
    4.47 -  }
    4.48 -  *translated_address = bus_address;
    4.49 -  FUNCTION_EXIT();
    4.50 -  return TRUE;
    4.51 -}
    4.52 -
    4.53 -static VOID
    4.54 -XenPci_DOP_PutDmaAdapter(PDMA_ADAPTER dma_adapter)
    4.55 -{
    4.56 -  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
    4.57 -  
    4.58 -  FUNCTION_ENTER();
    4.59 -
    4.60 -  if (xen_dma_adapter->dma_extension)
    4.61 -    ObDereferenceObject(xen_dma_adapter->dma_extension_driver);
    4.62 -  ExFreePoolWithTag(xen_dma_adapter->adapter_object.DmaHeader.DmaOperations, XENPCI_POOL_TAG);
    4.63 -  ExFreePoolWithTag(xen_dma_adapter, XENPCI_POOL_TAG);
    4.64 -  
    4.65 -  FUNCTION_EXIT();
    4.66 -
    4.67 -  return;
    4.68 -}
    4.69 -
    4.70 -static PVOID
    4.71 -XenPci_DOP_AllocateCommonBuffer(
    4.72 -  PDMA_ADAPTER DmaAdapter,
    4.73 -  ULONG Length,
    4.74 -  PPHYSICAL_ADDRESS LogicalAddress,
    4.75 -  BOOLEAN CacheEnabled
    4.76 -)
    4.77 -{
    4.78 -  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
    4.79 -  PXENPCI_DEVICE_DATA xpdd;
    4.80 -  PVOID buffer;
    4.81 -  PFN_NUMBER pfn;
    4.82 -  grant_ref_t gref;
    4.83 -  
    4.84 -  UNREFERENCED_PARAMETER(DmaAdapter);
    4.85 -  UNREFERENCED_PARAMETER(CacheEnabled);
    4.86 -  
    4.87 -  //FUNCTION_ENTER();
    4.88 -
    4.89 -  xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
    4.90 -
    4.91 -  //KdPrint((__DRIVER_NAME "     Length = %d\n", Length));
    4.92 -  
    4.93 -  buffer = ExAllocatePoolWithTag(NonPagedPool, Length, XENPCI_POOL_TAG);
    4.94 -  ASSERT(buffer); /* lazy */
    4.95 -
    4.96 -  pfn = (PFN_NUMBER)(MmGetPhysicalAddress(buffer).QuadPart >> PAGE_SHIFT);
    4.97 -  ASSERT(pfn); /* lazy */
    4.98 -  gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, INVALID_GRANT_REF);
    4.99 -  ASSERT(gref != INVALID_GRANT_REF); /* lazy */
   4.100 -  LogicalAddress->QuadPart = (gref << PAGE_SHIFT) | (PtrToUlong(buffer) & (PAGE_SIZE - 1));
   4.101 -  
   4.102 -  //FUNCTION_EXIT();
   4.103 -  return buffer;
   4.104 -}
   4.105 -
   4.106 -static VOID
   4.107 -XenPci_DOP_FreeCommonBuffer(
   4.108 -  PDMA_ADAPTER dma_adapter,
   4.109 -  ULONG length,
   4.110 -  PHYSICAL_ADDRESS logical_address,
   4.111 -  PVOID virtual_address,
   4.112 -  BOOLEAN cache_enabled
   4.113 -)
   4.114 -{
   4.115 -  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
   4.116 -  PXENPCI_DEVICE_DATA xpdd;
   4.117 -  grant_ref_t gref;
   4.118 -
   4.119 -  UNREFERENCED_PARAMETER(dma_adapter);
   4.120 -  UNREFERENCED_PARAMETER(length);
   4.121 -  UNREFERENCED_PARAMETER(cache_enabled);
   4.122 -
   4.123 -//  FUNCTION_ENTER();
   4.124 -
   4.125 -  xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   4.126 -  gref = (grant_ref_t)(logical_address.QuadPart >> PAGE_SHIFT);
   4.127 -  //KdPrint((__DRIVER_NAME "     F Releasing Grant Ref %d\n", gref));
   4.128 -  GntTbl_EndAccess(xpdd, gref, FALSE);
   4.129 -  //KdPrint((__DRIVER_NAME "     F Released Grant Ref\n"));
   4.130 -  ExFreePoolWithTag(virtual_address, XENPCI_POOL_TAG);
   4.131 -
   4.132 -//  FUNCTION_EXIT();
   4.133 -}
   4.134 -
   4.135 -static NTSTATUS
   4.136 -XenPci_DOP_AllocateAdapterChannel(
   4.137 -    IN PDMA_ADAPTER dma_adapter,
   4.138 -    IN PDEVICE_OBJECT device_object,
   4.139 -    IN ULONG NumberOfMapRegisters,
   4.140 -    IN PDRIVER_CONTROL ExecutionRoutine,
   4.141 -    IN PVOID Context
   4.142 -    )
   4.143 -{
   4.144 -  //xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
   4.145 -  //PXENPCI_DEVICE_DATA xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   4.146 -  IO_ALLOCATION_ACTION action;
   4.147 -  map_register_base_t *map_register_base;
   4.148 -  
   4.149 -  UNREFERENCED_PARAMETER(dma_adapter);
   4.150 -  
   4.151 -  //FUNCTION_ENTER();
   4.152 -
   4.153 -  map_register_base = ExAllocatePoolWithTag(NonPagedPool, 
   4.154 -    FIELD_OFFSET(map_register_base_t, regs) + NumberOfMapRegisters * sizeof(map_register_t), XENPCI_POOL_TAG);
   4.155 -  if (!map_register_base)
   4.156 -  {
   4.157 -    KdPrint((__DRIVER_NAME "     Cannot allocate memory for map_register_base\n"));
   4.158 -    //FUNCTION_EXIT();
   4.159 -    return STATUS_INSUFFICIENT_RESOURCES;
   4.160 -  }
   4.161 -  /* we should also allocate a single page of memory here for remap purposes as once we allocate the map registers there is no failure allowed */
   4.162 -  map_register_base->device_object = device_object;
   4.163 -  map_register_base->total_map_registers = NumberOfMapRegisters;
   4.164 -  map_register_base->count = 0;
   4.165 -  
   4.166 -  action = ExecutionRoutine(device_object, device_object->CurrentIrp, map_register_base, Context);
   4.167 -  
   4.168 -  switch (action)
   4.169 -  {
   4.170 -  case KeepObject:
   4.171 -    KdPrint((__DRIVER_NAME "     KeepObject\n"));
   4.172 -    ASSERT(FALSE);
   4.173 -    break;
   4.174 -  case DeallocateObject:
   4.175 -    KdPrint((__DRIVER_NAME "     DeallocateObject\n"));
   4.176 -    ASSERT(FALSE);
   4.177 -    break;
   4.178 -  case DeallocateObjectKeepRegisters:
   4.179 -    //KdPrint((__DRIVER_NAME "     DeallocateObjectKeepRegisters\n"));
   4.180 -    break;
   4.181 -  default:
   4.182 -    KdPrint((__DRIVER_NAME "     Unknown action %d\n", action));
   4.183 -    ASSERT(FALSE);
   4.184 -    break;
   4.185 -  }
   4.186 -  //FUNCTION_EXIT();
   4.187 -  return STATUS_SUCCESS;
   4.188 -}
   4.189 -
   4.190 -static BOOLEAN
   4.191 -XenPci_DOP_FlushAdapterBuffers(
   4.192 -  PDMA_ADAPTER dma_adapter,
   4.193 -  PMDL mdl,
   4.194 -  PVOID MapRegisterBase,
   4.195 -  PVOID CurrentVa,
   4.196 -  ULONG Length,
   4.197 -  BOOLEAN write_to_device)
   4.198 -{
   4.199 -  //xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
   4.200 -  //PXENPCI_DEVICE_DATA xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   4.201 -  map_register_base_t *map_register_base = MapRegisterBase;
   4.202 -  map_register_t *map_register;
   4.203 -  ULONG i;
   4.204 -  
   4.205 -  UNREFERENCED_PARAMETER(dma_adapter);
   4.206 -  UNREFERENCED_PARAMETER(mdl);
   4.207 -  UNREFERENCED_PARAMETER(CurrentVa);
   4.208 -  UNREFERENCED_PARAMETER(Length);
   4.209 -
   4.210 -  //FUNCTION_ENTER();
   4.211 -  
   4.212 -  for (i = 0; i < map_register_base->count; i++)
   4.213 -  {
   4.214 -    map_register = &map_register_base->regs[i];
   4.215 -    if (map_register->map_type == MAP_TYPE_REMAPPED && !write_to_device)
   4.216 -      memcpy(map_register->unaligned_buffer, map_register->aligned_buffer, map_register->copy_length);
   4.217 -  }
   4.218 -  //FUNCTION_EXIT();
   4.219 -  
   4.220 -  return TRUE;
   4.221 -}
   4.222 -
   4.223 -static VOID
   4.224 -XenPci_DOP_FreeAdapterChannel(
   4.225 -    IN PDMA_ADAPTER  DmaAdapter
   4.226 -    )
   4.227 -{
   4.228 -  UNREFERENCED_PARAMETER(DmaAdapter);
   4.229 -
   4.230 -  FUNCTION_ENTER();
   4.231 -  FUNCTION_EXIT();
   4.232 -}
   4.233 -
   4.234 -static VOID
   4.235 -XenPci_DOP_FreeMapRegisters(
   4.236 -  PDMA_ADAPTER dma_adapter,
   4.237 -  PVOID MapRegisterBase,
   4.238 -  ULONG NumberOfMapRegisters)
   4.239 -{
   4.240 -  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
   4.241 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   4.242 -  map_register_base_t *map_register_base = MapRegisterBase;
   4.243 -  map_register_t *map_register;
   4.244 -  ULONG i;
   4.245 -  grant_ref_t gref;
   4.246 -
   4.247 -  //FUNCTION_ENTER();
   4.248 -  if (!map_register_base)
   4.249 -  {
   4.250 -    /* i'm not sure if this is ideal here, but NDIS definitely does it */
   4.251 -    return;
   4.252 -  }
   4.253 -  ASSERT(map_register_base->total_map_registers == NumberOfMapRegisters);
   4.254 -
   4.255 -  for (i = 0; i < map_register_base->count; i++)
   4.256 -  {
   4.257 -    map_register = &map_register_base->regs[i];
   4.258 -    switch (map_register->map_type)
   4.259 -    {
   4.260 -    case MAP_TYPE_REMAPPED:
   4.261 -      gref = (grant_ref_t)(map_register->logical.QuadPart >> PAGE_SHIFT);
   4.262 -      //KdPrint((__DRIVER_NAME "     D Releasing Grant Ref %d\n", gref));
   4.263 -      GntTbl_EndAccess(xpdd, gref, FALSE);
   4.264 -      //KdPrint((__DRIVER_NAME "     D Released Grant Ref\n"));
   4.265 -      ExFreePoolWithTag(map_register->aligned_buffer, XENPCI_POOL_TAG);
   4.266 -      break;
   4.267 -    case MAP_TYPE_MDL:
   4.268 -      gref = (grant_ref_t)(map_register->logical.QuadPart >> PAGE_SHIFT);
   4.269 -      //KdPrint((__DRIVER_NAME "     E Releasing Grant Ref %d\n", gref));
   4.270 -      GntTbl_EndAccess(xpdd, gref, FALSE);
   4.271 -      //KdPrint((__DRIVER_NAME "     E Released Grant Ref\n"));
   4.272 -      break;
   4.273 -    case MAP_TYPE_VIRTUAL:
   4.274 -      break;
   4.275 -    }
   4.276 -  }
   4.277 -  ExFreePoolWithTag(map_register_base, XENPCI_POOL_TAG);
   4.278 -
   4.279 -  //FUNCTION_EXIT();
   4.280 -}
   4.281 -
   4.282 -static PHYSICAL_ADDRESS
   4.283 -XenPci_DOP_MapTransfer(
   4.284 -    PDMA_ADAPTER dma_adapter,
   4.285 -    PMDL mdl,
   4.286 -    PVOID MapRegisterBase,
   4.287 -    PVOID CurrentVa,
   4.288 -    PULONG Length,
   4.289 -    BOOLEAN WriteToDevice)
   4.290 -{
   4.291 -  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
   4.292 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   4.293 -  map_register_base_t *map_register_base = MapRegisterBase;
   4.294 -  map_register_t *map_register = &map_register_base->regs[map_register_base->count];
   4.295 -  PDEVICE_OBJECT device_object = map_register_base->device_object;
   4.296 -  ULONG page_offset;
   4.297 -  PFN_NUMBER pfn;
   4.298 -  grant_ref_t gref;
   4.299 -  PUCHAR ptr;
   4.300 -  ULONG mdl_offset;
   4.301 -  ULONG pfn_index;
   4.302 -
   4.303 -  //FUNCTION_ENTER();
   4.304 -
   4.305 -  //KdPrint((__DRIVER_NAME "     Mdl = %p, MapRegisterBase = %p, MdlVa = %p, CurrentVa = %p, Length = %d\n",
   4.306 -  //  mdl, MapRegisterBase, MmGetMdlVirtualAddress(mdl), CurrentVa, *Length));
   4.307 -
   4.308 -  ASSERT(mdl);
   4.309 -  ASSERT(map_register_base);
   4.310 -  ASSERT(map_register_base->count < map_register_base->total_map_registers);
   4.311 -  
   4.312 -  if (xen_dma_adapter->dma_extension)
   4.313 -  {
   4.314 -    if (xen_dma_adapter->dma_extension->need_virtual_address && xen_dma_adapter->dma_extension->need_virtual_address(device_object->CurrentIrp))
   4.315 -    {
   4.316 -      map_register->map_type = MAP_TYPE_VIRTUAL;
   4.317 -    }
   4.318 -    else
   4.319 -    {
   4.320 -      if (xen_dma_adapter->dma_extension->get_alignment)
   4.321 -      {
   4.322 -        ULONG alignment = xen_dma_adapter->dma_extension->get_alignment(device_object->CurrentIrp);
   4.323 -        if ((MmGetMdlByteOffset(mdl) & (alignment - 1)) || (MmGetMdlByteCount(mdl) & (alignment - 1)))
   4.324 -        {
   4.325 -          map_register->map_type = MAP_TYPE_REMAPPED;
   4.326 -        }
   4.327 -        else
   4.328 -        {
   4.329 -          map_register->map_type = MAP_TYPE_MDL;
   4.330 -        }
   4.331 -      }
   4.332 -      else
   4.333 -      {
   4.334 -        map_register->map_type = MAP_TYPE_MDL;
   4.335 -      }
   4.336 -    }
   4.337 -  }
   4.338 -  else
   4.339 -  {
   4.340 -    map_register->map_type = MAP_TYPE_MDL;
   4.341 -  }
   4.342 -
   4.343 -  switch (map_register->map_type)
   4.344 -  {
   4.345 -  case MAP_TYPE_MDL:
   4.346 -    //KdPrint((__DRIVER_NAME "     MAP_TYPE_MDL\n"));
   4.347 -    mdl_offset = (ULONG)((UINT_PTR)CurrentVa - (UINT_PTR)MmGetMdlVirtualAddress(mdl));
   4.348 -    page_offset = PtrToUlong(CurrentVa) & (PAGE_SIZE - 1);
   4.349 -    *Length = min(*Length, PAGE_SIZE - page_offset);
   4.350 -    pfn_index = (ULONG)(((UINT_PTR)CurrentVa >> PAGE_SHIFT) - ((UINT_PTR)MmGetMdlVirtualAddress(mdl) >> PAGE_SHIFT));
   4.351 -    //KdPrint((__DRIVER_NAME "     mdl_offset = %d, page_offset = %d, length = %d, pfn_index = %d\n",
   4.352 -    //  mdl_offset, page_offset, *Length, pfn_index));
   4.353 -    pfn = MmGetMdlPfnArray(mdl)[pfn_index];
   4.354 -    //KdPrint((__DRIVER_NAME "     B Requesting Grant Ref\n"));
   4.355 -    gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, INVALID_GRANT_REF);
   4.356 -    //KdPrint((__DRIVER_NAME "     B Got Grant Ref %d\n", gref));
   4.357 -    map_register->logical.QuadPart = (LONGLONG)(gref << PAGE_SHIFT) | page_offset;
   4.358 -    map_register_base->count++;
   4.359 -    break;
   4.360 -  case MAP_TYPE_REMAPPED:
   4.361 -    //KdPrint((__DRIVER_NAME "     MAP_TYPE_REMAPPED (MapTransfer)\n"));
   4.362 -    //KdPrint((__DRIVER_NAME "     Mdl = %p, MapRegisterBase = %p, MdlVa = %p, CurrentVa = %p, Length = %d\n",
   4.363 -    //  mdl, MapRegisterBase, MmGetMdlVirtualAddress(mdl), CurrentVa, *Length));
   4.364 -    mdl_offset = (ULONG)((UINT_PTR)CurrentVa - (UINT_PTR)MmGetMdlVirtualAddress(mdl));
   4.365 -    *Length = min(*Length, PAGE_SIZE);
   4.366 -    map_register->aligned_buffer = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
   4.367 -    ASSERT(map_register->aligned_buffer);
   4.368 -    map_register->unaligned_buffer = MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority);
   4.369 -    ASSERT(map_register->unaligned_buffer); /* lazy */
   4.370 -    map_register->unaligned_buffer = (PUCHAR)map_register->unaligned_buffer + mdl_offset;
   4.371 -    map_register->copy_length = *Length;
   4.372 -    if (WriteToDevice)
   4.373 -      memcpy(map_register->aligned_buffer, map_register->unaligned_buffer, map_register->copy_length);
   4.374 -    pfn = (PFN_NUMBER)(MmGetPhysicalAddress(map_register->aligned_buffer).QuadPart >> PAGE_SHIFT);
   4.375 -    //KdPrint((__DRIVER_NAME "     C Requesting Grant Ref\n"));
   4.376 -    gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, INVALID_GRANT_REF);
   4.377 -    //KdPrint((__DRIVER_NAME "     C Got Grant Ref %d\n", gref));
   4.378 -    map_register->logical.QuadPart = (LONGLONG)(gref << PAGE_SHIFT);
   4.379 -    map_register_base->count++;
   4.380 -    break;
   4.381 -  case MAP_TYPE_VIRTUAL:
   4.382 -    //KdPrint((__DRIVER_NAME "     MAP_TYPE_VIRTUAL\n"));
   4.383 -    ptr = MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority);
   4.384 -    ASSERT(ptr); /* lazy */
   4.385 -    map_register->logical.QuadPart = (ULONGLONG)ptr;
   4.386 -    map_register_base->count++;
   4.387 -    break;
   4.388 -  default:
   4.389 -    ASSERT(FALSE);
   4.390 -    break;
   4.391 -  }
   4.392 -  
   4.393 -  //KdPrint((__DRIVER_NAME "     logical = %08x:%08x\n", map_register->logical.HighPart, map_register->logical.LowPart));
   4.394 -  //FUNCTION_EXIT();
   4.395 -  return map_register->logical;
   4.396 -}
   4.397 -
   4.398 -static ULONG
   4.399 -XenPci_DOP_GetDmaAlignment(
   4.400 -  PDMA_ADAPTER DmaAdapter)
   4.401 -{
   4.402 -  UNREFERENCED_PARAMETER(DmaAdapter);
   4.403 -
   4.404 -  FUNCTION_ENTER();
   4.405 -  FUNCTION_EXIT();
   4.406 -  return 0;
   4.407 -}
   4.408 -
   4.409 -static ULONG
   4.410 -XenPci_DOP_ReadDmaCounter(
   4.411 -  PDMA_ADAPTER DmaAdapter)
   4.412 -{
   4.413 -  UNREFERENCED_PARAMETER(DmaAdapter);
   4.414 -
   4.415 -  FUNCTION_ENTER();
   4.416 -  FUNCTION_EXIT();
   4.417 -  return 0;
   4.418 -}
   4.419 -
   4.420 -static VOID
   4.421 -XenPci_DOP_PutScatterGatherList(
   4.422 -    IN PDMA_ADAPTER DmaAdapter,
   4.423 -    IN PSCATTER_GATHER_LIST sg_list,
   4.424 -    IN BOOLEAN WriteToDevice
   4.425 -    )
   4.426 -{
   4.427 -  xen_dma_adapter_t *xen_dma_adapter;
   4.428 -  PXENPCI_DEVICE_DATA xpdd;
   4.429 -  ULONG i;
   4.430 -  sg_extra_t *sg_extra;
   4.431 -  PMDL curr_mdl;
   4.432 -  ULONG offset;
   4.433 -  BOOLEAN active;
   4.434 -
   4.435 -  UNREFERENCED_PARAMETER(WriteToDevice);
   4.436 -  
   4.437 -  //FUNCTION_ENTER();
   4.438 -
   4.439 -  xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
   4.440 -  ASSERT(xen_dma_adapter);
   4.441 -  xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   4.442 -  
   4.443 -  sg_extra = (sg_extra_t *)((PUCHAR)sg_list + FIELD_OFFSET(SCATTER_GATHER_LIST, Elements) +
   4.444 -    (sizeof(SCATTER_GATHER_ELEMENT)) * sg_list->NumberOfElements);
   4.445 -
   4.446 -  switch (sg_extra->map_type)
   4.447 -  {
   4.448 -  case MAP_TYPE_REMAPPED:
   4.449 -    for (i = 0; i < sg_list->NumberOfElements; i++)
   4.450 -    {
   4.451 -      grant_ref_t gref;
   4.452 -      gref = (grant_ref_t)(sg_list->Elements[i].Address.QuadPart >> PAGE_SHIFT);
   4.453 -      GntTbl_EndAccess(xpdd, gref, FALSE);
   4.454 -      sg_list->Elements[i].Address.QuadPart = -1;
   4.455 -    }
   4.456 -    ASSERT(sg_extra->mdl);
   4.457 -    if (!WriteToDevice)
   4.458 -    {
   4.459 -      for (curr_mdl = sg_extra->mdl, offset = 0, active = FALSE; curr_mdl; curr_mdl = curr_mdl->Next)
   4.460 -      {
   4.461 -        PVOID mdl_start_va = MmGetMdlVirtualAddress(curr_mdl);
   4.462 -        ULONG mdl_byte_count = MmGetMdlByteCount(curr_mdl);
   4.463 -        ULONG mdl_offset = 0;
   4.464 -        /* need to use <= va + len - 1 to avoid ptr wraparound */
   4.465 -        if ((UINT_PTR)sg_extra->currentva >= (UINT_PTR)mdl_start_va && (UINT_PTR)sg_extra->currentva <= (UINT_PTR)mdl_start_va + mdl_byte_count - 1)
   4.466 -        {
   4.467 -          active = TRUE;
   4.468 -          mdl_byte_count -= (ULONG)((UINT_PTR)sg_extra->currentva - (UINT_PTR)mdl_start_va);
   4.469 -          mdl_offset = (ULONG)((UINT_PTR)sg_extra->currentva - (UINT_PTR)mdl_start_va);
   4.470 -          mdl_start_va = sg_extra->currentva;
   4.471 -        }
   4.472 -        if (active)
   4.473 -        {
   4.474 -          PVOID unaligned_buffer;
   4.475 -          unaligned_buffer = MmGetSystemAddressForMdlSafe(curr_mdl, NormalPagePriority);
   4.476 -          ASSERT(unaligned_buffer); /* lazy */
   4.477 -          memcpy((PUCHAR)unaligned_buffer + mdl_offset, (PUCHAR)sg_extra->aligned_buffer + offset, mdl_byte_count);
   4.478 -          offset += mdl_byte_count;
   4.479 -        }
   4.480 -      }
   4.481 -    }
   4.482 -    ExFreePoolWithTag(sg_extra->aligned_buffer, XENPCI_POOL_TAG);
   4.483 -    break;
   4.484 -  case MAP_TYPE_MDL:
   4.485 -    for (i = 0; i < sg_list->NumberOfElements; i++)
   4.486 -    {
   4.487 -      grant_ref_t gref;
   4.488 -      gref = (grant_ref_t)(sg_list->Elements[i].Address.QuadPart >> PAGE_SHIFT);
   4.489 -      GntTbl_EndAccess(xpdd, gref, FALSE);
   4.490 -      sg_list->Elements[i].Address.QuadPart = -1;
   4.491 -    }
   4.492 -    break;
   4.493 -  case MAP_TYPE_VIRTUAL:
   4.494 -    break;
   4.495 -  }
   4.496 -  if (sg_extra->allocated_by_me)
   4.497 -    ExFreePoolWithTag(sg_list, XENPCI_POOL_TAG);
   4.498 -  //FUNCTION_EXIT();
   4.499 -}
   4.500 -
   4.501 -static NTSTATUS
   4.502 -XenPci_DOP_CalculateScatterGatherList(
   4.503 -  PDMA_ADAPTER DmaAdapter,
   4.504 -  PMDL Mdl,
   4.505 -  PVOID CurrentVa,
   4.506 -  ULONG Length,
   4.507 -  PULONG ScatterGatherListSize,
   4.508 -  PULONG NumberOfMapRegisters
   4.509 -  )
   4.510 -{
   4.511 -  xen_dma_adapter_t *xen_dma_adapter;
   4.512 -  ULONG elements;
   4.513 -  PMDL curr_mdl;
   4.514 -  
   4.515 -  UNREFERENCED_PARAMETER(CurrentVa);
   4.516 -    
   4.517 -  //FUNCTION_ENTER();
   4.518 -  
   4.519 -  //KdPrint((__DRIVER_NAME "     Mdl = %p\n", Mdl));
   4.520 -  //KdPrint((__DRIVER_NAME "     CurrentVa = %p\n", CurrentVa));
   4.521 -  //KdPrint((__DRIVER_NAME "     Length = %d\n", Length));
   4.522 -
   4.523 -  xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
   4.524 -
   4.525 -  if (Mdl)
   4.526 -  {
   4.527 -    //if (CurrentVa != MmGetMdlVirtualAddress(Mdl))
   4.528 -    //{
   4.529 -    //  KdPrint((__DRIVER_NAME "     CurrentVa (%p) != MdlVa (%p)\n", CurrentVa, MmGetMdlVirtualAddress(Mdl)));
   4.530 -    //
   4.531 -
   4.532 -    //KdPrint((__DRIVER_NAME "     CurrentVa = %p, MdlVa = %p\n", CurrentVa, MmGetMdlVirtualAddress(Mdl)));
   4.533 -
   4.534 -    for (curr_mdl = Mdl, elements = 0; curr_mdl; curr_mdl = curr_mdl->Next)
   4.535 -    {
   4.536 -      //KdPrint((__DRIVER_NAME "     curr_mdlVa = %p, curr_mdl size = %d\n", MmGetMdlVirtualAddress(curr_mdl), MmGetMdlByteCount(curr_mdl)));
   4.537 -      elements += ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(curr_mdl), MmGetMdlByteCount(curr_mdl));
   4.538 -    }
   4.539 -  }
   4.540 -  else
   4.541 -  {
   4.542 -    elements = ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, Length); // + 1;
   4.543 -  }
   4.544 -
   4.545 -  if (elements > xen_dma_adapter->adapter_object.MapRegistersPerChannel)
   4.546 -  {
   4.547 -    //KdPrint((__DRIVER_NAME "     elements = %d - too many\n", elements));
   4.548 -    if (NumberOfMapRegisters)
   4.549 -      *NumberOfMapRegisters = 0;
   4.550 -    *ScatterGatherListSize = 0;
   4.551 -    
   4.552 -    return STATUS_INSUFFICIENT_RESOURCES;
   4.553 -  }
   4.554 -  
   4.555 -  *ScatterGatherListSize = FIELD_OFFSET(SCATTER_GATHER_LIST, Elements)
   4.556 -    + sizeof(SCATTER_GATHER_ELEMENT) * elements
   4.557 -    + sizeof(sg_extra_t);
   4.558 -  if (NumberOfMapRegisters)
   4.559 -    *NumberOfMapRegisters = elements;
   4.560 -
   4.561 -  //KdPrint((__DRIVER_NAME "     ScatterGatherListSize = %d, NumberOfMapRegisters = %d\n", *ScatterGatherListSize, elements));
   4.562 -
   4.563 -  //FUNCTION_EXIT();
   4.564 -  return STATUS_SUCCESS;
   4.565 -}
   4.566 -
   4.567 -static NTSTATUS
   4.568 -XenPci_DOP_BuildScatterGatherListButDontExecute(
   4.569 -  IN PDMA_ADAPTER DmaAdapter,
   4.570 -  IN PDEVICE_OBJECT DeviceObject,
   4.571 -  IN PMDL Mdl,
   4.572 -  IN PVOID CurrentVa,
   4.573 -  IN ULONG Length,
   4.574 -  IN BOOLEAN WriteToDevice,
   4.575 -  IN PVOID ScatterGatherBuffer,
   4.576 -  IN ULONG ScatterGatherBufferLength,
   4.577 -  BOOLEAN allocated_by_me)
   4.578 -{
   4.579 -  ULONG i;
   4.580 -  PSCATTER_GATHER_LIST sglist = ScatterGatherBuffer;
   4.581 -  PUCHAR ptr;
   4.582 -  ULONG remaining = Length;
   4.583 -  ULONG total_remaining;
   4.584 -  xen_dma_adapter_t *xen_dma_adapter;
   4.585 -  PXENPCI_DEVICE_DATA xpdd;
   4.586 -  sg_extra_t *sg_extra;
   4.587 -  PMDL curr_mdl;
   4.588 -  ULONG map_type;
   4.589 -  ULONG sg_element;
   4.590 -  ULONG offset;
   4.591 -  PFN_NUMBER pfn;
   4.592 -  grant_ref_t gref;
   4.593 -  BOOLEAN active;
   4.594 -  PVOID mdl_start_va;
   4.595 -  ULONG mdl_byte_count;
   4.596 -  ULONG mdl_offset;
   4.597 -  ULONG remapped_bytes = 0;
   4.598 -  
   4.599 -  //FUNCTION_ENTER();
   4.600 -  
   4.601 -  if (!ScatterGatherBuffer)
   4.602 -  {
   4.603 -    KdPrint((__DRIVER_NAME "     NULL ScatterGatherBuffer\n"));
   4.604 -    return STATUS_INVALID_PARAMETER;
   4.605 -  }
   4.606 -  //if (MmGetMdlVirtualAddress(Mdl) != CurrentVa)
   4.607 -  //{
   4.608 -  //  KdPrint((__DRIVER_NAME "     MmGetMdlVirtualAddress = %p, CurrentVa = %p, Length = %d\n", MmGetMdlVirtualAddress(Mdl), CurrentVa, Length));
   4.609 -  //}
   4.610 -
   4.611 -  xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
   4.612 -  xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   4.613 -
   4.614 -  ASSERT(Mdl);
   4.615 -  
   4.616 -  if (xen_dma_adapter->dma_extension)
   4.617 -  {
   4.618 -    if (xen_dma_adapter->dma_extension->need_virtual_address && xen_dma_adapter->dma_extension->need_virtual_address(DeviceObject->CurrentIrp))
   4.619 -    {
   4.620 -      ASSERT(!Mdl->Next); /* can only virtual a single buffer */
   4.621 -      //ASSERT(MmGetMdlVirtualAddress(Mdl) == CurrentVa);
   4.622 -      map_type = MAP_TYPE_VIRTUAL;
   4.623 -      sglist->NumberOfElements = 1;
   4.624 -    }
   4.625 -    else
   4.626 -    {
   4.627 -      if (xen_dma_adapter->dma_extension->get_alignment)
   4.628 -      {
   4.629 -        ULONG alignment = xen_dma_adapter->dma_extension->get_alignment(DeviceObject->CurrentIrp);
   4.630 -
   4.631 -        map_type = MAP_TYPE_MDL;
   4.632 -        sglist->NumberOfElements = 0;
   4.633 -        for (curr_mdl = Mdl, remapped_bytes = 0, active = FALSE; curr_mdl; curr_mdl = curr_mdl->Next)
   4.634 -        {
   4.635 -          mdl_start_va = MmGetMdlVirtualAddress(curr_mdl);
   4.636 -          mdl_byte_count = MmGetMdlByteCount(curr_mdl);
   4.637 -          /* need to use <= va + len - 1 to avoid ptr wraparound */
   4.638 -          if ((UINT_PTR)CurrentVa >= (UINT_PTR)mdl_start_va && (UINT_PTR)CurrentVa <= (UINT_PTR)mdl_start_va + mdl_byte_count - 1)
   4.639 -          {
   4.640 -            active = TRUE;
   4.641 -            mdl_byte_count -= (ULONG)((UINT_PTR)CurrentVa - (UINT_PTR)mdl_start_va);
   4.642 -            mdl_start_va = CurrentVa;
   4.643 -          }
   4.644 -          if (active)
   4.645 -          {
   4.646 -            if (((UINT_PTR)mdl_start_va & (alignment - 1)) || (mdl_byte_count & (alignment - 1)))
   4.647 -              map_type = MAP_TYPE_REMAPPED;
   4.648 -            remapped_bytes += mdl_byte_count;
   4.649 -          }
   4.650 -        }
   4.651 -        sglist->NumberOfElements += ADDRESS_AND_SIZE_TO_SPAN_PAGES(NULL, remapped_bytes);
   4.652 -      }
   4.653 -      else
   4.654 -      {
   4.655 -        map_type = MAP_TYPE_MDL;
   4.656 -      }
   4.657 -    }
   4.658 -  }
   4.659 -  else
   4.660 -  {
   4.661 -    map_type = MAP_TYPE_MDL;
   4.662 -  }
   4.663 -  if (map_type == MAP_TYPE_MDL)
   4.664 -  {    
   4.665 -    for (curr_mdl = Mdl, sglist->NumberOfElements = 0, total_remaining = Length, active = FALSE; total_remaining > 0; curr_mdl = curr_mdl->Next)
   4.666 -    {
   4.667 -      ASSERT(curr_mdl);
   4.668 -      mdl_start_va = MmGetMdlVirtualAddress(curr_mdl);
   4.669 -      mdl_byte_count = MmGetMdlByteCount(curr_mdl);
   4.670 -      /* need to use <= va + len - 1 to avoid ptr wraparound */
   4.671 -      if ((UINT_PTR)CurrentVa >= (UINT_PTR)mdl_start_va && (UINT_PTR)CurrentVa <= (UINT_PTR)mdl_start_va + mdl_byte_count - 1)
   4.672 -      {
   4.673 -        active = TRUE;
   4.674 -        mdl_byte_count -= (ULONG)((UINT_PTR)CurrentVa - (UINT_PTR)mdl_start_va);
   4.675 -        mdl_start_va = CurrentVa;
   4.676 -      }
   4.677 -      mdl_byte_count = min(mdl_byte_count, total_remaining);
   4.678 -      if (active && mdl_byte_count)
   4.679 -      {
   4.680 -        sglist->NumberOfElements += ADDRESS_AND_SIZE_TO_SPAN_PAGES(
   4.681 -          mdl_start_va, mdl_byte_count);
   4.682 -        total_remaining -= mdl_byte_count;
   4.683 -      }
   4.684 -    }
   4.685 -  }
   4.686 -  if (ScatterGatherBufferLength < FIELD_OFFSET(SCATTER_GATHER_LIST, Elements) +
   4.687 -    sizeof(SCATTER_GATHER_ELEMENT) * sglist->NumberOfElements + sizeof(sg_extra_t))
   4.688 -  {
   4.689 -    //KdPrint((__DRIVER_NAME "     STATUS_BUFFER_TOO_SMALL (%d < %d)\n", ScatterGatherBufferLength, FIELD_OFFSET(SCATTER_GATHER_LIST, Elements) +
   4.690 -    //  sizeof(SCATTER_GATHER_ELEMENT) * sglist->NumberOfElements + sizeof(sg_extra_t)));
   4.691 -    return STATUS_BUFFER_TOO_SMALL;
   4.692 -  }
   4.693 -  
   4.694 -  sg_extra = (sg_extra_t *)((PUCHAR)sglist + FIELD_OFFSET(SCATTER_GATHER_LIST, Elements) +
   4.695 -    (sizeof(SCATTER_GATHER_ELEMENT)) * sglist->NumberOfElements);
   4.696 -
   4.697 -  sg_extra->allocated_by_me = allocated_by_me;
   4.698 -  
   4.699 -  sg_extra->map_type = map_type;
   4.700 -  switch (map_type)
   4.701 -  {
   4.702 -  case MAP_TYPE_MDL:
   4.703 -    //KdPrint((__DRIVER_NAME "     MAP_TYPE_MDL - %p\n", MmGetMdlVirtualAddress(Mdl)));
   4.704 -    total_remaining = Length;
   4.705 -    for (sg_element = 0, curr_mdl = Mdl, active = FALSE; total_remaining > 0; curr_mdl = curr_mdl->Next)
   4.706 -    {
   4.707 -      ASSERT(curr_mdl);
   4.708 -      mdl_start_va = MmGetMdlVirtualAddress(curr_mdl);
   4.709 -      mdl_byte_count = MmGetMdlByteCount(curr_mdl);
   4.710 -      /* need to use <= va + len - 1 to avoid ptr wraparound */
   4.711 -      if ((UINT_PTR)CurrentVa >= (UINT_PTR)mdl_start_va && (UINT_PTR)CurrentVa <= (UINT_PTR)mdl_start_va + mdl_byte_count - 1)
   4.712 -      {
   4.713 -        active = TRUE;
   4.714 -        mdl_byte_count -= (ULONG)((UINT_PTR)CurrentVa - (UINT_PTR)mdl_start_va);
   4.715 -        mdl_start_va = CurrentVa;
   4.716 -      }
   4.717 -      if (active && mdl_byte_count)
   4.718 -      {
   4.719 -        ULONG pfn_offset;
   4.720 -        remaining = min(mdl_byte_count, total_remaining);
   4.721 -        offset = (ULONG)((UINT_PTR)mdl_start_va & (PAGE_SIZE - 1));
   4.722 -        pfn_offset = (ULONG)(((UINT_PTR)mdl_start_va >> PAGE_SHIFT) - ((UINT_PTR)MmGetMdlVirtualAddress(curr_mdl) >> PAGE_SHIFT));
   4.723 -        //for (i = 0; i < ADDRESS_AND_SIZE_TO_SPAN_PAGES(mdl_start_va, mdl_byte_count); i++)
   4.724 -        for (i = 0; remaining > 0; i++)
   4.725 -        {
   4.726 -          pfn = MmGetMdlPfnArray(curr_mdl)[pfn_offset + i];
   4.727 -          ASSERT(pfn);
   4.728 -          gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, INVALID_GRANT_REF);
   4.729 -          ASSERT(gref != INVALID_GRANT_REF);
   4.730 -          sglist->Elements[sg_element].Address.QuadPart = (LONGLONG)(gref << PAGE_SHIFT) | offset;
   4.731 -          sglist->Elements[sg_element].Length = min(min(PAGE_SIZE - offset, remaining), total_remaining);
   4.732 -          total_remaining -= sglist->Elements[sg_element].Length;
   4.733 -          remaining -= sglist->Elements[sg_element].Length;
   4.734 -          offset = 0;
   4.735 -          sg_element++;
   4.736 -        }
   4.737 -      }
   4.738 -    }
   4.739 -    if (sg_element != sglist->NumberOfElements)
   4.740 -    {
   4.741 -      KdPrint((__DRIVER_NAME "     sg_element = %d, sglist->NumberOfElements = %d\n", sg_element, sglist->NumberOfElements));
   4.742 -      KdPrint((__DRIVER_NAME "     CurrentVa = %p, Length = %d\n", CurrentVa, Length));
   4.743 -for (curr_mdl = Mdl; curr_mdl; curr_mdl = curr_mdl->Next)
   4.744 -{
   4.745 -  KdPrint((__DRIVER_NAME "     Mdl = %p, VirtualAddress = %p, ByteCount = %d\n", Mdl, MmGetMdlVirtualAddress(curr_mdl), MmGetMdlByteCount(curr_mdl)));
   4.746 -}
   4.747 -    }
   4.748 -    ASSERT(sg_element == sglist->NumberOfElements);
   4.749 -    break;
   4.750 -  case MAP_TYPE_REMAPPED:
   4.751 -    sg_extra->aligned_buffer = ExAllocatePoolWithTag(NonPagedPool, max(remapped_bytes, PAGE_SIZE), XENPCI_POOL_TAG);
   4.752 -    if (!sg_extra->aligned_buffer)
   4.753 -    {
   4.754 -      KdPrint((__DRIVER_NAME "     MAP_TYPE_REMAPPED buffer allocation failed - requested va = %p, length = %d\n", MmGetMdlVirtualAddress(Mdl), remapped_bytes));
   4.755 -      return STATUS_INSUFFICIENT_RESOURCES;
   4.756 -    }
   4.757 -    //KdPrint((__DRIVER_NAME "     MAP_TYPE_REMAPPED - %p\n", sg_extra->aligned_buffer));
   4.758 -    sg_extra->mdl = Mdl;
   4.759 -    sg_extra->currentva = CurrentVa;
   4.760 -    sg_extra->copy_length = remapped_bytes;
   4.761 -
   4.762 -    if (WriteToDevice)
   4.763 -    {
   4.764 -      for (curr_mdl = Mdl, offset = 0, active = FALSE; curr_mdl; curr_mdl = curr_mdl->Next)
   4.765 -      {
   4.766 -        mdl_start_va = MmGetMdlVirtualAddress(curr_mdl);
   4.767 -        mdl_byte_count = MmGetMdlByteCount(curr_mdl);
   4.768 -        mdl_offset = 0;
   4.769 -        /* need to use <= va + len - 1 to avoid ptr wraparound */
   4.770 -        if ((UINT_PTR)CurrentVa >= (UINT_PTR)mdl_start_va && (UINT_PTR)CurrentVa <= (UINT_PTR)mdl_start_va + mdl_byte_count - 1)
   4.771 -        {
   4.772 -          active = TRUE;
   4.773 -          mdl_byte_count -= (ULONG)((UINT_PTR)CurrentVa - (UINT_PTR)mdl_start_va);
   4.774 -          mdl_offset = (ULONG)((UINT_PTR)CurrentVa - (UINT_PTR)mdl_start_va);
   4.775 -          mdl_start_va = CurrentVa;
   4.776 -        }
   4.777 -        if (active)
   4.778 -        {
   4.779 -          PVOID unaligned_buffer;
   4.780 -          unaligned_buffer = (PUCHAR)MmGetSystemAddressForMdlSafe(curr_mdl, NormalPagePriority);
   4.781 -          ASSERT(unaligned_buffer); /* lazy */
   4.782 -          memcpy((PUCHAR)sg_extra->aligned_buffer + offset, (PUCHAR)unaligned_buffer + mdl_offset, mdl_byte_count);
   4.783 -          offset += mdl_byte_count;
   4.784 -        }
   4.785 -      }
   4.786 -    }
   4.787 -    for (sg_element = 0, remaining = remapped_bytes; 
   4.788 -      sg_element < ADDRESS_AND_SIZE_TO_SPAN_PAGES(sg_extra->aligned_buffer, remapped_bytes); sg_element++)
   4.789 -    {
   4.790 -      pfn = (PFN_NUMBER)(MmGetPhysicalAddress((PUCHAR)sg_extra->aligned_buffer + (sg_element << PAGE_SHIFT)).QuadPart >> PAGE_SHIFT);
   4.791 -      ASSERT(pfn);
   4.792 -      gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, INVALID_GRANT_REF);
   4.793 -      ASSERT(gref != INVALID_GRANT_REF);
   4.794 -      sglist->Elements[sg_element].Address.QuadPart = (ULONGLONG)gref << PAGE_SHIFT;
   4.795 -      sglist->Elements[sg_element].Length = min(PAGE_SIZE, remaining);
   4.796 -      remaining -= sglist->Elements[sg_element].Length;
   4.797 -    }
   4.798 -    break;
   4.799 -  case MAP_TYPE_VIRTUAL:
   4.800 -    ptr = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
   4.801 -    ASSERT(ptr); /* lazy */
   4.802 -    sglist->Elements[0].Address.QuadPart = (ULONGLONG)ptr + ((UINT_PTR)CurrentVa - (UINT_PTR)MmGetMdlVirtualAddress(Mdl));
   4.803 -    sglist->Elements[0].Length = Length;
   4.804 -    //KdPrint((__DRIVER_NAME "     MAP_TYPE_VIRTUAL - %08x\n", sglist->Elements[0].Address.LowPart));
   4.805 -    break;
   4.806 -  default:
   4.807 -    KdPrint((__DRIVER_NAME "     map_type = %d\n", map_type));
   4.808 -    break;
   4.809 -  }
   4.810 -  //FUNCTION_EXIT();
   4.811 -  return STATUS_SUCCESS;
   4.812 -}
   4.813 -
   4.814 -static NTSTATUS
   4.815 -XenPci_DOP_BuildScatterGatherList(
   4.816 -  IN PDMA_ADAPTER DmaAdapter,
   4.817 -  IN PDEVICE_OBJECT DeviceObject,
   4.818 -  IN PMDL Mdl,
   4.819 -  IN PVOID CurrentVa,
   4.820 -  IN ULONG Length,
   4.821 -  IN PDRIVER_LIST_CONTROL ExecutionRoutine,
   4.822 -  IN PVOID Context,
   4.823 -  IN BOOLEAN WriteToDevice,
   4.824 -  IN PVOID ScatterGatherBuffer,
   4.825 -  IN ULONG ScatterGatherBufferLength)
   4.826 -{
   4.827 -  NTSTATUS status;
   4.828 -  
   4.829 -  status = XenPci_DOP_BuildScatterGatherListButDontExecute(DmaAdapter, DeviceObject, Mdl, CurrentVa, Length, WriteToDevice, ScatterGatherBuffer, ScatterGatherBufferLength, FALSE);
   4.830 -  
   4.831 -  if (NT_SUCCESS(status))
   4.832 -    ExecutionRoutine(DeviceObject, DeviceObject->CurrentIrp, ScatterGatherBuffer, Context);
   4.833 -
   4.834 -  //FUNCTION_EXIT();
   4.835 -  
   4.836 -  return status;
   4.837 -}
   4.838 -
   4.839 -static NTSTATUS
   4.840 -XenPci_DOP_GetScatterGatherList(
   4.841 -  PDMA_ADAPTER DmaAdapter,
   4.842 -  PDEVICE_OBJECT DeviceObject,
   4.843 -  PMDL Mdl,
   4.844 -  PVOID CurrentVa,
   4.845 -  ULONG Length,
   4.846 -  PDRIVER_LIST_CONTROL ExecutionRoutine,
   4.847 -  PVOID Context,
   4.848 -  BOOLEAN WriteToDevice)
   4.849 -{
   4.850 -  NTSTATUS status;
   4.851 -  ULONG list_size;
   4.852 -  ULONG map_registers;
   4.853 -  PSCATTER_GATHER_LIST sg_list;
   4.854 -  
   4.855 -  //FUNCTION_ENTER();
   4.856 -
   4.857 -  status = XenPci_DOP_CalculateScatterGatherList(DmaAdapter, Mdl, CurrentVa, Length, &list_size, &map_registers);
   4.858 -  if (!NT_SUCCESS(status))
   4.859 -  {
   4.860 -    //FUNCTION_EXIT();
   4.861 -    return status;
   4.862 -  }
   4.863 -
   4.864 -  sg_list = ExAllocatePoolWithTag(NonPagedPool, list_size, XENPCI_POOL_TAG);
   4.865 -  if (!sg_list)
   4.866 -  {
   4.867 -    KdPrint((__DRIVER_NAME "     Cannot allocate memory for sg_list\n"));
   4.868 -    //FUNCTION_EXIT();
   4.869 -    return STATUS_INSUFFICIENT_RESOURCES;
   4.870 -  }
   4.871 -    
   4.872 -  status = XenPci_DOP_BuildScatterGatherListButDontExecute(DmaAdapter, DeviceObject, Mdl, CurrentVa, Length, WriteToDevice, sg_list, list_size, TRUE);
   4.873 -  
   4.874 -  if (NT_SUCCESS(status))
   4.875 -    ExecutionRoutine(DeviceObject, DeviceObject->CurrentIrp, sg_list, Context);
   4.876 -  
   4.877 -  //FUNCTION_EXIT();
   4.878 -  
   4.879 -  return status;
   4.880 -}
   4.881 -
   4.882 -static NTSTATUS
   4.883 -XenPci_DOP_BuildMdlFromScatterGatherList(
   4.884 -  PDMA_ADAPTER DmaAdapter,
   4.885 -  PSCATTER_GATHER_LIST ScatterGather,
   4.886 -  PMDL OriginalMdl,
   4.887 -  PMDL *TargetMdl)
   4.888 -{
   4.889 -  NTSTATUS status = STATUS_SUCCESS;
   4.890 -  UNREFERENCED_PARAMETER(DmaAdapter);
   4.891 -  UNREFERENCED_PARAMETER(ScatterGather);
   4.892 -  UNREFERENCED_PARAMETER(OriginalMdl);
   4.893 -  UNREFERENCED_PARAMETER(TargetMdl);
   4.894 -
   4.895 -  FUNCTION_ENTER();
   4.896 -  
   4.897 -  if (OriginalMdl)
   4.898 -  {
   4.899 -    *TargetMdl = OriginalMdl;
   4.900 -  }
   4.901 -  else
   4.902 -  {
   4.903 -    *TargetMdl = NULL;
   4.904 -    status = STATUS_INVALID_PARAMETER;
   4.905 -  }
   4.906 -  
   4.907 -  FUNCTION_EXIT();
   4.908 -  
   4.909 -  return status;
   4.910 -}
   4.911 -
   4.912 -static PDMA_ADAPTER
   4.913 -XenPci_BIS_GetDmaAdapter(PVOID context, PDEVICE_DESCRIPTION device_description, PULONG number_of_map_registers)
   4.914 -{
   4.915 -  xen_dma_adapter_t *xen_dma_adapter;
   4.916 -  PDEVICE_OBJECT curr, prev;
   4.917 -  PDRIVER_OBJECT fdo_driver_object;
   4.918 -  PVOID fdo_driver_extension;
   4.919 -  
   4.920 -  UNREFERENCED_PARAMETER(device_description);
   4.921 -  
   4.922 -  FUNCTION_ENTER();
   4.923 -
   4.924 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   4.925 -  KdPrint((__DRIVER_NAME "     Device Description = %p:\n", device_description));
   4.926 -  KdPrint((__DRIVER_NAME "      Version  = %d\n", device_description->Version));
   4.927 -  KdPrint((__DRIVER_NAME "      Master = %d\n", device_description->Master));
   4.928 -  KdPrint((__DRIVER_NAME "      ScatterGather = %d\n", device_description->ScatterGather));
   4.929 -  KdPrint((__DRIVER_NAME "      DemandMode = %d\n", device_description->DemandMode));
   4.930 -  KdPrint((__DRIVER_NAME "      AutoInitialize = %d\n", device_description->AutoInitialize));
   4.931 -  KdPrint((__DRIVER_NAME "      Dma32BitAddresses = %d\n", device_description->Dma32BitAddresses));
   4.932 -  KdPrint((__DRIVER_NAME "      IgnoreCount = %d\n", device_description->IgnoreCount));
   4.933 -  KdPrint((__DRIVER_NAME "      Dma64BitAddresses = %d\n", device_description->Dma64BitAddresses));
   4.934 -  KdPrint((__DRIVER_NAME "      BusNumber = %d\n", device_description->BusNumber));
   4.935 -  KdPrint((__DRIVER_NAME "      DmaChannel = %d\n", device_description->DmaChannel));
   4.936 -  KdPrint((__DRIVER_NAME "      InterfaceType = %d\n", device_description->InterfaceType));
   4.937 -  KdPrint((__DRIVER_NAME "      DmaWidth = %d\n", device_description->DmaWidth));
   4.938 -  KdPrint((__DRIVER_NAME "      DmaSpeed = %d\n", device_description->DmaSpeed));
   4.939 -  KdPrint((__DRIVER_NAME "      MaximumLength = %d\n", device_description->MaximumLength));
   4.940 -  KdPrint((__DRIVER_NAME "      DmaPort = %d\n", device_description->DmaPort));
   4.941 -  
   4.942 -  if (!device_description->Master)
   4.943 -    return NULL;
   4.944 -/*
   4.945 -we have to allocate PAGE_SIZE bytes here because Windows thinks this is
   4.946 -actually an ADAPTER_OBJECT, and then the verifier crashes because
   4.947 -Windows accessed beyond the end of the structure :(
   4.948 -*/
   4.949 -  xen_dma_adapter = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
   4.950 -  ASSERT(xen_dma_adapter);
   4.951 -  RtlZeroMemory(xen_dma_adapter, PAGE_SIZE);
   4.952 -  
   4.953 -  switch(device_description->Version)
   4.954 -  {
   4.955 -  case DEVICE_DESCRIPTION_VERSION1:
   4.956 -    xen_dma_adapter->adapter_object.DmaHeader.Version = 1;
   4.957 -    break;
   4.958 -  case DEVICE_DESCRIPTION_VERSION: /* ignore what the docs say here - DEVICE_DESCRIPTION_VERSION appears to mean the latest version */
   4.959 -  case DEVICE_DESCRIPTION_VERSION2:
   4.960 -    xen_dma_adapter->adapter_object.DmaHeader.Version = 2;
   4.961 -    break;
   4.962 -  default:
   4.963 -    KdPrint((__DRIVER_NAME "     Unsupported device description version %d\n", device_description->Version));
   4.964 -    ExFreePoolWithTag(xen_dma_adapter, XENPCI_POOL_TAG);
   4.965 -    return NULL;
   4.966 -  }
   4.967 -    
   4.968 -  xen_dma_adapter->xppdd = context;
   4.969 -  xen_dma_adapter->dma_extension = NULL;
   4.970 -
   4.971 -  KdPrint((__DRIVER_NAME "     About to call IoGetAttachedDeviceReference\n"));
   4.972 -  curr = IoGetAttachedDeviceReference(WdfDeviceWdmGetDeviceObject(xen_dma_adapter->xppdd->wdf_device));
   4.973 -  KdPrint((__DRIVER_NAME "     Before start of loop - curr = %p\n", curr));
   4.974 -  while (curr != NULL)
   4.975 -  {
   4.976 -    fdo_driver_object = curr->DriverObject;
   4.977 -    if (fdo_driver_object)
   4.978 -    {
   4.979 -      ObReferenceObject(fdo_driver_object);
   4.980 -      fdo_driver_extension = IoGetDriverObjectExtension(fdo_driver_object, UlongToPtr(XEN_DMA_DRIVER_EXTENSION_MAGIC));
   4.981 -      if (fdo_driver_extension)
   4.982 -      {
   4.983 -        xen_dma_adapter->dma_extension_driver = fdo_driver_object; /* so we can dereference it on putdmaadapter */
   4.984 -        xen_dma_adapter->dma_extension = (dma_driver_extension_t *)fdo_driver_extension;
   4.985 -        ObDereferenceObject(curr);
   4.986 -        break;
   4.987 -      }
   4.988 -      else
   4.989 -      {
   4.990 -        ObDereferenceObject(fdo_driver_object);
   4.991 -      }
   4.992 -    }
   4.993 -    prev = curr;
   4.994 -    curr = IoGetLowerDeviceObject(curr);
   4.995 -    ObDereferenceObject(prev);
   4.996 -  }
   4.997 -  KdPrint((__DRIVER_NAME "     End of loop\n"));
   4.998 -
   4.999 -  xen_dma_adapter->adapter_object.DmaHeader.Size = sizeof(X_ADAPTER_OBJECT); //xen_dma_adapter_t);
  4.1000 -  xen_dma_adapter->adapter_object.MasterAdapter = NULL;
  4.1001 -  if (xen_dma_adapter->dma_extension && xen_dma_adapter->dma_extension->max_sg_elements)
  4.1002 -  {
  4.1003 -    xen_dma_adapter->adapter_object.MapRegistersPerChannel = xen_dma_adapter->dma_extension->max_sg_elements;
  4.1004 -  }
  4.1005 -  else
  4.1006 -  {
  4.1007 -    xen_dma_adapter->adapter_object.MapRegistersPerChannel = 256;
  4.1008 -  }
  4.1009 -  xen_dma_adapter->adapter_object.AdapterBaseVa = NULL;
  4.1010 -  xen_dma_adapter->adapter_object.MapRegisterBase = NULL;
  4.1011 -  xen_dma_adapter->adapter_object.NumberOfMapRegisters = 0;
  4.1012 -  xen_dma_adapter->adapter_object.CommittedMapRegisters = 0;
  4.1013 -  xen_dma_adapter->adapter_object.CurrentWcb = NULL;
  4.1014 -  KeInitializeDeviceQueue(&xen_dma_adapter->adapter_object.ChannelWaitQueue);
  4.1015 -  xen_dma_adapter->adapter_object.RegisterWaitQueue = NULL;
  4.1016 -  InitializeListHead(&xen_dma_adapter->adapter_object.AdapterQueue);
  4.1017 -  KeInitializeSpinLock(&xen_dma_adapter->adapter_object.SpinLock);
  4.1018 -  xen_dma_adapter->adapter_object.MapRegisters = NULL;
  4.1019 -  xen_dma_adapter->adapter_object.PagePort = NULL;
  4.1020 -  xen_dma_adapter->adapter_object.ChannelNumber = 0xff;
  4.1021 -  xen_dma_adapter->adapter_object.AdapterNumber = 0;
  4.1022 -  xen_dma_adapter->adapter_object.DmaPortAddress = 0;
  4.1023 -  xen_dma_adapter->adapter_object.AdapterMode = 0;
  4.1024 -  xen_dma_adapter->adapter_object.NeedsMapRegisters = FALSE; /* when true this causes a crash in the crash dump path */
  4.1025 -  xen_dma_adapter->adapter_object.MasterDevice = 1;
  4.1026 -  xen_dma_adapter->adapter_object.Width16Bits = 0;
  4.1027 -  xen_dma_adapter->adapter_object.ScatterGather = device_description->ScatterGather;
  4.1028 -  xen_dma_adapter->adapter_object.IgnoreCount = device_description->IgnoreCount;
  4.1029 -  xen_dma_adapter->adapter_object.Dma32BitAddresses = device_description->Dma32BitAddresses;
  4.1030 -  xen_dma_adapter->adapter_object.Dma64BitAddresses = device_description->Dma64BitAddresses;
  4.1031 -  InitializeListHead(&xen_dma_adapter->adapter_object.AdapterList);  
  4.1032 -  
  4.1033 -  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DMA_OPERATIONS), XENPCI_POOL_TAG);
  4.1034 -  ASSERT(xen_dma_adapter->adapter_object.DmaHeader.DmaOperations);
  4.1035 -  if (xen_dma_adapter->adapter_object.DmaHeader.Version == 1)
  4.1036 -  {
  4.1037 -    xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->Size = FIELD_OFFSET(DMA_OPERATIONS, CalculateScatterGatherList);
  4.1038 -  }
  4.1039 -  else
  4.1040 -  {
  4.1041 -    xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->Size = sizeof(DMA_OPERATIONS);
  4.1042 -  }
  4.1043 -  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->PutDmaAdapter = XenPci_DOP_PutDmaAdapter;
  4.1044 -  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->AllocateCommonBuffer = XenPci_DOP_AllocateCommonBuffer;
  4.1045 -  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->FreeCommonBuffer = XenPci_DOP_FreeCommonBuffer;
  4.1046 -  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->AllocateAdapterChannel = XenPci_DOP_AllocateAdapterChannel;
  4.1047 -  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->FlushAdapterBuffers = XenPci_DOP_FlushAdapterBuffers;
  4.1048 -  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->FreeAdapterChannel = XenPci_DOP_FreeAdapterChannel;
  4.1049 -  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->FreeMapRegisters = XenPci_DOP_FreeMapRegisters;
  4.1050 -  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->MapTransfer = XenPci_DOP_MapTransfer;
  4.1051 -  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->GetDmaAlignment = XenPci_DOP_GetDmaAlignment;
  4.1052 -  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->ReadDmaCounter = XenPci_DOP_ReadDmaCounter;
  4.1053 -  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->GetScatterGatherList = XenPci_DOP_GetScatterGatherList;
  4.1054 -  xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->PutScatterGatherList = XenPci_DOP_PutScatterGatherList;
  4.1055 -  if (xen_dma_adapter->adapter_object.DmaHeader.Version == 2)
  4.1056 -  {
  4.1057 -    xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->CalculateScatterGatherList = XenPci_DOP_CalculateScatterGatherList;
  4.1058 -    xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->BuildScatterGatherList = XenPci_DOP_BuildScatterGatherList;
  4.1059 -    xen_dma_adapter->adapter_object.DmaHeader.DmaOperations->BuildMdlFromScatterGatherList = XenPci_DOP_BuildMdlFromScatterGatherList;
  4.1060 -  }
  4.1061 -
  4.1062 -  *number_of_map_registers = xen_dma_adapter->adapter_object.MapRegistersPerChannel; //1024; /* why not... */
  4.1063 -
  4.1064 -  FUNCTION_EXIT();
  4.1065 -
  4.1066 -  return &xen_dma_adapter->adapter_object.DmaHeader;
  4.1067 -}
  4.1068 -
  4.1069 -static ULONG
  4.1070 -XenPci_BIS_SetBusData(PVOID context, ULONG data_type, PVOID buffer, ULONG offset, ULONG length)
  4.1071 -{
  4.1072 -  UNREFERENCED_PARAMETER(context);
  4.1073 -  UNREFERENCED_PARAMETER(data_type);
  4.1074 -  UNREFERENCED_PARAMETER(buffer);
  4.1075 -  UNREFERENCED_PARAMETER(offset);
  4.1076 -  UNREFERENCED_PARAMETER(length);
  4.1077 -  
  4.1078 -  FUNCTION_ENTER();
  4.1079 -  FUNCTION_EXIT();
  4.1080 -  return 0;
  4.1081 -}
  4.1082 -
  4.1083 -static ULONG
  4.1084 -XenPci_BIS_GetBusData(PVOID context, ULONG data_type, PVOID buffer, ULONG offset, ULONG length)
  4.1085 -{
  4.1086 -  UNREFERENCED_PARAMETER(context);
  4.1087 -  UNREFERENCED_PARAMETER(data_type);
  4.1088 -  UNREFERENCED_PARAMETER(buffer);
  4.1089 -  UNREFERENCED_PARAMETER(offset);
  4.1090 -  UNREFERENCED_PARAMETER(length);
  4.1091 -  
  4.1092 -  FUNCTION_ENTER();
  4.1093 -  FUNCTION_EXIT();
  4.1094 -  return 0;
  4.1095 -}
  4.1096 -
  4.1097  /*
  4.1098  Called at PASSIVE_LEVEL(?)
  4.1099  Called during restore