win-pvdrivers

changeset 533:82f26efb764f

Implemented DMA_ADAPTER to allow scatter gather to work on xenpci enumerated devices
author James Harper <james.harper@bendigoit.com.au>
date Tue Jan 27 00:46:08 2009 +1100 (2009-01-27)
parents b7491d4ebb3c
children 1d13cbc9a3b0
files common/include/xen_public.h xenpci/gnttbl.c xenpci/makefile.inc xenpci/xenpci.c xenpci/xenpci.h xenpci/xenpci_pdo.c
line diff
     1.1 --- a/common/include/xen_public.h	Thu Jan 22 09:39:51 2009 +1100
     1.2 +++ b/common/include/xen_public.h	Tue Jan 27 00:46:08 2009 +1100
     1.3 @@ -175,6 +175,7 @@ typedef struct {
     1.4  } XENPCI_DEVICE_STATE, *PXENPCI_DEVICE_STATE;
     1.5  
     1.6  #define XEN_INIT_DRIVER_EXTENSION_MAGIC ((ULONG)'XCFG')
     1.7 +#define XEN_DMA_DRIVER_EXTENSION_MAGIC ((ULONG)'XDMA')
     1.8  
     1.9  #define XEN_INIT_TYPE_END                       0
    1.10  #define XEN_INIT_TYPE_WRITE_STRING              1
    1.11 @@ -460,4 +461,16 @@ GET_XEN_INIT_RSP(PUCHAR *ptr, PVOID *p1,
    1.12    return retval;
    1.13  }
    1.14  
    1.15 +typedef BOOLEAN
    1.16 +(*PXEN_DMA_NEED_VIRTUAL_ADDRESS)(PIRP irp);
    1.17 +
    1.18 +typedef ULONG
    1.19 +(*PXEN_DMA_GET_ALIGNMENT)(PIRP irp);
    1.20 +
    1.21 +typedef struct {
    1.22 +  PXEN_DMA_NEED_VIRTUAL_ADDRESS need_virtual_address;
    1.23 +  PXEN_DMA_GET_ALIGNMENT get_alignment;
    1.24 +} dma_driver_extension_t;
    1.25 +
    1.26 +
    1.27  #endif
     2.1 --- a/xenpci/gnttbl.c	Thu Jan 22 09:39:51 2009 +1100
     2.2 +++ b/xenpci/gnttbl.c	Tue Jan 27 00:46:08 2009 +1100
     2.3 @@ -163,7 +163,7 @@ GntTbl_EndAccess(
     2.4    do {
     2.5      if ((flags = nflags) & (GTF_reading|GTF_writing))
     2.6      {
     2.7 -      KdPrint((__DRIVER_NAME "WARNING: g.e. still in use!\n"));
     2.8 +      KdPrint((__DRIVER_NAME "     WARNING: g.e. %d still in use!\n", ref));
     2.9        return FALSE;
    2.10      }
    2.11    } while ((nflags = InterlockedCompareExchange16(
     3.1 --- a/xenpci/makefile.inc	Thu Jan 22 09:39:51 2009 +1100
     3.2 +++ b/xenpci/makefile.inc	Tue Jan 27 00:46:08 2009 +1100
     3.3 @@ -1,6 +1,6 @@
     3.4  _LNG=$(LANGUAGE)
     3.5  STAMP=stampinf -f $@ -a $(_BUILDARCH) -d * -v $(VERSION)
     3.6  
     3.7 -..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf: $(INF_NAME).inx sources ..\common.inc
     3.8 +$(INF_NAME).inf: $(INF_NAME).inx sources ..\common.inc
     3.9      copy $(@B).inx $@
    3.10      $(STAMP)
     4.1 --- a/xenpci/xenpci.c	Thu Jan 22 09:39:51 2009 +1100
     4.2 +++ b/xenpci/xenpci.c	Tue Jan 27 00:46:08 2009 +1100
     4.3 @@ -261,6 +261,92 @@ ULONG qemu_protocol_version;
     4.4  ULONG tpr_patch_requested;
     4.5  extern PULONG InitSafeBootMode;
     4.6  
     4.7 +static VOID
     4.8 +TestStuff()
     4.9 +{
    4.10 +  int j;
    4.11 +  int i;
    4.12 +  PVOID page, page2;
    4.13 +  PMDL mdl;
    4.14 +  LARGE_INTEGER start_time, end_time;
    4.15 +  KIRQL old_irql;
    4.16 +  KSPIN_LOCK lock;
    4.17 +  NPAGED_LOOKASIDE_LIST la_list;
    4.18 +
    4.19 +  for (j = 0; j < 10; j++)
    4.20 +  {
    4.21 +    KeQuerySystemTime(&start_time);
    4.22 +    for (i = 0; i < 1000000; i++)
    4.23 +    {
    4.24 +      page = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
    4.25 +      page2 = ExAllocatePoolWithTag(NonPagedPool, sizeof(mdl) + 64, XENPCI_POOL_TAG);
    4.26 +      ExFreePoolWithTag(page, XENPCI_POOL_TAG);
    4.27 +      ExFreePoolWithTag(page2, XENPCI_POOL_TAG);
    4.28 +    }
    4.29 +    KeQuerySystemTime(&end_time);
    4.30 +    KdPrint(("ExAllocatePoolWithTag+ExFreePoolWithTag ran in %d ms\n", (end_time.QuadPart - start_time.QuadPart) / 10000));
    4.31 +  }
    4.32 +  for (j = 0; j < 10; j++)
    4.33 +  {
    4.34 +    KeQuerySystemTime(&start_time);
    4.35 +    for (i = 0; i < 1000000; i++)
    4.36 +    {
    4.37 +      mdl = AllocatePage();
    4.38 +      FreePages(mdl);
    4.39 +    }
    4.40 +    KeQuerySystemTime(&end_time);
    4.41 +    KdPrint(("AllocatePage+FreePages ran in %d ms\n", (end_time.QuadPart - start_time.QuadPart) / 10000));
    4.42 +  }
    4.43 +  KeInitializeSpinLock(&lock);
    4.44 +  for (j = 0; j < 10; j++)
    4.45 +  {
    4.46 +    KeRaiseIrql(DISPATCH_LEVEL, &old_irql);
    4.47 +    KeQuerySystemTime(&start_time);
    4.48 +    for (i = 0; i < 1000000; i++)
    4.49 +    {
    4.50 +      KeAcquireSpinLockAtDpcLevel(&lock);
    4.51 +      KeReleaseSpinLockFromDpcLevel(&lock);
    4.52 +      KeAcquireSpinLockAtDpcLevel(&lock);
    4.53 +      KeReleaseSpinLockFromDpcLevel(&lock);
    4.54 +    }
    4.55 +    KeQuerySystemTime(&end_time);
    4.56 +    KeLowerIrql(old_irql);
    4.57 +    KdPrint(("KeAcquireSpinLockAtDpcLevel+KeReleaseSpinLockFromDpcLevel x 2 ran in %d ms\n", (end_time.QuadPart - start_time.QuadPart) / 10000));
    4.58 +  }
    4.59 +  
    4.60 +  ExInitializeNPagedLookasideList(&la_list, NULL, NULL, 0, PAGE_SIZE, XENPCI_POOL_TAG, 0);
    4.61 +  for (j = 0; j < 10; j++)
    4.62 +  {
    4.63 +    KeRaiseIrql(DISPATCH_LEVEL, &old_irql);
    4.64 +    KeQuerySystemTime(&start_time);
    4.65 +    for (i = 0; i < 1000000; i++)
    4.66 +    {
    4.67 +      page = ExAllocateFromNPagedLookasideList(&la_list);
    4.68 +      page2 = ExAllocateFromNPagedLookasideList(&la_list);
    4.69 +      ExFreeToNPagedLookasideList(&la_list, page);
    4.70 +      ExFreeToNPagedLookasideList(&la_list, page2);
    4.71 +    }
    4.72 +    KeQuerySystemTime(&end_time);
    4.73 +    KeLowerIrql(old_irql);
    4.74 +    KdPrint(("ExAllocateFromNPagedLookasideList+ExFreeToNPagedLookasideList ran in %d ms\n", (end_time.QuadPart - start_time.QuadPart) / 10000));
    4.75 +  }
    4.76 +  ExDeleteNPagedLookasideList(&la_list);
    4.77 +
    4.78 +    for (j = 0; j < 10; j++)
    4.79 +  {
    4.80 +    KeRaiseIrql(DISPATCH_LEVEL, &old_irql);
    4.81 +    KeQuerySystemTime(&start_time);
    4.82 +    for (i = 0; i < 1000000; i++)
    4.83 +    {
    4.84 +      KeMemoryBarrier();
    4.85 +    }
    4.86 +    KeQuerySystemTime(&end_time);
    4.87 +    KeLowerIrql(old_irql);
    4.88 +    KdPrint(("'Nothing ran in %d ms\n", (end_time.QuadPart - start_time.QuadPart) / 10000));
    4.89 +  }
    4.90 +
    4.91 +}
    4.92 +
    4.93  NTSTATUS DDKAPI
    4.94  DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
    4.95  {
    4.96 @@ -278,7 +364,8 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
    4.97    UNREFERENCED_PARAMETER(RegistryPath);
    4.98  
    4.99    FUNCTION_ENTER();
   4.100 -  
   4.101 +
   4.102 +  //TestStuff();  
   4.103    RtlInitUnicodeString(&RegKeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
   4.104    InitializeObjectAttributes(&RegObjectAttributes, &RegKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
   4.105    status = ZwOpenKey(&RegHandle, KEY_READ, &RegObjectAttributes);
     5.1 --- a/xenpci/xenpci.h	Thu Jan 22 09:39:51 2009 +1100
     5.2 +++ b/xenpci/xenpci.h	Tue Jan 27 00:46:08 2009 +1100
     5.3 @@ -270,8 +270,18 @@ typedef struct {
     5.4    PUCHAR assigned_resources_ptr;
     5.5    XENPCI_DEVICE_STATE device_state;
     5.6    BOOLEAN restart_on_resume;
     5.7 +  
     5.8  } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
     5.9  
    5.10 +typedef struct {
    5.11 +  DMA_ADAPTER dma_adapter;
    5.12 +  DMA_OPERATIONS dma_operations;
    5.13 +  PXENPCI_PDO_DEVICE_DATA xppdd;
    5.14 +  dma_driver_extension_t *dma_extension;
    5.15 +  //ULONG map_register_count;
    5.16 +  //map_register_t *map_registers;
    5.17 +} xen_dma_adapter_t;
    5.18 +
    5.19  typedef struct
    5.20  {
    5.21    LIST_ENTRY entry;
    5.22 @@ -296,7 +306,6 @@ typedef struct {
    5.23    PIRP pending_read_irp;
    5.24  } device_interface_xenbus_context_t;
    5.25  
    5.26 -
    5.27  #include "hypercall.h"
    5.28  
    5.29  #define XBT_NIL ((xenbus_transaction_t)0)
     6.1 --- a/xenpci/xenpci_pdo.c	Thu Jan 22 09:39:51 2009 +1100
     6.2 +++ b/xenpci/xenpci_pdo.c	Tue Jan 27 00:46:08 2009 +1100
     6.3 @@ -1289,6 +1289,7 @@ XenPci_BIS_TranslateBusAddress(PVOID con
     6.4  {
     6.5    UNREFERENCED_PARAMETER(context);
     6.6    UNREFERENCED_PARAMETER(length);
     6.7 +  /* actually this isn't right - should look up the gref for the physical address and work backwards from that */
     6.8    FUNCTION_ENTER();
     6.9    if (*address_space != 0)
    6.10    {
    6.11 @@ -1301,15 +1302,512 @@ XenPci_BIS_TranslateBusAddress(PVOID con
    6.12    return TRUE;
    6.13  }
    6.14  
    6.15 +static VOID
    6.16 +XenPci_DOP_PutDmaAdapter(PDMA_ADAPTER dma_adapter)
    6.17 +{
    6.18 +  UNREFERENCED_PARAMETER(dma_adapter);
    6.19 +  
    6.20 +  FUNCTION_ENTER();
    6.21 +  // decrement ref count
    6.22 +  FUNCTION_EXIT();
    6.23 +
    6.24 +  return;
    6.25 +}
    6.26 +
    6.27 +static PVOID
    6.28 +XenPci_DOP_AllocateCommonBuffer(
    6.29 +  PDMA_ADAPTER DmaAdapter,
    6.30 +  ULONG Length,
    6.31 +  PPHYSICAL_ADDRESS LogicalAddress,
    6.32 +  BOOLEAN CacheEnabled
    6.33 +)
    6.34 +{
    6.35 +  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
    6.36 +  PXENPCI_DEVICE_DATA xpdd = xen_dma_adapter->xppdd->bus_fdo->DeviceExtension;
    6.37 +  PVOID buffer;
    6.38 +  PFN_NUMBER pfn;
    6.39 +  grant_ref_t gref;
    6.40 +  /* should LogicalAddress be the gref? */
    6.41 +  
    6.42 +  UNREFERENCED_PARAMETER(DmaAdapter);
    6.43 +  UNREFERENCED_PARAMETER(CacheEnabled);
    6.44 +  
    6.45 +  FUNCTION_ENTER();
    6.46 +  KdPrint((__DRIVER_NAME "     Length = %d\n", Length));
    6.47 +  
    6.48 +  buffer = ExAllocatePoolWithTag(NonPagedPool, Length, XENPCI_POOL_TAG);
    6.49 +
    6.50 +  pfn = (PFN_NUMBER)(MmGetPhysicalAddress(buffer).QuadPart >> PAGE_SHIFT);
    6.51 +  ASSERT(pfn);
    6.52 +  gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, pfn, FALSE, INVALID_GRANT_REF);
    6.53 +  ASSERT(gref);
    6.54 +  LogicalAddress->QuadPart = (gref << PAGE_SHIFT) | (PtrToUlong(buffer) & (PAGE_SIZE - 1));
    6.55 +  
    6.56 +  FUNCTION_EXIT();
    6.57 +  return buffer;
    6.58 +}
    6.59 +
    6.60 +static VOID
    6.61 +XenPci_DOP_FreeCommonBuffer(
    6.62 +  PDMA_ADAPTER DmaAdapter,
    6.63 +  ULONG Length,
    6.64 +  PHYSICAL_ADDRESS LogicalAddress,
    6.65 +  PVOID VirtualAddress,
    6.66 +  BOOLEAN CacheEnabled
    6.67 +)
    6.68 +{
    6.69 +  UNREFERENCED_PARAMETER(DmaAdapter);
    6.70 +
    6.71 +  FUNCTION_ENTER();
    6.72 +  ExFreePoolWithTag(VirtualAddress, XENPCI_POOL_TAG);
    6.73 +  FUNCTION_EXIT();
    6.74 +}
    6.75 +
    6.76 +static NTSTATUS
    6.77 +XenPci_DOP_AllocateAdapterChannel(
    6.78 +    IN PDMA_ADAPTER  DmaAdapter,
    6.79 +    IN PDEVICE_OBJECT  DeviceObject,
    6.80 +    IN ULONG  NumberOfMapRegisters,
    6.81 +    IN PDRIVER_CONTROL  ExecutionRoutine,
    6.82 +    IN PVOID  Context
    6.83 +    )
    6.84 +{
    6.85 +  IO_ALLOCATION_ACTION action;
    6.86 +  
    6.87 +  UNREFERENCED_PARAMETER(DmaAdapter);
    6.88 +  UNREFERENCED_PARAMETER(NumberOfMapRegisters);
    6.89 +  
    6.90 +  FUNCTION_ENTER();
    6.91 +  action = ExecutionRoutine(DeviceObject, DeviceObject->CurrentIrp, UlongToPtr(64), Context);
    6.92 +  
    6.93 +  switch (action)
    6.94 +  {
    6.95 +  case KeepObject:
    6.96 +    KdPrint((__DRIVER_NAME "     KeepObject\n"));
    6.97 +    break;
    6.98 +  case DeallocateObject:
    6.99 +    KdPrint((__DRIVER_NAME "     DeallocateObject\n"));
   6.100 +    break;
   6.101 +  case DeallocateObjectKeepRegisters:
   6.102 +    KdPrint((__DRIVER_NAME "     DeallocateObjectKeepRegisters\n"));
   6.103 +    break;
   6.104 +  default:
   6.105 +    KdPrint((__DRIVER_NAME "     Unknown action %d\n", action));
   6.106 +    break;
   6.107 +  }
   6.108 +  FUNCTION_EXIT();
   6.109 +  return STATUS_SUCCESS;
   6.110 +}
   6.111 +
   6.112 +static BOOLEAN
   6.113 +XenPci_DOP_FlushAdapterBuffers(
   6.114 +    IN PDMA_ADAPTER  DmaAdapter,
   6.115 +    IN PMDL  Mdl,
   6.116 +    IN PVOID  MapRegisterBase,
   6.117 +    IN PVOID  CurrentVa,
   6.118 +    IN ULONG  Length,
   6.119 +    IN BOOLEAN  WriteToDevice
   6.120 +    )
   6.121 +{
   6.122 +  UNREFERENCED_PARAMETER(DmaAdapter);
   6.123 +
   6.124 +  FUNCTION_ENTER();
   6.125 +  FUNCTION_EXIT();
   6.126 +}
   6.127 +
   6.128 +static VOID
   6.129 +XenPci_DOP_FreeAdapterChannel(
   6.130 +    IN PDMA_ADAPTER  DmaAdapter
   6.131 +    )
   6.132 +{
   6.133 +  UNREFERENCED_PARAMETER(DmaAdapter);
   6.134 +
   6.135 +  FUNCTION_ENTER();
   6.136 +  FUNCTION_EXIT();
   6.137 +}
   6.138 +
   6.139 +static VOID
   6.140 +XenPci_DOP_FreeMapRegisters(
   6.141 +  PDMA_ADAPTER DmaAdapter,
   6.142 +  PVOID MapRegisterBase,
   6.143 +  ULONG NumberOfMapRegisters)
   6.144 +{
   6.145 +  UNREFERENCED_PARAMETER(DmaAdapter);
   6.146 +
   6.147 +  FUNCTION_ENTER();
   6.148 +  FUNCTION_EXIT();
   6.149 +}
   6.150 +
   6.151 +static PHYSICAL_ADDRESS
   6.152 +XenPci_DOP_MapTransfer(
   6.153 +    PDMA_ADAPTER DmaAdapter,
   6.154 +    PMDL Mdl,
   6.155 +    PVOID MapRegisterBase,
   6.156 +    PVOID CurrentVa,
   6.157 +    PULONG Length,
   6.158 +    BOOLEAN WriteToDevice)
   6.159 +{
   6.160 +  UNREFERENCED_PARAMETER(DmaAdapter);
   6.161 +
   6.162 +  FUNCTION_ENTER();
   6.163 +  FUNCTION_EXIT();
   6.164 +}
   6.165 +
   6.166 +static ULONG
   6.167 +XenPci_DOP_GetDmaAlignment(
   6.168 +  PDMA_ADAPTER DmaAdapter)
   6.169 +{
   6.170 +  UNREFERENCED_PARAMETER(DmaAdapter);
   6.171 +
   6.172 +  FUNCTION_ENTER();
   6.173 +  FUNCTION_EXIT();
   6.174 +}
   6.175 +
   6.176 +static ULONG
   6.177 +XenPci_DOP_ReadDmaCounter(
   6.178 +  PDMA_ADAPTER DmaAdapter)
   6.179 +{
   6.180 +  UNREFERENCED_PARAMETER(DmaAdapter);
   6.181 +
   6.182 +  FUNCTION_ENTER();
   6.183 +  FUNCTION_EXIT();
   6.184 +}
   6.185 +
   6.186 +static NTSTATUS
   6.187 +XenPci_DOP_GetScatterGatherList(
   6.188 +  PDMA_ADAPTER DmaAdapter,
   6.189 +  PDEVICE_OBJECT DeviceObject,
   6.190 +  PMDL Mdl,
   6.191 +  PVOID CurrentVa,
   6.192 +  ULONG Length,
   6.193 +  PDRIVER_LIST_CONTROL ExecutionRoutine,
   6.194 +  PVOID Context,
   6.195 +  BOOLEAN WriteToDevice)
   6.196 +{
   6.197 +  UNREFERENCED_PARAMETER(DmaAdapter);
   6.198 +
   6.199 +  FUNCTION_ENTER();
   6.200 +  FUNCTION_EXIT();
   6.201 +}
   6.202 +
   6.203 +#define MAP_TYPE_VIRTUAL  1
   6.204 +#define MAP_TYPE_MDL      2
   6.205 +#define MAP_TYPE_REMAPPED 3
   6.206 +
   6.207 +typedef struct {
   6.208 +  ULONG map_type;
   6.209 +  PVOID aligned_buffer;
   6.210 +  PVOID unaligned_buffer;
   6.211 +  ULONG copy_length;
   6.212 +} sg_extra_t;
   6.213 +
   6.214 +static VOID
   6.215 +XenPci_DOP_PutScatterGatherList(
   6.216 +    IN PDMA_ADAPTER DmaAdapter,
   6.217 +    IN PSCATTER_GATHER_LIST ScatterGather,
   6.218 +    IN BOOLEAN WriteToDevice
   6.219 +    )
   6.220 +{
   6.221 +  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
   6.222 +  PXENPCI_DEVICE_DATA xpdd = xen_dma_adapter->xppdd->bus_fdo->DeviceExtension;
   6.223 +  ULONG i;
   6.224 +  sg_extra_t *sg_extra;
   6.225 +
   6.226 +  UNREFERENCED_PARAMETER(WriteToDevice);
   6.227 +  
   6.228 +  //FUNCTION_ENTER();
   6.229 +  
   6.230 +  sg_extra = (sg_extra_t *)((PUCHAR)ScatterGather + FIELD_OFFSET(SCATTER_GATHER_LIST, Elements) +
   6.231 +    (sizeof(SCATTER_GATHER_ELEMENT)) * ScatterGather->NumberOfElements);
   6.232 +
   6.233 +  switch (sg_extra->map_type)
   6.234 +  {
   6.235 +  case MAP_TYPE_REMAPPED:
   6.236 +    for (i = 0; i < ScatterGather->NumberOfElements; i++)
   6.237 +    {
   6.238 +      grant_ref_t gref;
   6.239 +      gref = (grant_ref_t)(ScatterGather->Elements[i].Address.QuadPart >> PAGE_SHIFT);
   6.240 +      GntTbl_EndAccess(xpdd, gref, FALSE);
   6.241 +      ScatterGather->Elements[i].Address.QuadPart = -1;
   6.242 +    }
   6.243 +    if (!WriteToDevice)
   6.244 +      memcpy(sg_extra->unaligned_buffer, sg_extra->aligned_buffer, sg_extra->copy_length);
   6.245 +    ExFreePoolWithTag(sg_extra->aligned_buffer, XENPCI_POOL_TAG);
   6.246 +    break;
   6.247 +  case MAP_TYPE_MDL:
   6.248 +    for (i = 0; i < ScatterGather->NumberOfElements; i++)
   6.249 +    {
   6.250 +      grant_ref_t gref;
   6.251 +      gref = (grant_ref_t)(ScatterGather->Elements[i].Address.QuadPart >> PAGE_SHIFT);
   6.252 +      GntTbl_EndAccess(xpdd, gref, FALSE);
   6.253 +      ScatterGather->Elements[i].Address.QuadPart = -1;
   6.254 +    }
   6.255 +    break;
   6.256 +  case MAP_TYPE_VIRTUAL:
   6.257 +    break;
   6.258 +  }
   6.259 +  //FUNCTION_EXIT();
   6.260 +}
   6.261 +
   6.262 +static NTSTATUS
   6.263 +XenPci_DOP_CalculateScatterGatherList(
   6.264 +  PDMA_ADAPTER DmaAdapter,
   6.265 +  PMDL Mdl,
   6.266 +  PVOID CurrentVa,
   6.267 +  ULONG Length,
   6.268 +  PULONG ScatterGatherListSize,
   6.269 +  PULONG NumberOfMapRegisters
   6.270 +  )
   6.271 +{
   6.272 +  ULONG elements;
   6.273 +  PMDL curr_mdl;
   6.274 +  
   6.275 +  UNREFERENCED_PARAMETER(DmaAdapter);
   6.276 +  UNREFERENCED_PARAMETER(Mdl);
   6.277 +  
   6.278 +  FUNCTION_ENTER();
   6.279 +  
   6.280 +  KdPrint((__DRIVER_NAME "     Mdl = %p\n", Mdl));
   6.281 +  KdPrint((__DRIVER_NAME "     CurrentVa = %p\n", CurrentVa));
   6.282 +  KdPrint((__DRIVER_NAME "     Length = %d\n", Length));
   6.283 +  if (Mdl)
   6.284 +  {
   6.285 +    for (curr_mdl = Mdl, elements = 0; curr_mdl; curr_mdl = curr_mdl->Next)
   6.286 +      elements += ADDRESS_AND_SIZE_TO_SPAN_PAGES(CurrentVa, Length);
   6.287 +  }
   6.288 +  else
   6.289 +  {
   6.290 +    elements = ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, Length) + 1;
   6.291 +  }
   6.292 +  
   6.293 +  *ScatterGatherListSize = FIELD_OFFSET(SCATTER_GATHER_LIST, Elements)
   6.294 +    + sizeof(SCATTER_GATHER_ELEMENT) * elements
   6.295 +    + sizeof(sg_extra_t);
   6.296 +  if (NumberOfMapRegisters)
   6.297 +    *NumberOfMapRegisters = 1;
   6.298 +
   6.299 +  KdPrint((__DRIVER_NAME "     ScatterGatherListSize = %d\n", *ScatterGatherListSize));
   6.300 +  FUNCTION_EXIT();
   6.301 +  return STATUS_SUCCESS;
   6.302 +}
   6.303 +
   6.304 +static NTSTATUS
   6.305 +XenPci_DOP_BuildScatterGatherList(
   6.306 +  IN PDMA_ADAPTER DmaAdapter,
   6.307 +  IN PDEVICE_OBJECT DeviceObject,
   6.308 +  IN PMDL Mdl,
   6.309 +  IN PVOID CurrentVa,
   6.310 +  IN ULONG Length,
   6.311 +  IN PDRIVER_LIST_CONTROL ExecutionRoutine,
   6.312 +  IN PVOID Context,
   6.313 +  IN BOOLEAN WriteToDevice,
   6.314 +  IN PVOID ScatterGatherBuffer,
   6.315 +  IN ULONG ScatterGatherBufferLength)
   6.316 +{
   6.317 +  ULONG i;
   6.318 +  PSCATTER_GATHER_LIST sglist = ScatterGatherBuffer;
   6.319 +  PUCHAR ptr;
   6.320 +  ULONG remaining = Length;
   6.321 +  ULONG total_remaining;
   6.322 +  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
   6.323 +  PXENPCI_DEVICE_DATA xpdd = xen_dma_adapter->xppdd->bus_fdo->DeviceExtension;
   6.324 +  sg_extra_t *sg_extra;
   6.325 +  PMDL curr_mdl;
   6.326 +  ULONG map_type;
   6.327 +  ULONG sg_element;
   6.328 +  ULONG offset;
   6.329 +  PFN_NUMBER pfn;
   6.330 +  grant_ref_t gref;
   6.331 +  
   6.332 +  UNREFERENCED_PARAMETER(WriteToDevice);
   6.333 +
   6.334 +  //FUNCTION_ENTER();
   6.335 +
   6.336 +  ASSERT(Mdl);
   6.337 +  if (xen_dma_adapter->dma_extension)
   6.338 +  {
   6.339 +    if (xen_dma_adapter->dma_extension->need_virtual_address(DeviceObject->CurrentIrp))
   6.340 +    {
   6.341 +      ASSERT(!Mdl->Next); /* can only virtual a single buffer */
   6.342 +      map_type = MAP_TYPE_VIRTUAL;
   6.343 +      sglist->NumberOfElements = 1;
   6.344 +    }
   6.345 +    else
   6.346 +    {
   6.347 +      ULONG alignment = xen_dma_adapter->dma_extension->get_alignment(DeviceObject->CurrentIrp);
   6.348 +      if (PtrToUlong(CurrentVa) & (alignment - 1))
   6.349 +      {
   6.350 +        ASSERT(!Mdl->Next); /* can only remap a single buffer */
   6.351 +        map_type = MAP_TYPE_REMAPPED;
   6.352 +        sglist->NumberOfElements = ADDRESS_AND_SIZE_TO_SPAN_PAGES(NULL, Length);
   6.353 +      }
   6.354 +      else
   6.355 +      {
   6.356 +        map_type = MAP_TYPE_MDL;
   6.357 +        for (curr_mdl = Mdl, sglist->NumberOfElements = 0; curr_mdl; curr_mdl = curr_mdl->Next)
   6.358 +          sglist->NumberOfElements += ADDRESS_AND_SIZE_TO_SPAN_PAGES(
   6.359 +            MmGetMdlVirtualAddress(curr_mdl), MmGetMdlByteCount(curr_mdl));
   6.360 +      }
   6.361 +    }
   6.362 +  }
   6.363 +  else
   6.364 +  {
   6.365 +    map_type = MAP_TYPE_MDL;
   6.366 +    for (curr_mdl = Mdl, sglist->NumberOfElements = 0; curr_mdl; curr_mdl = curr_mdl->Next)
   6.367 +      sglist->NumberOfElements += ADDRESS_AND_SIZE_TO_SPAN_PAGES(
   6.368 +        MmGetMdlVirtualAddress(curr_mdl), MmGetMdlByteCount(curr_mdl));
   6.369 +  }
   6.370 +  if (ScatterGatherBufferLength < FIELD_OFFSET(SCATTER_GATHER_LIST, Elements) +
   6.371 +    sizeof(SCATTER_GATHER_ELEMENT) * sglist->NumberOfElements + sizeof(sg_extra_t))
   6.372 +  {
   6.373 +    return STATUS_BUFFER_TOO_SMALL;
   6.374 +  }
   6.375 +  
   6.376 +  sg_extra = (sg_extra_t *)((PUCHAR)sglist + FIELD_OFFSET(SCATTER_GATHER_LIST, Elements) +
   6.377 +    (sizeof(SCATTER_GATHER_ELEMENT)) * sglist->NumberOfElements);
   6.378 +  
   6.379 +  sg_extra->map_type = map_type;
   6.380 +  switch (map_type)
   6.381 +  {
   6.382 +  case MAP_TYPE_MDL:
   6.383 +    //KdPrint((__DRIVER_NAME "     MAP_TYPE_MDL\n"));
   6.384 +    total_remaining = Length;
   6.385 +    for (sg_element = 0, curr_mdl = Mdl; curr_mdl; curr_mdl = curr_mdl->Next)
   6.386 +    {
   6.387 +      remaining = MmGetMdlByteCount(curr_mdl);
   6.388 +      offset = MmGetMdlByteOffset(curr_mdl);
   6.389 +      for (i = 0; i < ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(curr_mdl), MmGetMdlByteCount(curr_mdl)); i++)
   6.390 +      {
   6.391 +//KdPrint((__DRIVER_NAME "     element = %d\n", sg_element));
   6.392 +//KdPrint((__DRIVER_NAME "     remaining = %d\n", remaining));
   6.393 +        pfn = MmGetMdlPfnArray(curr_mdl)[i];
   6.394 +        ASSERT(pfn);
   6.395 +        gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, pfn, FALSE, INVALID_GRANT_REF);
   6.396 +        ASSERT(gref != INVALID_GRANT_REF);
   6.397 +        sglist->Elements[sg_element].Address.QuadPart = (LONGLONG)(gref << PAGE_SHIFT) | offset;
   6.398 +        sglist->Elements[sg_element].Length = min(min(PAGE_SIZE - offset, remaining), total_remaining);
   6.399 +        total_remaining -= sglist->Elements[sg_element].Length;
   6.400 +        remaining -= sglist->Elements[sg_element].Length;
   6.401 +        offset = 0;
   6.402 +        sg_element++;
   6.403 +      }
   6.404 +    }
   6.405 +    break;
   6.406 +  case MAP_TYPE_REMAPPED:
   6.407 +    //KdPrint((__DRIVER_NAME "     MAP_TYPE_REMAPPED\n"));
   6.408 +    sg_extra->aligned_buffer = ExAllocatePoolWithTag(NonPagedPool, max(Length, PAGE_SIZE), XENPCI_POOL_TAG);
   6.409 +    ASSERT(sg_extra->aligned_buffer); /* lazy */
   6.410 +    sg_extra->unaligned_buffer = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
   6.411 +    ASSERT(sg_extra->unaligned_buffer); /* lazy */
   6.412 +    sg_extra->copy_length = Length;
   6.413 +    if (WriteToDevice)
   6.414 +      memcpy(sg_extra->aligned_buffer, sg_extra->unaligned_buffer, sg_extra->copy_length);
   6.415 +    for (sg_element = 0, remaining = Length; 
   6.416 +      sg_element < ADDRESS_AND_SIZE_TO_SPAN_PAGES(sg_extra->aligned_buffer, Length); sg_element++)
   6.417 +    {
   6.418 +      pfn = (PFN_NUMBER)(MmGetPhysicalAddress((PUCHAR)sg_extra->aligned_buffer + (sg_element << PAGE_SHIFT)).QuadPart >> PAGE_SHIFT);
   6.419 +      ASSERT(pfn);
   6.420 +      gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, pfn, FALSE, INVALID_GRANT_REF);
   6.421 +      ASSERT(gref);
   6.422 +      sglist->Elements[sg_element].Address.QuadPart = (ULONGLONG)gref << PAGE_SHIFT;
   6.423 +      sglist->Elements[sg_element].Length = min(PAGE_SIZE, remaining);
   6.424 +      remaining -= sglist->Elements[sg_element].Length;
   6.425 +    }
   6.426 +    break;
   6.427 +  case MAP_TYPE_VIRTUAL:
   6.428 +    //KdPrint((__DRIVER_NAME "     MAP_TYPE_VIRTUAL\n"));
   6.429 +    ptr = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
   6.430 +    ASSERT(ptr); /* lazy */
   6.431 +    sglist->Elements[0].Address.QuadPart = (ULONGLONG)ptr;
   6.432 +    sglist->Elements[0].Length = Length;
   6.433 +    break;
   6.434 +  }
   6.435 +  //KdPrint((__DRIVER_NAME "     CurrentVa = %p, Length = %d\n", CurrentVa, Length));
   6.436 +  //for (i = 0; i < sglist->NumberOfElements; i++)
   6.437 +  //{
   6.438 +    //KdPrint((__DRIVER_NAME "     sge[%d]->Address = %08x%08x, Length = %d\n", i, sglist->Elements[i].Address.HighPart,
   6.439 +    //  sglist->Elements[i].Address.LowPart, sglist->Elements[i].Length));
   6.440 +  //}
   6.441 +  
   6.442 +  ExecutionRoutine(DeviceObject, DeviceObject->CurrentIrp, ScatterGatherBuffer, Context);
   6.443 +
   6.444 +  //FUNCTION_EXIT();
   6.445 +  
   6.446 +  return STATUS_SUCCESS;
   6.447 +}
   6.448 +
   6.449 +static NTSTATUS
   6.450 +XenPci_DOP_BuildMdlFromScatterGatherList(
   6.451 +    IN PDMA_ADAPTER  DmaAdapter,
   6.452 +    IN PSCATTER_GATHER_LIST  ScatterGather,
   6.453 +    IN PMDL  OriginalMdl,
   6.454 +    OUT PMDL  *TargetMdl
   6.455 +    )
   6.456 +{
   6.457 +  FUNCTION_ENTER();
   6.458 +  FUNCTION_EXIT();
   6.459 +  return STATUS_UNSUCCESSFUL;
   6.460 +}
   6.461 +
   6.462  static PDMA_ADAPTER
   6.463  XenPci_BIS_GetDmaAdapter(PVOID context, PDEVICE_DESCRIPTION device_descriptor, PULONG number_of_map_registers)
   6.464  {
   6.465 -  UNREFERENCED_PARAMETER(context);
   6.466 +  xen_dma_adapter_t *xen_dma_adapter;
   6.467 +  PDEVICE_OBJECT curr, prev;
   6.468 +  PDRIVER_OBJECT fdo_driver_object;
   6.469 +  PVOID fdo_driver_extension;
   6.470 +  
   6.471    UNREFERENCED_PARAMETER(device_descriptor);
   6.472 -  UNREFERENCED_PARAMETER(number_of_map_registers);
   6.473 +  
   6.474    FUNCTION_ENTER();
   6.475 +  xen_dma_adapter = ExAllocatePoolWithTag(NonPagedPool, sizeof(xen_dma_adapter_t), XENPCI_POOL_TAG);
   6.476 +  xen_dma_adapter->dma_adapter.Version = 2;
   6.477 +  xen_dma_adapter->dma_adapter.Size = sizeof(xen_dma_adapter_t);
   6.478 +  xen_dma_adapter->dma_adapter.DmaOperations = &xen_dma_adapter->dma_operations;
   6.479 +  xen_dma_adapter->dma_operations.Size = sizeof(DMA_OPERATIONS);
   6.480 +  xen_dma_adapter->dma_operations.PutDmaAdapter = XenPci_DOP_PutDmaAdapter;
   6.481 +  xen_dma_adapter->dma_operations.AllocateCommonBuffer = XenPci_DOP_AllocateCommonBuffer;
   6.482 +  xen_dma_adapter->dma_operations.FreeCommonBuffer = XenPci_DOP_FreeCommonBuffer;
   6.483 +  xen_dma_adapter->dma_operations.AllocateAdapterChannel = XenPci_DOP_AllocateAdapterChannel;
   6.484 +  xen_dma_adapter->dma_operations.FlushAdapterBuffers = XenPci_DOP_FlushAdapterBuffers;
   6.485 +  xen_dma_adapter->dma_operations.FreeAdapterChannel = XenPci_DOP_FreeAdapterChannel;
   6.486 +  xen_dma_adapter->dma_operations.FreeMapRegisters = XenPci_DOP_FreeMapRegisters;
   6.487 +  xen_dma_adapter->dma_operations.MapTransfer = XenPci_DOP_MapTransfer;
   6.488 +  xen_dma_adapter->dma_operations.GetDmaAlignment = XenPci_DOP_GetDmaAlignment;
   6.489 +  xen_dma_adapter->dma_operations.ReadDmaCounter = XenPci_DOP_ReadDmaCounter;
   6.490 +  xen_dma_adapter->dma_operations.GetScatterGatherList = XenPci_DOP_GetScatterGatherList;
   6.491 +  xen_dma_adapter->dma_operations.PutScatterGatherList = XenPci_DOP_PutScatterGatherList;
   6.492 +  xen_dma_adapter->dma_operations.CalculateScatterGatherList = XenPci_DOP_CalculateScatterGatherList;
   6.493 +  xen_dma_adapter->dma_operations.BuildScatterGatherList = XenPci_DOP_BuildScatterGatherList;
   6.494 +  xen_dma_adapter->dma_operations.BuildMdlFromScatterGatherList = XenPci_DOP_BuildMdlFromScatterGatherList;
   6.495 +  xen_dma_adapter->xppdd = context;
   6.496 +  xen_dma_adapter->dma_extension = NULL;
   6.497 +
   6.498 +  curr = IoGetAttachedDeviceReference(xen_dma_adapter->xppdd->common.pdo);
   6.499 +  while (curr != NULL)
   6.500 +  {
   6.501 +    fdo_driver_object = curr->DriverObject;
   6.502 +    KdPrint((__DRIVER_NAME "     fdo_driver_object = %p\n", fdo_driver_object));
   6.503 +    if (fdo_driver_object)
   6.504 +    {
   6.505 +      fdo_driver_extension = IoGetDriverObjectExtension(fdo_driver_object, UlongToPtr(XEN_DMA_DRIVER_EXTENSION_MAGIC));
   6.506 +      if (fdo_driver_extension)
   6.507 +      {
   6.508 +        xen_dma_adapter->dma_extension = (dma_driver_extension_t *)fdo_driver_extension;
   6.509 +        ObDereferenceObject(curr);
   6.510 +        break;
   6.511 +      }
   6.512 +    }
   6.513 +    prev = curr;
   6.514 +    curr = IoGetLowerDeviceObject(curr);
   6.515 +    ObDereferenceObject(prev);
   6.516 +  }
   6.517 +
   6.518 +  *number_of_map_registers = 1024; /* why not... */
   6.519 +
   6.520    FUNCTION_EXIT();
   6.521 -  return NULL;
   6.522 +
   6.523 +  return &xen_dma_adapter->dma_adapter;
   6.524  }
   6.525  
   6.526  static ULONG