win-pvdrivers

changeset 718:fadce0b7a84c

Fixed a DMA problem in AdapterChannel routines which caused crashes under XP.
author James Harper <james.harper@bendigoit.com.au>
date Wed Dec 30 20:40:14 2009 +1100 (2009-12-30)
parents b30bcfed15d7
children eeb1a1d80778
files xenpci/xenpci.h xenpci/xenpci_dma.c
line diff
     1.1 --- a/xenpci/xenpci.h	Tue Dec 22 23:20:47 2009 +1100
     1.2 +++ b/xenpci/xenpci.h	Wed Dec 30 20:40:14 2009 +1100
     1.3 @@ -246,80 +246,6 @@ typedef struct {
     1.4    ULONG index;
     1.5  } XENPCI_PDO_IDENTIFICATION_DESCRIPTION, *PXENPCI_PDO_IDENTIFICATION_DESCRIPTION;
     1.6  
     1.7 -#if 0
     1.8 -kd> dt _ADAPTER_OBJECT 81e96b08 -v
     1.9 -hal!_ADAPTER_OBJECT
    1.10 -struct _ADAPTER_OBJECT, 26 elements, 0x64 bytes
    1.11 -   +0x000 DmaHeader        : struct _DMA_ADAPTER, 3 elements, 0x8 bytes
    1.12 -   +0x008 MasterAdapter    : (null) 
    1.13 -   +0x00c MapRegistersPerChannel : 0x80001
    1.14 -   +0x010 AdapterBaseVa    : (null) 
    1.15 -   +0x014 MapRegisterBase  : (null) 
    1.16 -   +0x018 NumberOfMapRegisters : 0
    1.17 -   +0x01c CommittedMapRegisters : 0
    1.18 -   +0x020 CurrentWcb       : (null) 
    1.19 -   +0x024 ChannelWaitQueue : struct _KDEVICE_QUEUE, 5 elements, 0x14 bytes
    1.20 -   +0x038 RegisterWaitQueue : (null) 
    1.21 -   +0x03c AdapterQueue     : struct _LIST_ENTRY, 2 elements, 0x8 bytes
    1.22 - [ 0x0 - 0x0 ]
    1.23 -   +0x044 SpinLock         : 0
    1.24 -   +0x048 MapRegisters     : (null) 
    1.25 -   +0x04c PagePort         : (null) 
    1.26 -   +0x050 ChannelNumber    : 0xff ''
    1.27 -   +0x051 AdapterNumber    : 0 ''
    1.28 -   +0x052 DmaPortAddress   : 0
    1.29 -   +0x054 AdapterMode      : 0 ''
    1.30 -   +0x055 NeedsMapRegisters : 0 ''
    1.31 -   +0x056 MasterDevice     : 0x1 ''
    1.32 -   +0x057 Width16Bits      : 0 ''
    1.33 -   +0x058 ScatterGather    : 0x1 ''
    1.34 -   +0x059 IgnoreCount      : 0 ''
    1.35 -   +0x05a Dma32BitAddresses : 0x1 ''
    1.36 -   +0x05b Dma64BitAddresses : 0 ''
    1.37 -   +0x05c AdapterList      : struct _LIST_ENTRY, 2 elements, 0x8 bytes
    1.38 - [ 0x806e1250 - 0x81f1b474 ]
    1.39 -#endif
    1.40 -
    1.41 -/* need to confirm that this is the same for AMD64 too */
    1.42 -typedef struct {
    1.43 -  DMA_ADAPTER DmaHeader;
    1.44 -  PVOID MasterAdapter;
    1.45 -  ULONG MapRegistersPerChannel;
    1.46 -  PVOID AdapterBaseVa;
    1.47 -  PVOID MapRegisterBase;
    1.48 -  ULONG NumberOfMapRegisters;
    1.49 -  ULONG CommittedMapRegisters;
    1.50 -  PVOID CurrentWcb;
    1.51 -  KDEVICE_QUEUE ChannelWaitQueue;
    1.52 -  PKDEVICE_QUEUE RegisterWaitQueue;
    1.53 -  LIST_ENTRY AdapterQueue;
    1.54 -  KSPIN_LOCK SpinLock;
    1.55 -  PVOID MapRegisters;
    1.56 -  PVOID PagePort;
    1.57 -  UCHAR ChannelNumber;
    1.58 -  UCHAR AdapterNumber;
    1.59 -  USHORT DmaPortAddress;
    1.60 -  UCHAR AdapterMode;
    1.61 -  BOOLEAN NeedsMapRegisters;
    1.62 -  BOOLEAN MasterDevice;
    1.63 -  UCHAR Width16Bits;
    1.64 -  BOOLEAN ScatterGather;
    1.65 -  BOOLEAN IgnoreCount;
    1.66 -  BOOLEAN Dma32BitAddresses;
    1.67 -  BOOLEAN Dma64BitAddresses;
    1.68 -#if (NTDDI_VERSION >= NTDDI_WS03)
    1.69 -  BOOLEAN LegacyAdapter;
    1.70 -#endif
    1.71 -  LIST_ENTRY AdapterList;
    1.72 -} X_ADAPTER_OBJECT;
    1.73 -  
    1.74 -typedef struct {
    1.75 -  X_ADAPTER_OBJECT adapter_object;
    1.76 -  PXENPCI_PDO_DEVICE_DATA xppdd;
    1.77 -  dma_driver_extension_t *dma_extension;
    1.78 -  PDRIVER_OBJECT dma_extension_driver; /* to deference it */
    1.79 -} xen_dma_adapter_t;
    1.80 -
    1.81  #define XEN_INTERFACE_VERSION 1
    1.82  
    1.83  //#define DEVICE_INTERFACE_TYPE_LEGACY 0
     2.1 --- a/xenpci/xenpci_dma.c	Tue Dec 22 23:20:47 2009 +1100
     2.2 +++ b/xenpci/xenpci_dma.c	Wed Dec 30 20:40:14 2009 +1100
     2.3 @@ -24,10 +24,79 @@ Foundation, Inc., 51 Franklin Street, Fi
     2.4  #pragma warning(disable : 4200) // zero-sized array
     2.5  #pragma warning(disable: 4127) // conditional expression is constant
     2.6  
     2.7 +#define MAP_TYPE_INVALID  0
     2.8  #define MAP_TYPE_VIRTUAL  1
     2.9  #define MAP_TYPE_MDL      2
    2.10  #define MAP_TYPE_REMAPPED 3
    2.11  
    2.12 +
    2.13 +#if 0
    2.14 +kd> dt _ADAPTER_OBJECT 81e96b08 -v
    2.15 +hal!_ADAPTER_OBJECT
    2.16 +struct _ADAPTER_OBJECT, 26 elements, 0x64 bytes
    2.17 +   +0x000 DmaHeader        : struct _DMA_ADAPTER, 3 elements, 0x8 bytes
    2.18 +   +0x008 MasterAdapter    : (null) 
    2.19 +   +0x00c MapRegistersPerChannel : 0x80001
    2.20 +   +0x010 AdapterBaseVa    : (null) 
    2.21 +   +0x014 MapRegisterBase  : (null) 
    2.22 +   +0x018 NumberOfMapRegisters : 0
    2.23 +   +0x01c CommittedMapRegisters : 0
    2.24 +   +0x020 CurrentWcb       : (null) 
    2.25 +   +0x024 ChannelWaitQueue : struct _KDEVICE_QUEUE, 5 elements, 0x14 bytes
    2.26 +   +0x038 RegisterWaitQueue : (null) 
    2.27 +   +0x03c AdapterQueue     : struct _LIST_ENTRY, 2 elements, 0x8 bytes
    2.28 + [ 0x0 - 0x0 ]
    2.29 +   +0x044 SpinLock         : 0
    2.30 +   +0x048 MapRegisters     : (null) 
    2.31 +   +0x04c PagePort         : (null) 
    2.32 +   +0x050 ChannelNumber    : 0xff ''
    2.33 +   +0x051 AdapterNumber    : 0 ''
    2.34 +   +0x052 DmaPortAddress   : 0
    2.35 +   +0x054 AdapterMode      : 0 ''
    2.36 +   +0x055 NeedsMapRegisters : 0 ''
    2.37 +   +0x056 MasterDevice     : 0x1 ''
    2.38 +   +0x057 Width16Bits      : 0 ''
    2.39 +   +0x058 ScatterGather    : 0x1 ''
    2.40 +   +0x059 IgnoreCount      : 0 ''
    2.41 +   +0x05a Dma32BitAddresses : 0x1 ''
    2.42 +   +0x05b Dma64BitAddresses : 0 ''
    2.43 +   +0x05c AdapterList      : struct _LIST_ENTRY, 2 elements, 0x8 bytes
    2.44 + [ 0x806e1250 - 0x81f1b474 ]
    2.45 +#endif
    2.46 +
    2.47 +/* need to confirm that this is the same for AMD64 too */
    2.48 +typedef struct {
    2.49 +  DMA_ADAPTER DmaHeader;
    2.50 +  PVOID MasterAdapter;
    2.51 +  ULONG MapRegistersPerChannel;
    2.52 +  PVOID AdapterBaseVa;
    2.53 +  PVOID MapRegisterBase;
    2.54 +  ULONG NumberOfMapRegisters;
    2.55 +  ULONG CommittedMapRegisters;
    2.56 +  PVOID CurrentWcb;
    2.57 +  KDEVICE_QUEUE ChannelWaitQueue;
    2.58 +  PKDEVICE_QUEUE RegisterWaitQueue;
    2.59 +  LIST_ENTRY AdapterQueue;
    2.60 +  KSPIN_LOCK SpinLock;
    2.61 +  PVOID MapRegisters;
    2.62 +  PVOID PagePort;
    2.63 +  UCHAR ChannelNumber;
    2.64 +  UCHAR AdapterNumber;
    2.65 +  USHORT DmaPortAddress;
    2.66 +  UCHAR AdapterMode;
    2.67 +  BOOLEAN NeedsMapRegisters;
    2.68 +  BOOLEAN MasterDevice;
    2.69 +  UCHAR Width16Bits;
    2.70 +  BOOLEAN ScatterGather;
    2.71 +  BOOLEAN IgnoreCount;
    2.72 +  BOOLEAN Dma32BitAddresses;
    2.73 +  BOOLEAN Dma64BitAddresses;
    2.74 +#if (NTDDI_VERSION >= NTDDI_WS03)
    2.75 +  BOOLEAN LegacyAdapter;
    2.76 +#endif
    2.77 +  LIST_ENTRY AdapterList;
    2.78 +} X_ADAPTER_OBJECT;
    2.79 +
    2.80  typedef struct {
    2.81    ULONG map_type;
    2.82    PVOID aligned_buffer;
    2.83 @@ -42,15 +111,29 @@ typedef struct {
    2.84    PVOID aligned_buffer;
    2.85    PVOID unaligned_buffer;
    2.86    ULONG copy_length;
    2.87 +  grant_ref_t gref;
    2.88    PHYSICAL_ADDRESS logical;
    2.89  } map_register_t;
    2.90  
    2.91  typedef struct {
    2.92    PDEVICE_OBJECT device_object;
    2.93    ULONG total_map_registers;
    2.94 +  PDRIVER_CONTROL execution_routine;
    2.95 +  PIRP current_irp;
    2.96 +  PVOID context;
    2.97    ULONG count;
    2.98    map_register_t regs[1];
    2.99  } map_register_base_t;  
   2.100 +  
   2.101 +typedef struct {
   2.102 +  X_ADAPTER_OBJECT adapter_object;
   2.103 +  PXENPCI_PDO_DEVICE_DATA xppdd;
   2.104 +  dma_driver_extension_t *dma_extension;
   2.105 +  PDRIVER_OBJECT dma_extension_driver; /* to deference it */
   2.106 +  map_register_base_t *map_register_base;
   2.107 +  map_register_base_t *queued_map_register_base;  
   2.108 +  KSPIN_LOCK lock;
   2.109 +} xen_dma_adapter_t;
   2.110  
   2.111  BOOLEAN
   2.112  XenPci_BIS_TranslateBusAddress(PVOID context, PHYSICAL_ADDRESS bus_address, ULONG length, PULONG address_space, PPHYSICAL_ADDRESS translated_address)
   2.113 @@ -77,6 +160,8 @@ XenPci_DOP_PutDmaAdapter(PDMA_ADAPTER dm
   2.114    
   2.115    FUNCTION_ENTER();
   2.116  
   2.117 +  ASSERT(!xen_dma_adapter->map_register_base);
   2.118 +  ASSERT(!xen_dma_adapter->queued_map_register_base);
   2.119    if (xen_dma_adapter->dma_extension)
   2.120      ObDereferenceObject(xen_dma_adapter->dma_extension_driver);
   2.121    ExFreePoolWithTag(xen_dma_adapter->adapter_object.DmaHeader.DmaOperations, XENPCI_POOL_TAG);
   2.122 @@ -152,58 +237,16 @@ XenPci_DOP_FreeCommonBuffer(
   2.123  //  FUNCTION_EXIT();
   2.124  }
   2.125  
   2.126 -static NTSTATUS
   2.127 -XenPci_DOP_AllocateAdapterChannel(
   2.128 -    IN PDMA_ADAPTER dma_adapter,
   2.129 -    IN PDEVICE_OBJECT device_object,
   2.130 -    IN ULONG NumberOfMapRegisters,
   2.131 -    IN PDRIVER_CONTROL ExecutionRoutine,
   2.132 -    IN PVOID Context
   2.133 -    )
   2.134 +static VOID
   2.135 +XenPci_ExecuteMapRegisterDma(
   2.136 +  PDMA_ADAPTER dma_adapter,
   2.137 +  map_register_base_t *map_register_base)
   2.138  {
   2.139 -  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
   2.140 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   2.141 -  ULONG i;
   2.142    IO_ALLOCATION_ACTION action;
   2.143 -  map_register_base_t *map_register_base;
   2.144 -  grant_ref_t gref;
   2.145 -  
   2.146 +
   2.147    UNREFERENCED_PARAMETER(dma_adapter);
   2.148    
   2.149 -  //FUNCTION_ENTER();
   2.150 -
   2.151 -  map_register_base = ExAllocatePoolWithTag(NonPagedPool, 
   2.152 -    FIELD_OFFSET(map_register_base_t, regs) + NumberOfMapRegisters * sizeof(map_register_t), XENPCI_POOL_TAG);
   2.153 -  if (!map_register_base)
   2.154 -  {
   2.155 -    KdPrint((__DRIVER_NAME "     Cannot allocate memory for map_register_base\n"));
   2.156 -    //FUNCTION_EXIT();
   2.157 -    return STATUS_INSUFFICIENT_RESOURCES;
   2.158 -  }
   2.159 -  /* 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 */
   2.160 -  map_register_base->device_object = device_object;
   2.161 -  map_register_base->total_map_registers = NumberOfMapRegisters;
   2.162 -  map_register_base->count = 0;
   2.163 -  
   2.164 -  for (i = 0; i < NumberOfMapRegisters; i++)
   2.165 -  {
   2.166 -    gref = GntTbl_GetRef(xpdd);
   2.167 -    if (gref == INVALID_GRANT_REF)
   2.168 -    {
   2.169 -      /* go back through the list and free the ones we allocated */
   2.170 -      NumberOfMapRegisters = i;
   2.171 -      for (i = 0; i < NumberOfMapRegisters; i++)
   2.172 -      {
   2.173 -        gref = (grant_ref_t)(map_register_base->regs[i].logical.QuadPart >> PAGE_SHIFT);
   2.174 -        GntTbl_PutRef(xpdd, gref);
   2.175 -      }
   2.176 -      ExFreePoolWithTag(map_register_base, XENPCI_POOL_TAG);
   2.177 -      return STATUS_INSUFFICIENT_RESOURCES;
   2.178 -    }
   2.179 -    map_register_base->regs[i].logical.QuadPart = ((LONGLONG)gref << PAGE_SHIFT);
   2.180 -  }
   2.181 -  
   2.182 -  action = ExecutionRoutine(device_object, device_object->CurrentIrp, map_register_base, Context);
   2.183 +  action = map_register_base->execution_routine(map_register_base->device_object, map_register_base->current_irp, map_register_base, map_register_base->context);
   2.184    
   2.185    switch (action)
   2.186    {
   2.187 @@ -223,6 +266,81 @@ XenPci_DOP_AllocateAdapterChannel(
   2.188      ASSERT(FALSE);
   2.189      break;
   2.190    }
   2.191 +  return;
   2.192 +}
   2.193 +
   2.194 +static NTSTATUS
   2.195 +XenPci_DOP_AllocateAdapterChannel(
   2.196 +    IN PDMA_ADAPTER dma_adapter,
   2.197 +    IN PDEVICE_OBJECT device_object,
   2.198 +    IN ULONG NumberOfMapRegisters,
   2.199 +    IN PDRIVER_CONTROL ExecutionRoutine,
   2.200 +    IN PVOID Context
   2.201 +    )
   2.202 +{
   2.203 +  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
   2.204 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   2.205 +  ULONG i;
   2.206 +  map_register_base_t *map_register_base;
   2.207 +  
   2.208 +  UNREFERENCED_PARAMETER(dma_adapter);
   2.209 +  
   2.210 +  //FUNCTION_ENTER();
   2.211 +  
   2.212 +  ASSERT(!xen_dma_adapter->queued_map_register_base);
   2.213 +
   2.214 +  map_register_base = ExAllocatePoolWithTag(NonPagedPool, 
   2.215 +    FIELD_OFFSET(map_register_base_t, regs) + NumberOfMapRegisters * sizeof(map_register_t), XENPCI_POOL_TAG);
   2.216 +  if (!map_register_base)
   2.217 +  {
   2.218 +    KdPrint((__DRIVER_NAME "     Cannot allocate memory for map_register_base\n"));
   2.219 +    //FUNCTION_EXIT();
   2.220 +    return STATUS_INSUFFICIENT_RESOURCES;
   2.221 +  }
   2.222 +  //KdPrint((__DRIVER_NAME "     Alloc %p\n", map_register_base));
   2.223 +  /* 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 */
   2.224 +  map_register_base->device_object = device_object;
   2.225 +  map_register_base->current_irp = device_object->CurrentIrp;
   2.226 +  map_register_base->total_map_registers = NumberOfMapRegisters;
   2.227 +  map_register_base->execution_routine = ExecutionRoutine;
   2.228 +  map_register_base->context = Context;  
   2.229 +  map_register_base->count = 0;
   2.230 +  
   2.231 +  for (i = 0; i < NumberOfMapRegisters; i++)
   2.232 +  {
   2.233 +    map_register_base->regs[i].gref = GntTbl_GetRef(xpdd);
   2.234 +    if (map_register_base->regs[i].gref == INVALID_GRANT_REF)
   2.235 +    {
   2.236 +      KdPrint((__DRIVER_NAME "     Not enough gref's for AdapterChannel list\n"));
   2.237 +      /* go back through the list and free the ones we allocated */
   2.238 +      NumberOfMapRegisters = i;
   2.239 +      for (i = 0; i < NumberOfMapRegisters; i++)
   2.240 +      {
   2.241 +        GntTbl_PutRef(xpdd, map_register_base->regs[i].gref);
   2.242 +      }
   2.243 +      //KdPrint((__DRIVER_NAME "     B Free %p\n", map_register_base));
   2.244 +      ExFreePoolWithTag(map_register_base, XENPCI_POOL_TAG);
   2.245 +      return STATUS_INSUFFICIENT_RESOURCES;
   2.246 +    }
   2.247 +    map_register_base->regs[i].map_type = MAP_TYPE_INVALID;
   2.248 +    map_register_base->regs[i].aligned_buffer = NULL;
   2.249 +    map_register_base->regs[i].unaligned_buffer = NULL;
   2.250 +    map_register_base->regs[i].copy_length = 0;
   2.251 +  }
   2.252 +  
   2.253 +  KeAcquireSpinLockAtDpcLevel(&xen_dma_adapter->lock);
   2.254 +  if (xen_dma_adapter->map_register_base)
   2.255 +  {
   2.256 +    xen_dma_adapter->queued_map_register_base = map_register_base;
   2.257 +    KeReleaseSpinLockFromDpcLevel(&xen_dma_adapter->lock);
   2.258 +  }
   2.259 +  else
   2.260 +  {
   2.261 +    xen_dma_adapter->map_register_base = map_register_base;
   2.262 +    KeReleaseSpinLockFromDpcLevel(&xen_dma_adapter->lock);
   2.263 +    XenPci_ExecuteMapRegisterDma(dma_adapter, map_register_base);
   2.264 +  }
   2.265 +
   2.266    //FUNCTION_EXIT();
   2.267    return STATUS_SUCCESS;
   2.268  }
   2.269 @@ -236,7 +354,7 @@ XenPci_DOP_FlushAdapterBuffers(
   2.270    ULONG Length,
   2.271    BOOLEAN write_to_device)
   2.272  {
   2.273 -  //xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
   2.274 +  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
   2.275    //PXENPCI_DEVICE_DATA xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   2.276    map_register_base_t *map_register_base = MapRegisterBase;
   2.277    map_register_t *map_register;
   2.278 @@ -249,6 +367,9 @@ XenPci_DOP_FlushAdapterBuffers(
   2.279  
   2.280    //FUNCTION_ENTER();
   2.281    
   2.282 +  ASSERT(xen_dma_adapter->map_register_base);
   2.283 +  ASSERT(xen_dma_adapter->map_register_base == map_register_base);
   2.284 +  
   2.285    for (i = 0; i < map_register_base->count; i++)
   2.286    {
   2.287      map_register = &map_register_base->regs[i];
   2.288 @@ -282,31 +403,32 @@ XenPci_DOP_FreeMapRegisters(
   2.289    map_register_base_t *map_register_base = MapRegisterBase;
   2.290    map_register_t *map_register;
   2.291    ULONG i;
   2.292 -  grant_ref_t gref;
   2.293  
   2.294    UNREFERENCED_PARAMETER(NumberOfMapRegisters);
   2.295    
   2.296    //FUNCTION_ENTER();
   2.297 +
   2.298    if (!map_register_base)
   2.299    {
   2.300      /* i'm not sure if this is ideal here, but NDIS definitely does it */
   2.301      return;
   2.302    }
   2.303 +
   2.304 +  ASSERT(xen_dma_adapter->map_register_base == map_register_base);  
   2.305    ASSERT(map_register_base->total_map_registers == NumberOfMapRegisters);
   2.306  
   2.307 -  for (i = 0; i < map_register_base->count; i++)
   2.308 +  for (i = 0; i < map_register_base->total_map_registers; i++)
   2.309    {
   2.310      map_register = &map_register_base->regs[i];
   2.311 +    GntTbl_EndAccess(xpdd, map_register->gref, FALSE);
   2.312      switch (map_register->map_type)
   2.313      {
   2.314 +    case MAP_TYPE_INVALID:
   2.315 +      break;
   2.316      case MAP_TYPE_REMAPPED:
   2.317 -      gref = (grant_ref_t)(map_register->logical.QuadPart >> PAGE_SHIFT);
   2.318 -      GntTbl_EndAccess(xpdd, gref, FALSE);
   2.319        ExFreePoolWithTag(map_register->aligned_buffer, XENPCI_POOL_TAG);
   2.320        break;
   2.321      case MAP_TYPE_MDL:
   2.322 -      gref = (grant_ref_t)(map_register->logical.QuadPart >> PAGE_SHIFT);
   2.323 -      GntTbl_EndAccess(xpdd, gref, FALSE);
   2.324        break;
   2.325      case MAP_TYPE_VIRTUAL:
   2.326        break;
   2.327 @@ -314,6 +436,20 @@ XenPci_DOP_FreeMapRegisters(
   2.328    }
   2.329    ExFreePoolWithTag(map_register_base, XENPCI_POOL_TAG);
   2.330  
   2.331 +  KeAcquireSpinLockAtDpcLevel(&xen_dma_adapter->lock);
   2.332 +  if (xen_dma_adapter->queued_map_register_base)
   2.333 +  {
   2.334 +    xen_dma_adapter->map_register_base = xen_dma_adapter->queued_map_register_base;
   2.335 +    xen_dma_adapter->queued_map_register_base = NULL;
   2.336 +    KeReleaseSpinLockFromDpcLevel(&xen_dma_adapter->lock);
   2.337 +    XenPci_ExecuteMapRegisterDma(dma_adapter, xen_dma_adapter->map_register_base);
   2.338 +  }
   2.339 +  else
   2.340 +  {
   2.341 +    xen_dma_adapter->map_register_base = NULL;
   2.342 +    KeReleaseSpinLockFromDpcLevel(&xen_dma_adapter->lock);
   2.343 +  }
   2.344 +  
   2.345    //FUNCTION_EXIT();
   2.346  }
   2.347  
   2.348 @@ -345,6 +481,7 @@ XenPci_DOP_MapTransfer(
   2.349  
   2.350    ASSERT(mdl);
   2.351    ASSERT(map_register_base);
   2.352 +  ASSERT(xen_dma_adapter->map_register_base == map_register_base);  
   2.353    ASSERT(map_register_base->count < map_register_base->total_map_registers);
   2.354    
   2.355    if (xen_dma_adapter->dma_extension)
   2.356 @@ -390,10 +527,11 @@ XenPci_DOP_MapTransfer(
   2.357      //  mdl_offset, page_offset, *Length, pfn_index));
   2.358      pfn = MmGetMdlPfnArray(mdl)[pfn_index];
   2.359      //KdPrint((__DRIVER_NAME "     B Requesting Grant Ref\n"));
   2.360 -    GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, (grant_ref_t)(map_register->logical.QuadPart >> PAGE_SHIFT));
   2.361 +    
   2.362 +    //ASSERT(map_register->gref != INVALID_GRANT_REF);
   2.363 +    GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, map_register->gref);
   2.364      //KdPrint((__DRIVER_NAME "     B Got Grant Ref %d\n", gref));
   2.365 -    map_register->logical.QuadPart &= ~(LONGLONG)(PAGE_SIZE - 1);
   2.366 -    map_register->logical.QuadPart |= page_offset;
   2.367 +    map_register->logical.QuadPart = ((LONGLONG)map_register->gref << PAGE_SHIFT) | page_offset;
   2.368      map_register_base->count++;
   2.369      break;
   2.370    case MAP_TYPE_REMAPPED:
   2.371 @@ -412,9 +550,9 @@ XenPci_DOP_MapTransfer(
   2.372        memcpy(map_register->aligned_buffer, map_register->unaligned_buffer, map_register->copy_length);
   2.373      pfn = (PFN_NUMBER)(MmGetPhysicalAddress(map_register->aligned_buffer).QuadPart >> PAGE_SHIFT);
   2.374      //KdPrint((__DRIVER_NAME "     C Requesting Grant Ref\n"));
   2.375 -    GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, (grant_ref_t)(map_register->logical.QuadPart >> PAGE_SHIFT));
   2.376 +    GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE, map_register->gref);
   2.377      //KdPrint((__DRIVER_NAME "     C Got Grant Ref %d\n", gref));
   2.378 -    map_register->logical.QuadPart &= ~(LONGLONG)(PAGE_SIZE - 1);
   2.379 +    map_register->logical.QuadPart = ((LONGLONG)map_register->gref << PAGE_SHIFT);
   2.380      map_register_base->count++;
   2.381      break;
   2.382    case MAP_TYPE_VIRTUAL:
   2.383 @@ -749,6 +887,7 @@ XenPci_DOP_BuildScatterGatherListButDont
   2.384        gref = GntTbl_GetRef(xpdd);
   2.385        if (gref == INVALID_GRANT_REF)
   2.386        {
   2.387 +        KdPrint((__DRIVER_NAME "     Not enough gref's for SG list\n"));
   2.388          /* go back through the list and free the ones we allocated */
   2.389          sglist->NumberOfElements = sg_element;
   2.390          for (sg_element = 0; sg_element < sglist->NumberOfElements; sg_element++)
   2.391 @@ -795,6 +934,10 @@ XenPci_DOP_BuildScatterGatherListButDont
   2.392          for (i = 0; remaining > 0; i++)
   2.393          {
   2.394            pfn = MmGetMdlPfnArray(curr_mdl)[pfn_offset + i];
   2.395 +          //ASSERT((grant_ref_t)(sglist->Elements[sg_element].Address.QuadPart >> PAGE_SHIFT) != INVALID_GRANT_REF);
   2.396 +          if ((grant_ref_t)(sglist->Elements[sg_element].Address.QuadPart >> PAGE_SHIFT) == INVALID_GRANT_REF)
   2.397 +            KdPrint((__DRIVER_NAME "     GGG\n"));
   2.398 +
   2.399            GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE,
   2.400              (grant_ref_t)(sglist->Elements[sg_element].Address.QuadPart >> PAGE_SHIFT));
   2.401            sglist->Elements[sg_element].Address.QuadPart |= (LONGLONG)offset;
   2.402 @@ -865,6 +1008,9 @@ for (curr_mdl = Mdl; curr_mdl; curr_mdl 
   2.403        sg_element < ADDRESS_AND_SIZE_TO_SPAN_PAGES(sg_extra->aligned_buffer, remapped_bytes); sg_element++)
   2.404      {
   2.405        pfn = (PFN_NUMBER)(MmGetPhysicalAddress((PUCHAR)sg_extra->aligned_buffer + (sg_element << PAGE_SHIFT)).QuadPart >> PAGE_SHIFT);
   2.406 +      //ASSERT((grant_ref_t)(sglist->Elements[sg_element].Address.QuadPart >> PAGE_SHIFT) != INVALID_GRANT_REF);
   2.407 +      if ((grant_ref_t)(sglist->Elements[sg_element].Address.QuadPart >> PAGE_SHIFT) == INVALID_GRANT_REF)
   2.408 +        KdPrint((__DRIVER_NAME "     HHH\n"));
   2.409        GntTbl_GrantAccess(xpdd, 0, (ULONG)pfn, FALSE,
   2.410          (grant_ref_t)(sglist->Elements[sg_element].Address.QuadPart >> PAGE_SHIFT));
   2.411        sglist->Elements[sg_element].Length = min(PAGE_SIZE, remaining);
   2.412 @@ -1141,6 +1287,10 @@ Windows accessed beyond the end of the s
   2.413  
   2.414    *number_of_map_registers = xen_dma_adapter->adapter_object.MapRegistersPerChannel; //1024; /* why not... */
   2.415  
   2.416 +  KeInitializeSpinLock(&xen_dma_adapter->lock);
   2.417 +  xen_dma_adapter->map_register_base = NULL;
   2.418 +  xen_dma_adapter->queued_map_register_base = NULL;
   2.419 +
   2.420    FUNCTION_EXIT();
   2.421  
   2.422    return &xen_dma_adapter->adapter_object.DmaHeader;