win-pvdrivers

changeset 536:1d39de3ab8d6

mostly finished migration back to kmdf
author James Harper <james.harper@bendigoit.com.au>
date Sat Feb 14 13:35:48 2009 +1100 (2009-02-14)
parents 285d80861ecf
children 2a74ac2f43bb
files common.inc common/include/xen_public.h common/include/xen_windows.h shutdownmon/shutdownmon.c xennet/makefile.inc xennet/sources xennet/xennet.c xennet/xennet.h xennet/xennet_common.c xennet/xennet_oid.c xennet/xennet_rx.c xennet/xennet_tx.c xenpci/evtchn.c xenpci/gnttbl.c xenpci/makefile.inc xenpci/memory.c xenpci/sources xenpci/xenbus.c xenpci/xenbus_device_interface.c xenpci/xenpci.c xenpci/xenpci.h xenpci/xenpci.inx xenpci/xenpci_fdo.c xenpci/xenpci_highsync.c xenpci/xenpci_pdo.c xenscsi/xenscsi.c xenstub/makefile.inc xenstub/sources xenvbd/makefile.inc xenvbd/sources xenvbd/xenvbd.c xenvbd/xenvbd.h
line diff
     1.1 --- a/common.inc	Tue Jan 27 00:47:02 2009 +1100
     1.2 +++ b/common.inc	Sat Feb 14 13:35:48 2009 +1100
     1.3 @@ -1,5 +1,5 @@
     1.4  VERSION=0.9.11.15
     1.5 -TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.6 +#TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7  MSC_WARNING_LEVEL=/W4
     1.8  INCLUDES = ..\common\include;..\common\include\public
     1.9  TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\ntstrsafe.lib
     2.1 --- a/common/include/xen_public.h	Tue Jan 27 00:47:02 2009 +1100
     2.2 +++ b/common/include/xen_public.h	Sat Feb 14 13:35:48 2009 +1100
     2.3 @@ -20,457 +20,11 @@ Foundation, Inc., 51 Franklin Street, Fi
     2.4  #if !defined(_XEN_PUBLIC_H_)
     2.5  #define _XEN_PUBLIC_H_
     2.6  
     2.7 -#include <grant_table.h>
     2.8 -#include <event_channel.h>
     2.9 -#include <xen_guids.h>
    2.10 -
    2.11  // {5C568AC5-9DDF-4FA5-A94A-39D67077819C}
    2.12  DEFINE_GUID(GUID_XEN_IFACE, 0x5C568AC5, 0x9DDF, 0x4FA5, 0xA9, 0x4A, 0x39, 0xD6, 0x70, 0x77, 0x81, 0x9C);
    2.13  
    2.14  // {14CE175A-3EE2-4fae-9252-00DBD84F018E}
    2.15 -DEFINE_GUID(GUID_XENBUS_IFACE, 0x14ce175a, 0x3ee2, 0x4fae, 0x92, 0x52, 0x0, 0xdb, 0xd8, 0x4f, 0x1, 0x8e);
    2.16 -
    2.17 -#define INVALID_GRANT_REF 0xFFFFFFFF
    2.18 -
    2.19 -typedef PHYSICAL_ADDRESS
    2.20 -(*PXEN_ALLOCMMIO)(PVOID Context, ULONG Length);
    2.21 -
    2.22 -typedef void
    2.23 -(*PXEN_FREEMEM)(PVOID Ptr);
    2.24 -
    2.25 -typedef VOID
    2.26 -(*PXEN_EVTCHN_SERVICE_ROUTINE)(PVOID Context);
    2.27 -
    2.28 -typedef NTSTATUS
    2.29 -(*PXEN_EVTCHN_BIND)(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
    2.30 -
    2.31 -typedef NTSTATUS
    2.32 -(*PXEN_EVTCHN_UNBIND)(PVOID Context, evtchn_port_t Port);
    2.33 -
    2.34 -typedef NTSTATUS
    2.35 -(*PXEN_EVTCHN_MASK)(PVOID Context, evtchn_port_t Port);
    2.36 -
    2.37 -typedef NTSTATUS
    2.38 -(*PXEN_EVTCHN_UNMASK)(PVOID Context, evtchn_port_t Port);
    2.39 -
    2.40 -typedef NTSTATUS
    2.41 -(*PXEN_EVTCHN_NOTIFY)(PVOID Context, evtchn_port_t Port);
    2.42 -
    2.43 -typedef evtchn_port_t
    2.44 -(*PXEN_EVTCHN_ALLOCUNBOUND)(PVOID Context, domid_t Domain);
    2.45 -
    2.46 -typedef BOOLEAN
    2.47 -(*PXEN_EVTCHN_ACK_EVENT)(PVOID context, evtchn_port_t port);
    2.48 -
    2.49 -typedef BOOLEAN
    2.50 -(*PXEN_EVTCHN_SYNC)(PVOID Context, PKSYNCHRONIZE_ROUTINE sync_routine, PVOID sync_context);
    2.51 -
    2.52 -typedef grant_ref_t
    2.53 -(*PXEN_GNTTBL_GRANTACCESS)(PVOID Context, domid_t domid, uint32_t frame, int readonly, grant_ref_t ref);
    2.54 -
    2.55 -typedef BOOLEAN
    2.56 -(*PXEN_GNTTBL_ENDACCESS)(PVOID Context, grant_ref_t ref, BOOLEAN keepref);
    2.57 -
    2.58 -typedef VOID
    2.59 -(*PXEN_GNTTBL_PUTREF)(PVOID Context, grant_ref_t ref);
    2.60 -
    2.61 -typedef grant_ref_t
    2.62 -(*PXEN_GNTTBL_GETREF)(PVOID Context);
    2.63 -
    2.64 -
    2.65 -typedef VOID
    2.66 -(*PXENBUS_WATCH_CALLBACK)(char *Path, PVOID ServiceContext);
    2.67 -
    2.68 -typedef char *
    2.69 -(*PXEN_XENBUS_READ)(PVOID Context, xenbus_transaction_t xbt, char *path, char **value);
    2.70 -
    2.71 -typedef char *
    2.72 -(*PXEN_XENBUS_WRITE)(PVOID Context, xenbus_transaction_t xbt, char *path, char *value);
    2.73 -
    2.74 -typedef char *
    2.75 -(*PXEN_XENBUS_PRINTF)(PVOID Context, xenbus_transaction_t xbt, char *path, char *fmt, ...);
    2.76 -
    2.77 -typedef char *
    2.78 -(*PXEN_XENBUS_STARTTRANSACTION)(PVOID Context, xenbus_transaction_t *xbt);
    2.79 -
    2.80 -typedef char *
    2.81 -(*PXEN_XENBUS_ENDTRANSACTION)(PVOID Context, xenbus_transaction_t t, int abort, int *retry);
    2.82 -
    2.83 -typedef char *
    2.84 -(*PXEN_XENBUS_LIST)(PVOID Context, xenbus_transaction_t xbt, char *prefix, char ***contents);
    2.85 -
    2.86 -typedef char *
    2.87 -(*PXEN_XENBUS_ADDWATCH)(PVOID Context, xenbus_transaction_t xbt, char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
    2.88 -
    2.89 -typedef char *
    2.90 -(*PXEN_XENBUS_REMWATCH)(PVOID Context, xenbus_transaction_t xbt, char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
    2.91 -
    2.92 -typedef NTSTATUS
    2.93 -(*PXEN_XENPCI_XEN_CONFIG_DEVICE)(PVOID Context);
    2.94 -
    2.95 -typedef NTSTATUS
    2.96 -(*PXEN_XENPCI_XEN_SHUTDOWN_DEVICE)(PVOID Context);
    2.97 -
    2.98 -#ifndef XENPCI_POOL_TAG
    2.99 -#define XENPCI_POOL_TAG (ULONG) 'XenP'
   2.100 -#endif
   2.101 -
   2.102 -static __inline VOID
   2.103 -XenPci_FreeMem(PVOID Ptr)
   2.104 -{
   2.105 -  ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
   2.106 -}
   2.107 -
   2.108 -#define XEN_DATA_MAGIC 0x12345678
   2.109 -
   2.110 -typedef struct {
   2.111 -  ULONG magic;
   2.112 -  USHORT length;
   2.113 -
   2.114 -  PVOID context;
   2.115 -  PXEN_EVTCHN_BIND EvtChn_Bind;
   2.116 -  PXEN_EVTCHN_BIND EvtChn_BindDpc;
   2.117 -  PXEN_EVTCHN_UNBIND EvtChn_Unbind;
   2.118 -  PXEN_EVTCHN_MASK EvtChn_Mask;
   2.119 -  PXEN_EVTCHN_UNMASK EvtChn_Unmask;
   2.120 -  PXEN_EVTCHN_NOTIFY EvtChn_Notify;
   2.121 -  PXEN_EVTCHN_ACK_EVENT EvtChn_AckEvent;
   2.122 -  PXEN_EVTCHN_SYNC EvtChn_Sync;
   2.123 -
   2.124 -  PXEN_GNTTBL_GETREF GntTbl_GetRef;
   2.125 -  PXEN_GNTTBL_PUTREF GntTbl_PutRef;
   2.126 -  PXEN_GNTTBL_GRANTACCESS GntTbl_GrantAccess;
   2.127 -  PXEN_GNTTBL_ENDACCESS GntTbl_EndAccess;
   2.128 -
   2.129 -  PXEN_XENPCI_XEN_CONFIG_DEVICE XenPci_XenConfigDevice;
   2.130 -  PXEN_XENPCI_XEN_SHUTDOWN_DEVICE XenPci_XenShutdownDevice;
   2.131 -
   2.132 -  CHAR path[128];
   2.133 -  CHAR backend_path[128];
   2.134 -
   2.135 -  evtchn_port_t pdo_event_channel;
   2.136 -
   2.137 -  PXEN_XENBUS_READ XenBus_Read;
   2.138 -  PXEN_XENBUS_WRITE XenBus_Write;
   2.139 -  PXEN_XENBUS_PRINTF XenBus_Printf;
   2.140 -  PXEN_XENBUS_STARTTRANSACTION XenBus_StartTransaction;
   2.141 -  PXEN_XENBUS_ENDTRANSACTION XenBus_EndTransaction;
   2.142 -  PXEN_XENBUS_LIST XenBus_List;
   2.143 -  PXEN_XENBUS_ADDWATCH XenBus_AddWatch;
   2.144 -  PXEN_XENBUS_REMWATCH XenBus_RemWatch;
   2.145 -
   2.146 -} XENPCI_VECTORS, *PXENPCI_VECTORS;
   2.147 -
   2.148 -#define RESUME_STATE_RUNNING            0
   2.149 -#define RESUME_STATE_SUSPENDING         1
   2.150 -#define RESUME_STATE_BACKEND_RESUME     2
   2.151 -#define RESUME_STATE_FRONTEND_RESUME    3
   2.152 -
   2.153 -typedef struct {
   2.154 -  ULONG magic;
   2.155 -  USHORT length;
   2.156 -
   2.157 -  ULONG resume_state;
   2.158 -  ULONG resume_state_ack;
   2.159 -} XENPCI_DEVICE_STATE, *PXENPCI_DEVICE_STATE;
   2.160 -
   2.161 -#define XEN_INIT_DRIVER_EXTENSION_MAGIC ((ULONG)'XCFG')
   2.162 -#define XEN_DMA_DRIVER_EXTENSION_MAGIC ((ULONG)'XDMA')
   2.163 -
   2.164 -#define XEN_INIT_TYPE_END                       0
   2.165 -#define XEN_INIT_TYPE_WRITE_STRING              1
   2.166 -#define XEN_INIT_TYPE_RING                      2
   2.167 -#define XEN_INIT_TYPE_EVENT_CHANNEL             3
   2.168 -#define XEN_INIT_TYPE_EVENT_CHANNEL_IRQ         4
   2.169 -#define XEN_INIT_TYPE_READ_STRING_FRONT         5
   2.170 -#define XEN_INIT_TYPE_READ_STRING_BACK          6
   2.171 -#define XEN_INIT_TYPE_VECTORS                   7
   2.172 -#define XEN_INIT_TYPE_GRANT_ENTRIES             8
   2.173 -//#define XEN_INIT_TYPE_COPY_PTR                  9
   2.174 -#define XEN_INIT_TYPE_RUN                       10
   2.175 -#define XEN_INIT_TYPE_STATE_PTR                 11
   2.176 -#define XEN_INIT_TYPE_ACTIVE                    12
   2.177 -#define XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION     13
   2.178 -
   2.179 -static __inline VOID
   2.180 -__ADD_XEN_INIT_UCHAR(PUCHAR *ptr, UCHAR val)
   2.181 -{
   2.182 -//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_UCHAR *ptr = %p, val = %d\n", *ptr, val));
   2.183 -  *(PUCHAR)(*ptr) = val;
   2.184 -  *ptr += sizeof(UCHAR);
   2.185 -}
   2.186 -
   2.187 -static __inline VOID
   2.188 -__ADD_XEN_INIT_USHORT(PUCHAR *ptr, USHORT val)
   2.189 -{
   2.190 -//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_USHORT *ptr = %p, val = %d\n", *ptr, val));
   2.191 -  *(PUSHORT)(*ptr) = val;
   2.192 -  *ptr += sizeof(USHORT);
   2.193 -}
   2.194 -
   2.195 -static __inline VOID
   2.196 -__ADD_XEN_INIT_ULONG(PUCHAR *ptr, ULONG val)
   2.197 -{
   2.198 -//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_ULONG *ptr = %p, val = %d\n", *ptr, val));
   2.199 -  *(PULONG)(*ptr) = val;
   2.200 -  *ptr += sizeof(ULONG);
   2.201 -}
   2.202 -
   2.203 -static __inline VOID
   2.204 -__ADD_XEN_INIT_PTR(PUCHAR *ptr, PVOID val)
   2.205 -{
   2.206 -//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_PTR *ptr = %p, val = %p\n", *ptr, val));
   2.207 -  *(PVOID *)(*ptr) = val;
   2.208 -  *ptr += sizeof(PVOID);
   2.209 -}
   2.210 -
   2.211 -static __inline VOID
   2.212 -__ADD_XEN_INIT_STRING(PUCHAR *ptr, PCHAR val)
   2.213 -{
   2.214 -//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_STRING *ptr = %p, val = %s\n", *ptr, val));
   2.215 -  RtlStringCbCopyA((PCHAR)*ptr, PAGE_SIZE - (PtrToUlong(*ptr) & (PAGE_SIZE - 1)), val);
   2.216 -  *ptr += strlen(val) + 1;
   2.217 -}
   2.218 -
   2.219 -static __inline UCHAR
   2.220 -__GET_XEN_INIT_UCHAR(PUCHAR *ptr)
   2.221 -{
   2.222 -  UCHAR retval;
   2.223 -  retval = **ptr;
   2.224 -//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_UCHAR *ptr = %p, retval = %d\n", *ptr, retval));
   2.225 -  *ptr += sizeof(UCHAR);
   2.226 -  return retval;
   2.227 -}
   2.228 -
   2.229 -static __inline USHORT
   2.230 -__GET_XEN_INIT_USHORT(PUCHAR *ptr)
   2.231 -{
   2.232 -  USHORT retval;
   2.233 -  retval = *(PUSHORT)*ptr;
   2.234 -//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_USHORT *ptr = %p, retval = %d\n", *ptr, retval));
   2.235 -  *ptr += sizeof(USHORT);
   2.236 -  return retval;
   2.237 -}
   2.238 -
   2.239 -static __inline ULONG
   2.240 -__GET_XEN_INIT_ULONG(PUCHAR *ptr)
   2.241 -{
   2.242 -  ULONG retval;
   2.243 -  retval = *(PLONG)*ptr;
   2.244 -//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_ULONG *ptr = %p, retval = %d\n", *ptr, retval));
   2.245 -  *ptr += sizeof(ULONG);
   2.246 -  return retval;
   2.247 -}
   2.248 -
   2.249 -static __inline PCHAR
   2.250 -__GET_XEN_INIT_STRING(PUCHAR *ptr)
   2.251 -{
   2.252 -  PCHAR retval;
   2.253 -  retval = (PCHAR)*ptr;
   2.254 -//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_STRING *ptr = %p, retval = %s\n", *ptr, retval));
   2.255 -  *ptr += strlen((PCHAR)*ptr) + 1;
   2.256 -  return retval;
   2.257 -}
   2.258 -
   2.259 -static __inline PVOID
   2.260 -__GET_XEN_INIT_PTR(PUCHAR *ptr)
   2.261 -{
   2.262 -  PVOID retval;
   2.263 -  retval = *(PVOID *)(*ptr);
   2.264 -//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_PTR *ptr = %p, retval = %p\n", *ptr, retval));
   2.265 -  *ptr += sizeof(PVOID);
   2.266 -  return retval;
   2.267 -}
   2.268 -
   2.269 -static __inline VOID
   2.270 -ADD_XEN_INIT_REQ(PUCHAR *ptr, UCHAR type, PVOID p1, PVOID p2)
   2.271 -{
   2.272 -  __ADD_XEN_INIT_UCHAR(ptr, type);
   2.273 -  switch (type)
   2.274 -  {
   2.275 -  case XEN_INIT_TYPE_END:
   2.276 -  case XEN_INIT_TYPE_VECTORS:
   2.277 -  case XEN_INIT_TYPE_RUN:
   2.278 -  case XEN_INIT_TYPE_STATE_PTR:
   2.279 -  case XEN_INIT_TYPE_ACTIVE:
   2.280 -  case XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION:
   2.281 -    break;
   2.282 -  case XEN_INIT_TYPE_WRITE_STRING:
   2.283 -    __ADD_XEN_INIT_STRING(ptr, (PCHAR) p1);
   2.284 -    __ADD_XEN_INIT_STRING(ptr, (PCHAR) p2);
   2.285 -    break;
   2.286 -  case XEN_INIT_TYPE_RING:
   2.287 -  case XEN_INIT_TYPE_EVENT_CHANNEL:
   2.288 -  case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ:
   2.289 -  case XEN_INIT_TYPE_READ_STRING_FRONT:
   2.290 -  case XEN_INIT_TYPE_READ_STRING_BACK:
   2.291 -    __ADD_XEN_INIT_STRING(ptr, (PCHAR) p1);
   2.292 -    break;
   2.293 -  case XEN_INIT_TYPE_GRANT_ENTRIES:
   2.294 -    __ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p2));
   2.295 -    break;
   2.296 -//  case XEN_INIT_TYPE_COPY_PTR:
   2.297 -//    __ADD_XEN_INIT_STRING(ptr, p1);
   2.298 -//    __ADD_XEN_INIT_PTR(ptr, p2);
   2.299 -//    break;
   2.300 -  }
   2.301 -}
   2.302 -
   2.303 -static __inline UCHAR
   2.304 -GET_XEN_INIT_REQ(PUCHAR *ptr, PVOID *p1, PVOID *p2)
   2.305 -{
   2.306 -  UCHAR retval;
   2.307 -
   2.308 -  retval = __GET_XEN_INIT_UCHAR(ptr);
   2.309 -  switch (retval)
   2.310 -  {
   2.311 -  case XEN_INIT_TYPE_END:
   2.312 -  case XEN_INIT_TYPE_VECTORS:
   2.313 -  case XEN_INIT_TYPE_RUN:
   2.314 -  case XEN_INIT_TYPE_STATE_PTR:
   2.315 -  case XEN_INIT_TYPE_ACTIVE:
   2.316 -  case XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION:
   2.317 -    *p1 = NULL;
   2.318 -    *p2 = NULL;
   2.319 -    break;
   2.320 -  case XEN_INIT_TYPE_WRITE_STRING:
   2.321 -    *p1 = __GET_XEN_INIT_STRING(ptr);
   2.322 -    *p2 = __GET_XEN_INIT_STRING(ptr);
   2.323 -    break;
   2.324 -  case XEN_INIT_TYPE_RING:
   2.325 -  case XEN_INIT_TYPE_EVENT_CHANNEL:
   2.326 -  case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ:
   2.327 -  case XEN_INIT_TYPE_READ_STRING_FRONT:
   2.328 -  case XEN_INIT_TYPE_READ_STRING_BACK:
   2.329 -    *p1 = __GET_XEN_INIT_STRING(ptr);
   2.330 -    *p2 = NULL;
   2.331 -    break;
   2.332 -  case XEN_INIT_TYPE_GRANT_ENTRIES:
   2.333 -    *p2 = UlongToPtr(__GET_XEN_INIT_ULONG(ptr));
   2.334 -    break;
   2.335 -//  case XEN_INIT_TYPE_COPY_PTR:
   2.336 -//    *p1 = __GET_XEN_INIT_STRING(ptr);
   2.337 -//    *p2 = __GET_XEN_INIT_PTR(ptr);
   2.338 -//    break;
   2.339 -  }
   2.340 -  return retval;
   2.341 -}
   2.342 -
   2.343 -static __inline VOID
   2.344 -ADD_XEN_INIT_RSP(PUCHAR *ptr, UCHAR type, PVOID p1, PVOID p2)
   2.345 -{
   2.346 -  __ADD_XEN_INIT_UCHAR(ptr, type);
   2.347 -  switch (type)
   2.348 -  {
   2.349 -  case XEN_INIT_TYPE_END:
   2.350 -  case XEN_INIT_TYPE_WRITE_STRING: /* this shouldn't happen */
   2.351 -  case XEN_INIT_TYPE_RUN:
   2.352 -  case XEN_INIT_TYPE_ACTIVE:
   2.353 -    break;
   2.354 -  case XEN_INIT_TYPE_RING:
   2.355 -    __ADD_XEN_INIT_STRING(ptr, (PCHAR) p1);
   2.356 -    __ADD_XEN_INIT_PTR(ptr, p2);
   2.357 -    break;
   2.358 -  case XEN_INIT_TYPE_EVENT_CHANNEL:
   2.359 -  case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ:
   2.360 -    __ADD_XEN_INIT_STRING(ptr, (PCHAR) p1);
   2.361 -    __ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p2));
   2.362 -    break;
   2.363 -  case XEN_INIT_TYPE_READ_STRING_FRONT:
   2.364 -  case XEN_INIT_TYPE_READ_STRING_BACK:
   2.365 -    __ADD_XEN_INIT_STRING(ptr, (PCHAR) p1);
   2.366 -    __ADD_XEN_INIT_STRING(ptr, (PCHAR) p2);
   2.367 -    break;
   2.368 -  case XEN_INIT_TYPE_VECTORS:
   2.369 -    //__ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p1));
   2.370 -    memcpy(*ptr, p2, sizeof(XENPCI_VECTORS));
   2.371 -    *ptr += sizeof(XENPCI_VECTORS);
   2.372 -    break;
   2.373 -  case XEN_INIT_TYPE_GRANT_ENTRIES:
   2.374 -    __ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p1));
   2.375 -    memcpy(*ptr, p2, PtrToUlong(p1) * sizeof(grant_entry_t));
   2.376 -    *ptr += PtrToUlong(p1) * sizeof(grant_entry_t);
   2.377 -    break;
   2.378 -  case XEN_INIT_TYPE_STATE_PTR:
   2.379 -    __ADD_XEN_INIT_PTR(ptr, p2);
   2.380 -    break;
   2.381 -  case XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION:
   2.382 -    __ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p2));
   2.383 -    break;
   2.384 -//  case XEN_INIT_TYPE_COPY_PTR:
   2.385 -//    __ADD_XEN_INIT_STRING(ptr, p1);
   2.386 -//    __ADD_XEN_INIT_PTR(ptr, p2);
   2.387 -//    break;
   2.388 -  }
   2.389 -}
   2.390 -
   2.391 -static __inline UCHAR
   2.392 -GET_XEN_INIT_RSP(PUCHAR *ptr, PVOID *p1, PVOID *p2)
   2.393 -{
   2.394 -  UCHAR retval;
   2.395 -
   2.396 -  retval = __GET_XEN_INIT_UCHAR(ptr);
   2.397 -  switch (retval)
   2.398 -  {
   2.399 -  case XEN_INIT_TYPE_END:
   2.400 -  case XEN_INIT_TYPE_RUN:
   2.401 -  case XEN_INIT_TYPE_ACTIVE:
   2.402 -    *p1 = NULL;
   2.403 -    *p2 = NULL;
   2.404 -    break;
   2.405 -  case XEN_INIT_TYPE_WRITE_STRING:
   2.406 -    // this shouldn't happen - no response here
   2.407 -    break;
   2.408 -  case XEN_INIT_TYPE_RING:
   2.409 -    *p1 = __GET_XEN_INIT_STRING(ptr);
   2.410 -    *p2 = __GET_XEN_INIT_PTR(ptr);
   2.411 -    break;
   2.412 -  case XEN_INIT_TYPE_EVENT_CHANNEL:
   2.413 -  case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ:
   2.414 -    *p1 = __GET_XEN_INIT_STRING(ptr);
   2.415 -    *p2 = UlongToPtr(__GET_XEN_INIT_ULONG(ptr));
   2.416 -    break;
   2.417 -  case XEN_INIT_TYPE_READ_STRING_FRONT:
   2.418 -    *p1 = __GET_XEN_INIT_STRING(ptr);
   2.419 -    *p2 = __GET_XEN_INIT_STRING(ptr);
   2.420 -    break;
   2.421 -  case XEN_INIT_TYPE_READ_STRING_BACK:
   2.422 -    *p1 = __GET_XEN_INIT_STRING(ptr);
   2.423 -    *p2 = __GET_XEN_INIT_STRING(ptr);
   2.424 -    break;
   2.425 -  case XEN_INIT_TYPE_VECTORS:
   2.426 -    *p1 = NULL;
   2.427 -    *p2 = *ptr;
   2.428 -    *ptr += ((PXENPCI_VECTORS)*p2)->length;
   2.429 -    break;
   2.430 -  case XEN_INIT_TYPE_GRANT_ENTRIES:
   2.431 -    *p1 = UlongToPtr(__GET_XEN_INIT_ULONG(ptr));
   2.432 -    *p2 = *ptr;
   2.433 -    *ptr += PtrToUlong(*p1) * sizeof(grant_ref_t);
   2.434 -    break;
   2.435 -  case XEN_INIT_TYPE_STATE_PTR:
   2.436 -    *p2 = __GET_XEN_INIT_PTR(ptr);
   2.437 -    break;
   2.438 -  case XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION:
   2.439 -    *p2 = UlongToPtr(__GET_XEN_INIT_ULONG(ptr));
   2.440 -    break;
   2.441 -//  case XEN_INIT_TYPE_COPY_PTR:
   2.442 -//    *p1 = __GET_XEN_INIT_STRING(ptr);
   2.443 -//    *p2 = __GET_XEN_INIT_PTR(ptr);
   2.444 -  }
   2.445 -  return retval;
   2.446 -}
   2.447 -
   2.448 -typedef BOOLEAN
   2.449 -(*PXEN_DMA_NEED_VIRTUAL_ADDRESS)(PIRP irp);
   2.450 -
   2.451 -typedef ULONG
   2.452 -(*PXEN_DMA_GET_ALIGNMENT)(PIRP irp);
   2.453 -
   2.454 -typedef struct {
   2.455 -  PXEN_DMA_NEED_VIRTUAL_ADDRESS need_virtual_address;
   2.456 -  PXEN_DMA_GET_ALIGNMENT get_alignment;
   2.457 -} dma_driver_extension_t;
   2.458 +DEFINE_GUID(GUID_DEVINTERFACE_XENBUS, 0x14ce175a, 0x3ee2, 0x4fae, 0x92, 0x52, 0x0, 0xdb, 0xd8, 0x4f, 0x1, 0x8e);
   2.459  
   2.460  
   2.461  #endif
     3.1 --- a/common/include/xen_windows.h	Tue Jan 27 00:47:02 2009 +1100
     3.2 +++ b/common/include/xen_windows.h	Sat Feb 14 13:35:48 2009 +1100
     3.3 @@ -37,6 +37,9 @@ typedef UINT64 uint64_t;
     3.4  #endif
     3.5  
     3.6  #include <xen.h>
     3.7 +#include <grant_table.h>
     3.8 +#include <event_channel.h>
     3.9 +#include <xen_guids.h>
    3.10  
    3.11  #define _PAGE_PRESENT  0x001UL
    3.12  #define _PAGE_RW       0x002UL
    3.13 @@ -61,17 +64,6 @@ typedef unsigned long xenbus_transaction
    3.14  
    3.15  #define wmb() KeMemoryBarrier()
    3.16  #define mb() KeMemoryBarrier()
    3.17 -#define FUNCTION_ENTER()       XenDbgPrint(__DRIVER_NAME " --> %s\n", __FUNCTION__)
    3.18 -#define FUNCTION_EXIT()        XenDbgPrint(__DRIVER_NAME " <-- %s\n", __FUNCTION__)
    3.19 -#define FUNCTION_EXIT_STATUS(_status) XenDbgPrint(__DRIVER_NAME " <-- %s, status = %08x\n", __FUNCTION__, _status)
    3.20 -#define FUNCTION_ERROR_EXIT()  XenDbgPrint(__DRIVER_NAME " <-- %s (error path)\n", __FUNCTION__)
    3.21 -#define FUNCTION_CALLED()      XenDbgPrint(__DRIVER_NAME " %s called (line %d)\n", __FUNCTION__, __LINE__)
    3.22 -#ifdef __MINGW32__
    3.23 -#define FUNCTION_MSG(_x) _FUNCTION_MSG _x
    3.24 -#define _FUNCTION_MSG(format, args...) XenDbgPrint(__DRIVER_NAME " %s called: " format, __FUNCTION__, ##args)
    3.25 -#else
    3.26 -#define FUNCTION_MSG(format, ...)     XenDbgPrint(__DRIVER_NAME "     " format, __VA_ARGS__);
    3.27 -#endif
    3.28  
    3.29  static __inline char **
    3.30  SplitString(char *String, char Split, int MaxParts, int *Count)
    3.31 @@ -251,9 +243,499 @@ static void XenDbgPrint(PCHAR format, ..
    3.32    }
    3.33  }
    3.34  
    3.35 +static VOID
    3.36 +XenRtlAssert(PCHAR expr, PCHAR filename, ULONG line_number)
    3.37 +{
    3.38 +  XenDbgPrint("Failed ASSERTion '%s' at %s:%d\n", expr, filename, line_number);
    3.39 +  RtlAssert(expr, filename, line_number, NULL);
    3.40 +}
    3.41 +
    3.42 +
    3.43 +#if 1
    3.44  #ifdef KdPrint
    3.45    #undef KdPrint
    3.46  #endif
    3.47  #define KdPrint(_x_) XenDbgPrint _x_
    3.48 +#endif
    3.49 +
    3.50 +#ifdef ASSERT
    3.51 +  #undef ASSERT
    3.52 +#endif
    3.53 +#define ASSERT( exp ) ((!(exp)) ? (XenRtlAssert( #exp, __FILE__, __LINE__), FALSE) : TRUE)
    3.54 +
    3.55 +#define FUNCTION_ENTER()       XenDbgPrint(__DRIVER_NAME " --> %s\n", __FUNCTION__)
    3.56 +#define FUNCTION_EXIT()        XenDbgPrint(__DRIVER_NAME " <-- %s\n", __FUNCTION__)
    3.57 +#define FUNCTION_EXIT_STATUS(_status) XenDbgPrint(__DRIVER_NAME " <-- %s, status = %08x\n", __FUNCTION__, _status)
    3.58 +#define FUNCTION_ERROR_EXIT()  XenDbgPrint(__DRIVER_NAME " <-- %s (error path)\n", __FUNCTION__)
    3.59 +#define FUNCTION_CALLED()      XenDbgPrint(__DRIVER_NAME " %s called (line %d)\n", __FUNCTION__, __LINE__)
    3.60 +#ifdef __MINGW32__
    3.61 +#define FUNCTION_MSG(_x) _FUNCTION_MSG _x
    3.62 +#define _FUNCTION_MSG(format, args...) XenDbgPrint(__DRIVER_NAME " %s called: " format, __FUNCTION__, ##args)
    3.63 +#else
    3.64 +#define FUNCTION_MSG(format, ...) XenDbgPrint(__DRIVER_NAME "     " format, __VA_ARGS__)
    3.65 +#endif
    3.66 +
    3.67 +#define INVALID_GRANT_REF 0xFFFFFFFF
    3.68 +
    3.69 +typedef PHYSICAL_ADDRESS
    3.70 +(*PXEN_ALLOCMMIO)(PVOID Context, ULONG Length);
    3.71 +
    3.72 +typedef void
    3.73 +(*PXEN_FREEMEM)(PVOID Ptr);
    3.74 +
    3.75 +typedef VOID
    3.76 +(*PXEN_EVTCHN_SERVICE_ROUTINE)(PVOID Context);
    3.77 +
    3.78 +typedef NTSTATUS
    3.79 +(*PXEN_EVTCHN_BIND)(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
    3.80 +
    3.81 +typedef NTSTATUS
    3.82 +(*PXEN_EVTCHN_UNBIND)(PVOID Context, evtchn_port_t Port);
    3.83 +
    3.84 +typedef NTSTATUS
    3.85 +(*PXEN_EVTCHN_MASK)(PVOID Context, evtchn_port_t Port);
    3.86 +
    3.87 +typedef NTSTATUS
    3.88 +(*PXEN_EVTCHN_UNMASK)(PVOID Context, evtchn_port_t Port);
    3.89 +
    3.90 +typedef NTSTATUS
    3.91 +(*PXEN_EVTCHN_NOTIFY)(PVOID Context, evtchn_port_t Port);
    3.92 +
    3.93 +typedef evtchn_port_t
    3.94 +(*PXEN_EVTCHN_ALLOCUNBOUND)(PVOID Context, domid_t Domain);
    3.95 +
    3.96 +typedef BOOLEAN
    3.97 +(*PXEN_EVTCHN_ACK_EVENT)(PVOID context, evtchn_port_t port);
    3.98 +
    3.99 +typedef BOOLEAN
   3.100 +(*PXEN_EVTCHN_SYNC_ROUTINE)(PVOID sync_context);
   3.101 +
   3.102 +typedef BOOLEAN
   3.103 +(*PXEN_EVTCHN_SYNC)(PVOID Context, PXEN_EVTCHN_SYNC_ROUTINE sync_routine, PVOID sync_context);
   3.104 +
   3.105 +typedef grant_ref_t
   3.106 +(*PXEN_GNTTBL_GRANTACCESS)(PVOID Context, domid_t domid, uint32_t frame, int readonly, grant_ref_t ref);
   3.107 +
   3.108 +typedef BOOLEAN
   3.109 +(*PXEN_GNTTBL_ENDACCESS)(PVOID Context, grant_ref_t ref, BOOLEAN keepref);
   3.110 +
   3.111 +typedef VOID
   3.112 +(*PXEN_GNTTBL_PUTREF)(PVOID Context, grant_ref_t ref);
   3.113 +
   3.114 +typedef grant_ref_t
   3.115 +(*PXEN_GNTTBL_GETREF)(PVOID Context);
   3.116 +
   3.117 +
   3.118 +typedef VOID
   3.119 +(*PXENBUS_WATCH_CALLBACK)(char *Path, PVOID ServiceContext);
   3.120 +
   3.121 +typedef char *
   3.122 +(*PXEN_XENBUS_READ)(PVOID Context, xenbus_transaction_t xbt, char *path, char **value);
   3.123 +
   3.124 +typedef char *
   3.125 +(*PXEN_XENBUS_WRITE)(PVOID Context, xenbus_transaction_t xbt, char *path, char *value);
   3.126 +
   3.127 +typedef char *
   3.128 +(*PXEN_XENBUS_PRINTF)(PVOID Context, xenbus_transaction_t xbt, char *path, char *fmt, ...);
   3.129 +
   3.130 +typedef char *
   3.131 +(*PXEN_XENBUS_STARTTRANSACTION)(PVOID Context, xenbus_transaction_t *xbt);
   3.132 +
   3.133 +typedef char *
   3.134 +(*PXEN_XENBUS_ENDTRANSACTION)(PVOID Context, xenbus_transaction_t t, int abort, int *retry);
   3.135 +
   3.136 +typedef char *
   3.137 +(*PXEN_XENBUS_LIST)(PVOID Context, xenbus_transaction_t xbt, char *prefix, char ***contents);
   3.138 +
   3.139 +typedef char *
   3.140 +(*PXEN_XENBUS_ADDWATCH)(PVOID Context, xenbus_transaction_t xbt, char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
   3.141 +
   3.142 +typedef char *
   3.143 +(*PXEN_XENBUS_REMWATCH)(PVOID Context, xenbus_transaction_t xbt, char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
   3.144 +
   3.145 +typedef NTSTATUS
   3.146 +(*PXEN_XENPCI_XEN_CONFIG_DEVICE)(PVOID Context);
   3.147 +
   3.148 +typedef NTSTATUS
   3.149 +(*PXEN_XENPCI_XEN_SHUTDOWN_DEVICE)(PVOID Context);
   3.150 +
   3.151 +#ifndef XENPCI_POOL_TAG
   3.152 +#define XENPCI_POOL_TAG (ULONG) 'XenP'
   3.153 +#endif
   3.154 +
   3.155 +static __inline VOID
   3.156 +XenPci_FreeMem(PVOID Ptr)
   3.157 +{
   3.158 +  ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
   3.159 +}
   3.160 +
   3.161 +#define XEN_DATA_MAGIC 0x12345678
   3.162 +
   3.163 +typedef struct {
   3.164 +  ULONG magic;
   3.165 +  USHORT length;
   3.166 +
   3.167 +  PVOID context;
   3.168 +  PXEN_EVTCHN_BIND EvtChn_Bind;
   3.169 +  PXEN_EVTCHN_BIND EvtChn_BindDpc;
   3.170 +  PXEN_EVTCHN_UNBIND EvtChn_Unbind;
   3.171 +  PXEN_EVTCHN_MASK EvtChn_Mask;
   3.172 +  PXEN_EVTCHN_UNMASK EvtChn_Unmask;
   3.173 +  PXEN_EVTCHN_NOTIFY EvtChn_Notify;
   3.174 +  PXEN_EVTCHN_ACK_EVENT EvtChn_AckEvent;
   3.175 +  PXEN_EVTCHN_SYNC EvtChn_Sync;
   3.176 +
   3.177 +  PXEN_GNTTBL_GETREF GntTbl_GetRef;
   3.178 +  PXEN_GNTTBL_PUTREF GntTbl_PutRef;
   3.179 +  PXEN_GNTTBL_GRANTACCESS GntTbl_GrantAccess;
   3.180 +  PXEN_GNTTBL_ENDACCESS GntTbl_EndAccess;
   3.181 +
   3.182 +  PXEN_XENPCI_XEN_CONFIG_DEVICE XenPci_XenConfigDevice;
   3.183 +  PXEN_XENPCI_XEN_SHUTDOWN_DEVICE XenPci_XenShutdownDevice;
   3.184 +
   3.185 +  CHAR path[128];
   3.186 +  CHAR backend_path[128];
   3.187 +
   3.188 +  //evtchn_port_t pdo_event_channel;
   3.189 +
   3.190 +  PXEN_XENBUS_READ XenBus_Read;
   3.191 +  PXEN_XENBUS_WRITE XenBus_Write;
   3.192 +  PXEN_XENBUS_PRINTF XenBus_Printf;
   3.193 +  PXEN_XENBUS_STARTTRANSACTION XenBus_StartTransaction;
   3.194 +  PXEN_XENBUS_ENDTRANSACTION XenBus_EndTransaction;
   3.195 +  PXEN_XENBUS_LIST XenBus_List;
   3.196 +  PXEN_XENBUS_ADDWATCH XenBus_AddWatch;
   3.197 +  PXEN_XENBUS_REMWATCH XenBus_RemWatch;
   3.198 +
   3.199 +} XENPCI_VECTORS, *PXENPCI_VECTORS;
   3.200 +
   3.201 +/*
   3.202 +suspend_resume_state_xxx values
   3.203 +pdo will assert a value, and fdo will assert when complete
   3.204 +*/
   3.205 +#define SR_STATE_RUNNING            0 /* normal working state */
   3.206 +#define SR_STATE_SUSPENDING         1 /* suspend has started */
   3.207 +#define SR_STATE_RESUMING           2 /* resume has started */
   3.208 +
   3.209 +#define XEN_DEVICE_STATE_MAGIC ((ULONG)'XDST')
   3.210 +
   3.211 +typedef struct {
   3.212 +  ULONG magic;
   3.213 +  USHORT length;
   3.214 +
   3.215 +  ULONG suspend_resume_state_pdo; /* only the PDO can touch this */
   3.216 +  ULONG suspend_resume_state_fdo; /* only the FDO can touch this */
   3.217 +  evtchn_port_t pdo_event_channel;
   3.218 +} XENPCI_DEVICE_STATE, *PXENPCI_DEVICE_STATE;
   3.219 +
   3.220 +#define XEN_INIT_DRIVER_EXTENSION_MAGIC ((ULONG)'XCFG')
   3.221 +#define XEN_DMA_DRIVER_EXTENSION_MAGIC ((ULONG)'XDMA')
   3.222 +
   3.223 +#define XEN_INIT_TYPE_END                       0
   3.224 +#define XEN_INIT_TYPE_WRITE_STRING              1
   3.225 +#define XEN_INIT_TYPE_RING                      2
   3.226 +#define XEN_INIT_TYPE_EVENT_CHANNEL             3
   3.227 +#define XEN_INIT_TYPE_EVENT_CHANNEL_IRQ         4
   3.228 +#define XEN_INIT_TYPE_READ_STRING_FRONT         5
   3.229 +#define XEN_INIT_TYPE_READ_STRING_BACK          6
   3.230 +#define XEN_INIT_TYPE_VECTORS                   7
   3.231 +#define XEN_INIT_TYPE_GRANT_ENTRIES             8
   3.232 +//#define XEN_INIT_TYPE_COPY_PTR                  9
   3.233 +#define XEN_INIT_TYPE_RUN                       10
   3.234 +#define XEN_INIT_TYPE_STATE_PTR                 11
   3.235 +#define XEN_INIT_TYPE_ACTIVE                    12
   3.236 +#define XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION     13
   3.237 +
   3.238 +static __inline VOID
   3.239 +__ADD_XEN_INIT_UCHAR(PUCHAR *ptr, UCHAR val)
   3.240 +{
   3.241 +//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_UCHAR *ptr = %p, val = %d\n", *ptr, val));
   3.242 +  *(PUCHAR)(*ptr) = val;
   3.243 +  *ptr += sizeof(UCHAR);
   3.244 +}
   3.245 +
   3.246 +static __inline VOID
   3.247 +__ADD_XEN_INIT_USHORT(PUCHAR *ptr, USHORT val)
   3.248 +{
   3.249 +//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_USHORT *ptr = %p, val = %d\n", *ptr, val));
   3.250 +  *(PUSHORT)(*ptr) = val;
   3.251 +  *ptr += sizeof(USHORT);
   3.252 +}
   3.253 +
   3.254 +static __inline VOID
   3.255 +__ADD_XEN_INIT_ULONG(PUCHAR *ptr, ULONG val)
   3.256 +{
   3.257 +//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_ULONG *ptr = %p, val = %d\n", *ptr, val));
   3.258 +  *(PULONG)(*ptr) = val;
   3.259 +  *ptr += sizeof(ULONG);
   3.260 +}
   3.261 +
   3.262 +static __inline VOID
   3.263 +__ADD_XEN_INIT_PTR(PUCHAR *ptr, PVOID val)
   3.264 +{
   3.265 +//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_PTR *ptr = %p, val = %p\n", *ptr, val));
   3.266 +  *(PVOID *)(*ptr) = val;
   3.267 +  *ptr += sizeof(PVOID);
   3.268 +}
   3.269 +
   3.270 +static __inline VOID
   3.271 +__ADD_XEN_INIT_STRING(PUCHAR *ptr, PCHAR val)
   3.272 +{
   3.273 +//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_STRING *ptr = %p, val = %s\n", *ptr, val));
   3.274 +  RtlStringCbCopyA((PCHAR)*ptr, PAGE_SIZE - (PtrToUlong(*ptr) & (PAGE_SIZE - 1)), val);
   3.275 +  *ptr += strlen(val) + 1;
   3.276 +}
   3.277 +
   3.278 +static __inline UCHAR
   3.279 +__GET_XEN_INIT_UCHAR(PUCHAR *ptr)
   3.280 +{
   3.281 +  UCHAR retval;
   3.282 +  retval = **ptr;
   3.283 +//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_UCHAR *ptr = %p, retval = %d\n", *ptr, retval));
   3.284 +  *ptr += sizeof(UCHAR);
   3.285 +  return retval;
   3.286 +}
   3.287 +
   3.288 +static __inline USHORT
   3.289 +__GET_XEN_INIT_USHORT(PUCHAR *ptr)
   3.290 +{
   3.291 +  USHORT retval;
   3.292 +  retval = *(PUSHORT)*ptr;
   3.293 +//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_USHORT *ptr = %p, retval = %d\n", *ptr, retval));
   3.294 +  *ptr += sizeof(USHORT);
   3.295 +  return retval;
   3.296 +}
   3.297 +
   3.298 +static __inline ULONG
   3.299 +__GET_XEN_INIT_ULONG(PUCHAR *ptr)
   3.300 +{
   3.301 +  ULONG retval;
   3.302 +  retval = *(PLONG)*ptr;
   3.303 +//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_ULONG *ptr = %p, retval = %d\n", *ptr, retval));
   3.304 +  *ptr += sizeof(ULONG);
   3.305 +  return retval;
   3.306 +}
   3.307 +
   3.308 +static __inline PCHAR
   3.309 +__GET_XEN_INIT_STRING(PUCHAR *ptr)
   3.310 +{
   3.311 +  PCHAR retval;
   3.312 +  retval = (PCHAR)*ptr;
   3.313 +//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_STRING *ptr = %p, retval = %s\n", *ptr, retval));
   3.314 +  *ptr += strlen((PCHAR)*ptr) + 1;
   3.315 +  return retval;
   3.316 +}
   3.317 +
   3.318 +static __inline PVOID
   3.319 +__GET_XEN_INIT_PTR(PUCHAR *ptr)
   3.320 +{
   3.321 +  PVOID retval;
   3.322 +  retval = *(PVOID *)(*ptr);
   3.323 +//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_PTR *ptr = %p, retval = %p\n", *ptr, retval));
   3.324 +  *ptr += sizeof(PVOID);
   3.325 +  return retval;
   3.326 +}
   3.327 +
   3.328 +static __inline VOID
   3.329 +ADD_XEN_INIT_REQ(PUCHAR *ptr, UCHAR type, PVOID p1, PVOID p2, PVOID p3)
   3.330 +{
   3.331 +  __ADD_XEN_INIT_UCHAR(ptr, type);
   3.332 +  switch (type)
   3.333 +  {
   3.334 +  case XEN_INIT_TYPE_END:
   3.335 +  case XEN_INIT_TYPE_VECTORS:
   3.336 +  case XEN_INIT_TYPE_RUN:
   3.337 +  case XEN_INIT_TYPE_STATE_PTR:
   3.338 +  case XEN_INIT_TYPE_ACTIVE:
   3.339 +  case XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION:
   3.340 +    break;
   3.341 +  case XEN_INIT_TYPE_WRITE_STRING:
   3.342 +    __ADD_XEN_INIT_STRING(ptr, (PCHAR) p1);
   3.343 +    __ADD_XEN_INIT_STRING(ptr, (PCHAR) p2);
   3.344 +    break;
   3.345 +  case XEN_INIT_TYPE_RING:
   3.346 +  case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ:
   3.347 +  case XEN_INIT_TYPE_READ_STRING_FRONT:
   3.348 +  case XEN_INIT_TYPE_READ_STRING_BACK:
   3.349 +    __ADD_XEN_INIT_STRING(ptr, (PCHAR) p1);
   3.350 +    break;
   3.351 +  case XEN_INIT_TYPE_EVENT_CHANNEL:
   3.352 +    __ADD_XEN_INIT_STRING(ptr, (PCHAR) p1);
   3.353 +    __ADD_XEN_INIT_PTR(ptr, p2);
   3.354 +    __ADD_XEN_INIT_PTR(ptr, p3);
   3.355 +    break;
   3.356 +  case XEN_INIT_TYPE_GRANT_ENTRIES:
   3.357 +    __ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p2));
   3.358 +    break;
   3.359 +//  case XEN_INIT_TYPE_COPY_PTR:
   3.360 +//    __ADD_XEN_INIT_STRING(ptr, p1);
   3.361 +//    __ADD_XEN_INIT_PTR(ptr, p2);
   3.362 +//    break;
   3.363 +  }
   3.364 +}
   3.365 +
   3.366 +static __inline UCHAR
   3.367 +GET_XEN_INIT_REQ(PUCHAR *ptr, PVOID *p1, PVOID *p2, PVOID *p3)
   3.368 +{
   3.369 +  UCHAR retval;
   3.370 +
   3.371 +  retval = __GET_XEN_INIT_UCHAR(ptr);
   3.372 +  switch (retval)
   3.373 +  {
   3.374 +  case XEN_INIT_TYPE_END:
   3.375 +  case XEN_INIT_TYPE_VECTORS:
   3.376 +  case XEN_INIT_TYPE_RUN:
   3.377 +  case XEN_INIT_TYPE_STATE_PTR:
   3.378 +  case XEN_INIT_TYPE_ACTIVE:
   3.379 +  case XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION:
   3.380 +    *p1 = NULL;
   3.381 +    *p2 = NULL;
   3.382 +    break;
   3.383 +  case XEN_INIT_TYPE_WRITE_STRING:
   3.384 +    *p1 = __GET_XEN_INIT_STRING(ptr);
   3.385 +    *p2 = __GET_XEN_INIT_STRING(ptr);
   3.386 +    break;
   3.387 +  case XEN_INIT_TYPE_RING:
   3.388 +  case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ:
   3.389 +  case XEN_INIT_TYPE_READ_STRING_FRONT:
   3.390 +  case XEN_INIT_TYPE_READ_STRING_BACK:
   3.391 +    *p1 = __GET_XEN_INIT_STRING(ptr);
   3.392 +    *p2 = NULL;
   3.393 +    break;
   3.394 +  case XEN_INIT_TYPE_EVENT_CHANNEL:
   3.395 +    *p1 = __GET_XEN_INIT_STRING(ptr);
   3.396 +    *p2 = __GET_XEN_INIT_PTR(ptr);
   3.397 +    *p3 = __GET_XEN_INIT_PTR(ptr);
   3.398 +    break;
   3.399 +  case XEN_INIT_TYPE_GRANT_ENTRIES:
   3.400 +    *p2 = UlongToPtr(__GET_XEN_INIT_ULONG(ptr));
   3.401 +    break;
   3.402 +//  case XEN_INIT_TYPE_COPY_PTR:
   3.403 +//    *p1 = __GET_XEN_INIT_STRING(ptr);
   3.404 +//    *p2 = __GET_XEN_INIT_PTR(ptr);
   3.405 +//    break;
   3.406 +  }
   3.407 +  return retval;
   3.408 +}
   3.409 +
   3.410 +static __inline VOID
   3.411 +ADD_XEN_INIT_RSP(PUCHAR *ptr, UCHAR type, PVOID p1, PVOID p2, PVOID p3)
   3.412 +{
   3.413 +  UNREFERENCED_PARAMETER(p3);
   3.414 +
   3.415 +  __ADD_XEN_INIT_UCHAR(ptr, type);
   3.416 +  switch (type)
   3.417 +  {
   3.418 +  case XEN_INIT_TYPE_END:
   3.419 +  case XEN_INIT_TYPE_WRITE_STRING: /* this shouldn't happen */
   3.420 +  case XEN_INIT_TYPE_RUN:
   3.421 +  case XEN_INIT_TYPE_ACTIVE:
   3.422 +    break;
   3.423 +  case XEN_INIT_TYPE_RING:
   3.424 +    __ADD_XEN_INIT_STRING(ptr, (PCHAR) p1);
   3.425 +    __ADD_XEN_INIT_PTR(ptr, p2);
   3.426 +    break;
   3.427 +  case XEN_INIT_TYPE_EVENT_CHANNEL:
   3.428 +  case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ:
   3.429 +    __ADD_XEN_INIT_STRING(ptr, (PCHAR) p1);
   3.430 +    __ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p2));
   3.431 +    break;
   3.432 +  case XEN_INIT_TYPE_READ_STRING_FRONT:
   3.433 +  case XEN_INIT_TYPE_READ_STRING_BACK:
   3.434 +    __ADD_XEN_INIT_STRING(ptr, (PCHAR) p1);
   3.435 +    __ADD_XEN_INIT_STRING(ptr, (PCHAR) p2);
   3.436 +    break;
   3.437 +  case XEN_INIT_TYPE_VECTORS:
   3.438 +    //__ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p1));
   3.439 +    memcpy(*ptr, p2, sizeof(XENPCI_VECTORS));
   3.440 +    *ptr += sizeof(XENPCI_VECTORS);
   3.441 +    break;
   3.442 +  case XEN_INIT_TYPE_GRANT_ENTRIES:
   3.443 +    __ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p1));
   3.444 +    memcpy(*ptr, p2, PtrToUlong(p1) * sizeof(grant_entry_t));
   3.445 +    *ptr += PtrToUlong(p1) * sizeof(grant_entry_t);
   3.446 +    break;
   3.447 +  case XEN_INIT_TYPE_STATE_PTR:
   3.448 +    __ADD_XEN_INIT_PTR(ptr, p2);
   3.449 +    break;
   3.450 +  case XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION:
   3.451 +    __ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p2));
   3.452 +    break;
   3.453 +//  case XEN_INIT_TYPE_COPY_PTR:
   3.454 +//    __ADD_XEN_INIT_STRING(ptr, p1);
   3.455 +//    __ADD_XEN_INIT_PTR(ptr, p2);
   3.456 +//    break;
   3.457 +  }
   3.458 +}
   3.459 +
   3.460 +static __inline UCHAR
   3.461 +GET_XEN_INIT_RSP(PUCHAR *ptr, PVOID *p1, PVOID *p2, PVOID *p3)
   3.462 +{
   3.463 +  UCHAR retval;
   3.464 +
   3.465 +  UNREFERENCED_PARAMETER(p3);
   3.466 +
   3.467 +  retval = __GET_XEN_INIT_UCHAR(ptr);
   3.468 +  switch (retval)
   3.469 +  {
   3.470 +  case XEN_INIT_TYPE_END:
   3.471 +  case XEN_INIT_TYPE_RUN:
   3.472 +  case XEN_INIT_TYPE_ACTIVE:
   3.473 +    *p1 = NULL;
   3.474 +    *p2 = NULL;
   3.475 +    break;
   3.476 +  case XEN_INIT_TYPE_WRITE_STRING:
   3.477 +    // this shouldn't happen - no response here
   3.478 +    break;
   3.479 +  case XEN_INIT_TYPE_RING:
   3.480 +    *p1 = __GET_XEN_INIT_STRING(ptr);
   3.481 +    *p2 = __GET_XEN_INIT_PTR(ptr);
   3.482 +    break;
   3.483 +  case XEN_INIT_TYPE_EVENT_CHANNEL:
   3.484 +  case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ:
   3.485 +    *p1 = __GET_XEN_INIT_STRING(ptr);
   3.486 +    *p2 = UlongToPtr(__GET_XEN_INIT_ULONG(ptr));
   3.487 +    break;
   3.488 +  case XEN_INIT_TYPE_READ_STRING_FRONT:
   3.489 +    *p1 = __GET_XEN_INIT_STRING(ptr);
   3.490 +    *p2 = __GET_XEN_INIT_STRING(ptr);
   3.491 +    break;
   3.492 +  case XEN_INIT_TYPE_READ_STRING_BACK:
   3.493 +    *p1 = __GET_XEN_INIT_STRING(ptr);
   3.494 +    *p2 = __GET_XEN_INIT_STRING(ptr);
   3.495 +    break;
   3.496 +  case XEN_INIT_TYPE_VECTORS:
   3.497 +    *p1 = NULL;
   3.498 +    *p2 = *ptr;
   3.499 +    *ptr += ((PXENPCI_VECTORS)*p2)->length;
   3.500 +    break;
   3.501 +  case XEN_INIT_TYPE_GRANT_ENTRIES:
   3.502 +    *p1 = UlongToPtr(__GET_XEN_INIT_ULONG(ptr));
   3.503 +    *p2 = *ptr;
   3.504 +    *ptr += PtrToUlong(*p1) * sizeof(grant_ref_t);
   3.505 +    break;
   3.506 +  case XEN_INIT_TYPE_STATE_PTR:
   3.507 +    *p2 = __GET_XEN_INIT_PTR(ptr);
   3.508 +    break;
   3.509 +  case XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION:
   3.510 +    *p2 = UlongToPtr(__GET_XEN_INIT_ULONG(ptr));
   3.511 +    break;
   3.512 +//  case XEN_INIT_TYPE_COPY_PTR:
   3.513 +//    *p1 = __GET_XEN_INIT_STRING(ptr);
   3.514 +//    *p2 = __GET_XEN_INIT_PTR(ptr);
   3.515 +  }
   3.516 +  return retval;
   3.517 +}
   3.518 +
   3.519 +typedef BOOLEAN
   3.520 +(*PXEN_DMA_NEED_VIRTUAL_ADDRESS)(PIRP irp);
   3.521 +
   3.522 +typedef ULONG
   3.523 +(*PXEN_DMA_GET_ALIGNMENT)(PIRP irp);
   3.524 +
   3.525 +typedef struct {
   3.526 +  PXEN_DMA_NEED_VIRTUAL_ADDRESS need_virtual_address;
   3.527 +  PXEN_DMA_GET_ALIGNMENT get_alignment;
   3.528 +} dma_driver_extension_t;
   3.529  
   3.530  #endif
     4.1 --- a/shutdownmon/shutdownmon.c	Tue Jan 27 00:47:02 2009 +1100
     4.2 +++ b/shutdownmon/shutdownmon.c	Sat Feb 14 13:35:48 2009 +1100
     4.3 @@ -15,9 +15,41 @@
     4.4  
     4.5  #define OLD_SERVICE_ID "XenShutdownMon"
     4.6  
     4.7 -DEFINE_GUID(GUID_XEN_IFACE, 0x5C568AC5, 0x9DDF, 0x4FA5, 0xA9, 0x4A, 0x39, 0xD6, 0x70, 0x77, 0x81, 0x9C);
     4.8 +DEFINE_GUID(GUID_XENBUS_IFACE, 0x14ce175a, 0x3ee2, 0x4fae, 0x92, 0x52, 0x0, 0xdb, 0xd8, 0x4f, 0x1, 0x8e);
     4.9  
    4.10 +enum xsd_sockmsg_type
    4.11 +{
    4.12 +    XS_DEBUG,
    4.13 +    XS_DIRECTORY,
    4.14 +    XS_READ,
    4.15 +    XS_GET_PERMS,
    4.16 +    XS_WATCH,
    4.17 +    XS_UNWATCH,
    4.18 +    XS_TRANSACTION_START,
    4.19 +    XS_TRANSACTION_END,
    4.20 +    XS_INTRODUCE,
    4.21 +    XS_RELEASE,
    4.22 +    XS_GET_DOMAIN_PATH,
    4.23 +    XS_WRITE,
    4.24 +    XS_MKDIR,
    4.25 +    XS_RM,
    4.26 +    XS_SET_PERMS,
    4.27 +    XS_WATCH_EVENT,
    4.28 +    XS_ERROR,
    4.29 +    XS_IS_DOMAIN_INTRODUCED,
    4.30 +    XS_RESUME,
    4.31 +    XS_SET_TARGET
    4.32 +};
    4.33  
    4.34 +struct xsd_sockmsg
    4.35 +{
    4.36 +    ULONG type;  /* XS_??? */
    4.37 +    ULONG req_id;/* Request identifier, echoed in daemon's response.  */
    4.38 +    ULONG tx_id; /* Transaction id (0 if not related to a transaction). */
    4.39 +    ULONG len;   /* Length of data following this. */
    4.40 +
    4.41 +    /* Generally followed by nul-terminated string(s). */
    4.42 +};
    4.43  SERVICE_STATUS service_status; 
    4.44  SERVICE_STATUS_HANDLE hStatus; 
    4.45  
    4.46 @@ -42,7 +74,7 @@ install_service()
    4.47    TCHAR path[MAX_PATH];
    4.48    TCHAR command_line[MAX_PATH + 10];
    4.49  
    4.50 -  if( !GetModuleFileName( NULL, path, MAX_PATH ) )
    4.51 +  if(!GetModuleFileName(NULL, path, MAX_PATH))
    4.52    {
    4.53      printf("Cannot install service (%d)\n", GetLastError());
    4.54      return;
    4.55 @@ -189,14 +221,14 @@ get_xen_interface_path()
    4.56    DWORD buf_len;
    4.57    char *path;
    4.58  
    4.59 -  handle = SetupDiGetClassDevs(&GUID_XEN_IFACE, 0, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    4.60 +  handle = SetupDiGetClassDevs(&GUID_XENBUS_IFACE, 0, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    4.61    if (handle == INVALID_HANDLE_VALUE)
    4.62    {
    4.63      write_log("SetupDiGetClassDevs failed\n"); 
    4.64      return NULL;
    4.65    }
    4.66    sdid.cbSize = sizeof(sdid);
    4.67 -  if (!SetupDiEnumDeviceInterfaces(handle, NULL, &GUID_XEN_IFACE, 0, &sdid))
    4.68 +  if (!SetupDiEnumDeviceInterfaces(handle, NULL, &GUID_XENBUS_IFACE, 0, &sdid))
    4.69    {
    4.70      write_log("SetupDiEnumDeviceInterfaces failed\n");
    4.71      return NULL;
    4.72 @@ -217,70 +249,129 @@ get_xen_interface_path()
    4.73    return path;
    4.74  }
    4.75  
    4.76 +static int
    4.77 +xb_add_watch(HANDLE handle, char *path)
    4.78 +{
    4.79 +  char buf[1024];
    4.80 +  struct xsd_sockmsg *msg;
    4.81 +  DWORD bytes_written;
    4.82 +  DWORD bytes_read;
    4.83 +  char *token = "0";
    4.84 +
    4.85 +  msg = (struct xsd_sockmsg *)buf;
    4.86 +  msg->type = XS_WATCH;
    4.87 +  msg->req_id = 0;
    4.88 +  msg->tx_id = 0;
    4.89 +  msg->len = strlen(path) + 1 + strlen(token) + 1;
    4.90 +  strcpy(buf + sizeof(*msg), path);
    4.91 +  strcpy(buf + sizeof(*msg) + strlen(path) + 1, token);
    4.92 +
    4.93 +  if (!WriteFile(handle, buf, sizeof(*msg) + msg->len, &bytes_written, NULL))
    4.94 +  {
    4.95 +    printf("write failed\n");
    4.96 +    return 0;
    4.97 +  }
    4.98 +  if (!ReadFile(handle, buf, 1024, &bytes_read, NULL))
    4.99 +  {
   4.100 +    printf("read failed\n");
   4.101 +    return 0;
   4.102 +  }
   4.103 +  printf("bytes_read = %d\n", bytes_read);
   4.104 +  printf("msg->len = %d\n", msg->len);
   4.105 +  buf[sizeof(*msg) + msg->len] = 0;
   4.106 +  printf("msg text = %s\n", buf + sizeof(*msg));
   4.107 +
   4.108 +  return 1;
   4.109 +}
   4.110 +
   4.111 +static int
   4.112 +xb_wait_event(HANDLE handle)
   4.113 +{
   4.114 +  char buf[1024];
   4.115 +  struct xsd_sockmsg *msg;
   4.116 +  DWORD bytes_read;
   4.117 +
   4.118 +printf("wait_event start\n");
   4.119 +  msg = (struct xsd_sockmsg *)buf;
   4.120 +  if (!ReadFile(handle, buf, 1024, &bytes_read, NULL))
   4.121 +  {
   4.122 +    printf("read failed\n");
   4.123 +    return 0;
   4.124 +  }
   4.125 +  printf("bytes_read = %d\n", bytes_read);
   4.126 +  printf("msg->len = %d\n", msg->len);
   4.127 +  buf[sizeof(*msg) + msg->len] = 0;
   4.128 +  printf("msg text = %s\n", buf + sizeof(*msg));
   4.129 +  return 1;
   4.130 +}
   4.131 +
   4.132 +static char *
   4.133 +xb_read(HANDLE handle, char *path)
   4.134 +{
   4.135 +  char buf[1024];
   4.136 +  struct xsd_sockmsg *msg;
   4.137 +  char *ret;
   4.138 +  DWORD bytes_written;
   4.139 +  DWORD bytes_read;
   4.140 +
   4.141 +printf("read start\n");
   4.142 +  msg = (struct xsd_sockmsg *)buf;
   4.143 +  msg->type = XS_READ;
   4.144 +  msg->req_id = 0;
   4.145 +  msg->tx_id = 0;
   4.146 +  msg->len = strlen(path) + 1;
   4.147 +  strcpy(buf + sizeof(*msg), path);
   4.148 +  if (!WriteFile(handle, buf, sizeof(*msg) + msg->len, &bytes_written, NULL))
   4.149 +  {
   4.150 +    printf("write failed\n");
   4.151 +    return NULL;
   4.152 +  }
   4.153 +
   4.154 +  if (!ReadFile(handle, buf, 1024, &bytes_read, NULL))
   4.155 +  {
   4.156 +    printf("read failed\n");
   4.157 +    return NULL;
   4.158 +  }
   4.159 +  printf("bytes_read = %d\n", bytes_read);
   4.160 +  printf("msg->len = %d\n", msg->len);
   4.161 +  buf[sizeof(*msg) + msg->len] = 0;
   4.162 +  printf("msg text = %s\n", buf + sizeof(*msg));
   4.163 +  ret = malloc(strlen(buf + sizeof(*msg)));
   4.164 +  strcpy(ret, buf + sizeof(*msg));
   4.165 +  return ret;
   4.166 +}
   4.167 +
   4.168  static void
   4.169  do_monitoring()
   4.170  {
   4.171 -  char buf[1024];
   4.172 -  char *bufptr = buf;
   4.173    HANDLE handle;
   4.174    int state;
   4.175    char *path;
   4.176 -  DWORD bytes_read;
   4.177 -  char inchar;
   4.178 +  char *buf;
   4.179  
   4.180    path = get_xen_interface_path();
   4.181    if (path == NULL)
   4.182      return;
   4.183  
   4.184 -  handle = CreateFile(path, FILE_GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
   4.185 +  handle = CreateFile(path, FILE_GENERIC_READ|FILE_GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
   4.186 +
   4.187 +  xb_add_watch(handle, "control/shutdown");
   4.188  
   4.189    state = 0;
   4.190 -  for (;;)
   4.191 +  while(xb_wait_event(handle))
   4.192    {
   4.193      if (service_status.dwCurrentState != SERVICE_RUNNING)
   4.194        return;
   4.195 -    if (!ReadFile(handle, &inchar, 1, &bytes_read, NULL))
   4.196 -    {
   4.197 -      CloseHandle(handle);
   4.198 -      return;
   4.199 -    }
   4.200 -    switch (state)
   4.201 +    buf = xb_read(handle, "control/shutdown");
   4.202 +    //printf("msg = '%s'\n", msg);
   4.203 +    if (strcmp("poweroff", buf) == 0 || strcmp("halt", buf) == 0)
   4.204      {
   4.205 -    case 0:
   4.206 -      if (isalnum(inchar))
   4.207 -      {
   4.208 -        *bufptr = inchar;
   4.209 -        bufptr++;
   4.210 -      }
   4.211 -      else if (inchar == '\r')
   4.212 -      {
   4.213 -        *bufptr = 0;
   4.214 -        state = 1;
   4.215 -      }
   4.216 -      else
   4.217 -      {
   4.218 -        bufptr = buf;
   4.219 -      }
   4.220 -      break;
   4.221 -    case 1:
   4.222 -      if (inchar == '\n')
   4.223 -      {
   4.224 -        if (strcmp("poweroff", buf) == 0 || strcmp("halt", buf) == 0)
   4.225 -        {
   4.226 -          do_shutdown(FALSE);
   4.227 -        }
   4.228 -        else if (strcmp("reboot", buf) == 0)
   4.229 -        {
   4.230 -          do_shutdown(TRUE);
   4.231 -        } 
   4.232 -        else
   4.233 -        {
   4.234 -          // complain here
   4.235 -        }
   4.236 -      }
   4.237 -      state = 0;
   4.238 -      break;
   4.239 +      do_shutdown(FALSE);
   4.240      }
   4.241 +    else if (strcmp("reboot", buf) == 0)
   4.242 +    {
   4.243 +      do_shutdown(TRUE);
   4.244 +    } 
   4.245    }
   4.246  }
   4.247  
     5.1 --- a/xennet/makefile.inc	Tue Jan 27 00:47:02 2009 +1100
     5.2 +++ b/xennet/makefile.inc	Sat Feb 14 13:35:48 2009 +1100
     5.3 @@ -1,6 +1,6 @@
     5.4  _LNG=$(LANGUAGE)
     5.5  STAMP=stampinf -f $@ -a $(_BUILDARCH) -d * -v $(VERSION)
     5.6  
     5.7 -..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf: $(INF_NAME).inx sources ..\common.inc
     5.8 +$(INF_NAME).inf: $(INF_NAME).inx sources ..\common.inc
     5.9      copy $(@B).inx $@
    5.10      $(STAMP)
     6.1 --- a/xennet/sources	Tue Jan 27 00:47:02 2009 +1100
     6.2 +++ b/xennet/sources	Sat Feb 14 13:35:48 2009 +1100
     6.3 @@ -3,5 +3,5 @@ TARGETNAME=xennet
     6.4  TARGETTYPE=DRIVER
     6.5  INF_NAME=$(TARGETNAME)
     6.6  TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\ndis.lib
     6.7 -MISCFILES=..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf
     6.8 +MISCFILES=$(INF_NAME).inf
     6.9  SOURCES=xennet.c xennet_tx.c xennet_rx.c xennet_oid.c xennet_common.c
     7.1 --- a/xennet/xennet.c	Tue Jan 27 00:47:02 2009 +1100
     7.2 +++ b/xennet/xennet.c	Sat Feb 14 13:35:48 2009 +1100
     7.3 @@ -122,18 +122,20 @@ XenNet_ConnectBackend(struct xennet_info
     7.4  {
     7.5    PUCHAR ptr;
     7.6    UCHAR type;
     7.7 -  PCHAR setting, value;
     7.8 +  PCHAR setting, value, value2;
     7.9    UINT i;
    7.10  
    7.11 +  FUNCTION_ENTER();
    7.12 +  
    7.13    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
    7.14  
    7.15    ptr = xi->config_page;
    7.16 -  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value)) != XEN_INIT_TYPE_END)
    7.17 +  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
    7.18    {
    7.19      switch(type)
    7.20      {
    7.21      case XEN_INIT_TYPE_RING: /* frontend ring */
    7.22 -      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
    7.23 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
    7.24        if (strcmp(setting, "tx-ring-ref") == 0)
    7.25        {
    7.26          FRONT_RING_INIT(&xi->tx, (netif_tx_sring_t *)value, PAGE_SIZE);
    7.27 @@ -171,7 +173,7 @@ XenNet_ConnectBackend(struct xennet_info
    7.28        }
    7.29        break;
    7.30      case XEN_INIT_TYPE_VECTORS:
    7.31 -      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
    7.32 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
    7.33        if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
    7.34          ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
    7.35        {
    7.36 @@ -184,7 +186,7 @@ XenNet_ConnectBackend(struct xennet_info
    7.37          memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS));
    7.38        break;
    7.39      case XEN_INIT_TYPE_STATE_PTR:
    7.40 -      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
    7.41 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
    7.42        xi->device_state = (PXENPCI_DEVICE_STATE)value;
    7.43        break;
    7.44      default:
    7.45 @@ -192,6 +194,8 @@ XenNet_ConnectBackend(struct xennet_info
    7.46        break;
    7.47      }
    7.48    }
    7.49 +  FUNCTION_EXIT();
    7.50 +  
    7.51    return NDIS_STATUS_SUCCESS;
    7.52  }
    7.53  
    7.54 @@ -202,12 +206,20 @@ XenNet_Resume(PDEVICE_OBJECT device_obje
    7.55    
    7.56    UNREFERENCED_PARAMETER(device_object);
    7.57    
    7.58 -  XenNet_RxResumeStart(xi);
    7.59 +  FUNCTION_ENTER();
    7.60 +  
    7.61    XenNet_TxResumeStart(xi);
    7.62 +  XenNet_RxResumeStart(xi);
    7.63    XenNet_ConnectBackend(xi);
    7.64 -  xi->device_state->resume_state = RESUME_STATE_RUNNING;
    7.65    XenNet_RxResumeEnd(xi);
    7.66    XenNet_TxResumeEnd(xi);
    7.67 +  KdPrint((__DRIVER_NAME "     *Setting suspend_resume_state_fdo = %d\n", xi->device_state->suspend_resume_state_pdo));
    7.68 +  xi->device_state->suspend_resume_state_fdo = xi->device_state->suspend_resume_state_pdo;
    7.69 +  KdPrint((__DRIVER_NAME "     *Notifying event channel %d\n", xi->device_state->pdo_event_channel));
    7.70 +  xi->vectors.EvtChn_Notify(xi->vectors.context, xi->device_state->pdo_event_channel);
    7.71 +
    7.72 +  FUNCTION_EXIT();
    7.73 +
    7.74  }
    7.75  
    7.76  static VOID
    7.77 @@ -215,6 +227,7 @@ XenNet_SuspendResume(PKDPC dpc, PVOID co
    7.78  {
    7.79    struct xennet_info *xi = context;
    7.80    PIO_WORKITEM work_item;
    7.81 +  KIRQL old_irql;
    7.82  
    7.83    UNREFERENCED_PARAMETER(dpc);
    7.84    UNREFERENCED_PARAMETER(arg1);
    7.85 @@ -222,26 +235,31 @@ XenNet_SuspendResume(PKDPC dpc, PVOID co
    7.86  
    7.87    FUNCTION_ENTER();
    7.88    
    7.89 -  switch (xi->device_state->resume_state)
    7.90 +  switch (xi->device_state->suspend_resume_state_pdo)
    7.91    {
    7.92 -  case RESUME_STATE_SUSPENDING:
    7.93 +  case SR_STATE_SUSPENDING:
    7.94      KdPrint((__DRIVER_NAME "     New state SUSPENDING\n"));
    7.95 -    // there should be a better way to synchronise with rx and tx...
    7.96 -    KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
    7.97 -    KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
    7.98 -    KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
    7.99 -    KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
   7.100 +    KeAcquireSpinLock(&xi->rx_lock, &old_irql);
   7.101 +    if (xi->tx_id_free == NET_TX_RING_SIZE)
   7.102 +    {  
   7.103 +      xi->device_state->suspend_resume_state_fdo = SR_STATE_SUSPENDING;
   7.104 +      KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xi->device_state->pdo_event_channel));
   7.105 +      xi->vectors.EvtChn_Notify(xi->vectors.context, xi->device_state->pdo_event_channel);
   7.106 +    }
   7.107 +    KeReleaseSpinLock(&xi->rx_lock, old_irql);
   7.108      break;
   7.109 -  case RESUME_STATE_FRONTEND_RESUME:
   7.110 -    KdPrint((__DRIVER_NAME "     New state RESUME_STATE_FRONTEND_RESUME\n"));
   7.111 +  case SR_STATE_RESUMING:
   7.112 +    KdPrint((__DRIVER_NAME "     New state SR_STATE_RESUMING\n"));
   7.113      work_item = IoAllocateWorkItem(xi->fdo);
   7.114      IoQueueWorkItem(work_item, XenNet_Resume, DelayedWorkQueue, xi);
   7.115      break;
   7.116    default:
   7.117 -    KdPrint((__DRIVER_NAME "     New state %d\n", xi->device_state->resume_state));
   7.118 +    KdPrint((__DRIVER_NAME "     New state %d\n", xi->device_state->suspend_resume_state_fdo));
   7.119 +    xi->device_state->suspend_resume_state_fdo = xi->device_state->suspend_resume_state_pdo;
   7.120 +    KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xi->device_state->pdo_event_channel));
   7.121 +    xi->vectors.EvtChn_Notify(xi->vectors.context, xi->device_state->pdo_event_channel);
   7.122      break;
   7.123    }
   7.124 -  xi->device_state->resume_state_ack = xi->device_state->resume_state;
   7.125    KeMemoryBarrier();
   7.126    
   7.127    FUNCTION_EXIT();
   7.128 @@ -251,16 +269,21 @@ static DDKAPI BOOLEAN
   7.129  XenNet_HandleEvent(PVOID context)
   7.130  {
   7.131    struct xennet_info *xi = context;
   7.132 +  ULONG suspend_resume_state_pdo;
   7.133    
   7.134    //FUNCTION_ENTER();
   7.135 -  if (xi->device_state->resume_state != xi->device_state->resume_state_ack)
   7.136 +  suspend_resume_state_pdo = xi->device_state->suspend_resume_state_pdo;
   7.137 +  KeMemoryBarrier();
   7.138 +//  KdPrint((__DRIVER_NAME "     connected = %d, inactive = %d, suspend_resume_state_pdo = %d\n",
   7.139 +//    xi->connected, xi->inactive, suspend_resume_state_pdo));
   7.140 +  if (suspend_resume_state_pdo != xi->device_state->suspend_resume_state_fdo)
   7.141    {
   7.142      KeInsertQueueDpc(&xi->suspend_dpc, NULL, NULL);
   7.143    }
   7.144 -  else if (xi->connected && !xi->inactive && xi->device_state->resume_state == RESUME_STATE_RUNNING)
   7.145 +  else if (xi->connected && !xi->inactive && suspend_resume_state_pdo != SR_STATE_RESUMING)
   7.146    {
   7.147      KeInsertQueueDpc(&xi->tx_dpc, NULL, NULL);
   7.148 -    KeInsertQueueDpc(&xi->rx_dpc, UlongToPtr(FALSE), NULL);
   7.149 +    KeInsertQueueDpc(&xi->rx_dpc, NULL, NULL);
   7.150    }
   7.151    //FUNCTION_EXIT();
   7.152    return TRUE;
   7.153 @@ -292,7 +315,7 @@ XenNet_Init(
   7.154    ULONG i;
   7.155    PUCHAR ptr;
   7.156    UCHAR type;
   7.157 -  PCHAR setting, value;
   7.158 +  PCHAR setting, value, value2;
   7.159    ULONG length;
   7.160    CHAR buf[128];
   7.161    PVOID network_address;
   7.162 @@ -410,15 +433,6 @@ XenNet_Init(
   7.163  
   7.164    KeInitializeDpc(&xi->suspend_dpc, XenNet_SuspendResume, xi);
   7.165  
   7.166 -  NdisAllocatePacketPool(&status, &xi->packet_pool, XN_RX_QUEUE_LEN * 8,
   7.167 -    PROTOCOL_RESERVED_SIZE_IN_PACKET);
   7.168 -  if (status != NDIS_STATUS_SUCCESS)
   7.169 -  {
   7.170 -    KdPrint(("NdisAllocatePacketPool failed with 0x%x\n", status));
   7.171 -    status = NDIS_STATUS_RESOURCES;
   7.172 -    goto err;
   7.173 -  }
   7.174 -
   7.175    NdisMGetDeviceProperty(MiniportAdapterHandle, &xi->pdo, &xi->fdo,
   7.176      &xi->lower_do, NULL, NULL);
   7.177    xi->packet_filter = NDIS_PACKET_TYPE_PROMISCUOUS;
   7.178 @@ -433,7 +447,7 @@ XenNet_Init(
   7.179    }
   7.180  
   7.181    ptr = xi->config_page;
   7.182 -  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value)) != XEN_INIT_TYPE_END)
   7.183 +  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value)) != XEN_INIT_TYPE_END)
   7.184    {
   7.185      switch(type)
   7.186      {
   7.187 @@ -455,6 +469,7 @@ XenNet_Init(
   7.188        xi->device_state = (PXENPCI_DEVICE_STATE)value;
   7.189        break;
   7.190      case XEN_INIT_TYPE_ACTIVE:
   7.191 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_ACTIVE\n"));
   7.192        xi->inactive = FALSE;
   7.193        break;
   7.194      default:
   7.195 @@ -462,7 +477,7 @@ XenNet_Init(
   7.196        break;
   7.197      }
   7.198    }
   7.199 -  
   7.200 +
   7.201    // now build config page
   7.202    
   7.203    NdisOpenConfiguration(&status, &config_handle, WrapperConfigurationContext);
   7.204 @@ -577,22 +592,21 @@ XenNet_Init(
   7.205  
   7.206    ptr = xi->config_page;
   7.207    // two XEN_INIT_TYPE_RUNs means go straight to XenbusStateConnected - skip XenbusStateInitialised
   7.208 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL);
   7.209 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL);
   7.210 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "tx-ring-ref", NULL);
   7.211 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "rx-ring-ref", NULL);
   7.212 -  //ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_IRQ, "event-channel", NULL);
   7.213 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL, "event-channel", NULL);
   7.214 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "mac", NULL);
   7.215 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL, NULL);
   7.216 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL, NULL);
   7.217 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "tx-ring-ref", NULL, NULL);
   7.218 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "rx-ring-ref", NULL, NULL);
   7.219 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL, "event-channel", XenNet_HandleEvent, xi);
   7.220 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "mac", NULL, NULL);
   7.221    RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "%d", !xi->config_csum);
   7.222 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-no-csum-offload", buf);
   7.223 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "request-rx-copy", "1", NULL);
   7.224 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-rx-notify", "1", NULL);
   7.225 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-no-csum-offload", buf, NULL);
   7.226    RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "%d", (int)xi->config_sg);
   7.227 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-sg", buf);
   7.228 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-sg", buf, NULL);
   7.229    RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "%d", !!xi->config_gso);
   7.230 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-gso-tcpv4", buf);
   7.231 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "request-rx-copy", "1");
   7.232 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-rx-notify", "1");
   7.233 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL);
   7.234 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-gso-tcpv4", buf, NULL);
   7.235 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
   7.236    
   7.237    status = xi->vectors.XenPci_XenConfigDevice(xi->vectors.context);
   7.238    if (!NT_SUCCESS(status))
   7.239 @@ -636,7 +650,7 @@ XenNet_Init(
   7.240      goto err;
   7.241    }
   7.242    #endif
   7.243 -  xi->vectors.EvtChn_Bind(xi->vectors.context, xi->event_channel, XenNet_HandleEvent, xi);
   7.244 +  //xi->vectors.EvtChn_Bind(xi->vectors.context, xi->event_channel, XenNet_HandleEvent, xi);
   7.245  
   7.246    FUNCTION_EXIT();
   7.247  
   7.248 @@ -702,8 +716,6 @@ XenNet_Halt(
   7.249    XenNet_TxShutdown(xi);
   7.250    XenNet_RxShutdown(xi);
   7.251  
   7.252 -  NdisFreePacketPool(xi->packet_pool);
   7.253 -
   7.254    NdisFreeMemory(xi, 0, 0); // <= DISPATCH_LEVEL
   7.255  
   7.256    FUNCTION_EXIT();
     8.1 --- a/xennet/xennet.h	Tue Jan 27 00:47:02 2009 +1100
     8.2 +++ b/xennet/xennet.h	Sat Feb 14 13:35:48 2009 +1100
     8.3 @@ -163,7 +163,6 @@ SET_NET_ULONG(PVOID ptr, ULONG data)
     8.4  
     8.5  #define XN_MAX_SEND_PKTS 16
     8.6  
     8.7 -#define XN_RX_QUEUE_LEN 256
     8.8  #define XENSOURCE_MAC_HDR 0x00163E
     8.9  #define XN_VENDOR_DESC "Xensource"
    8.10  #define MAX_XENBUS_STR_LEN 128
    8.11 @@ -172,7 +171,7 @@ SET_NET_ULONG(PVOID ptr, ULONG data)
    8.12  #define RX_DFL_MIN_TARGET 256
    8.13  #define RX_MAX_TARGET min(NET_RX_RING_SIZE, 256)
    8.14  
    8.15 -#define MAX_BUFFERS_PER_PACKET NET_RX_RING_SIZE
    8.16 +//#define MAX_BUFFERS_PER_PACKET NET_RX_RING_SIZE
    8.17  
    8.18  #define MAX_ETH_HEADER_SIZE 14
    8.19  #define MIN_IP4_HEADER_SIZE 20
    8.20 @@ -183,22 +182,27 @@ SET_NET_ULONG(PVOID ptr, ULONG data)
    8.21  
    8.22  typedef struct
    8.23  {
    8.24 -  ULONG id;
    8.25 +  PVOID next;
    8.26    PHYSICAL_ADDRESS logical;
    8.27    PVOID virtual;
    8.28 +  PNDIS_BUFFER buffer;
    8.29 +  USHORT id;
    8.30 +  USHORT ref_count;
    8.31  } shared_buffer_t;
    8.32  
    8.33  typedef struct
    8.34  {
    8.35    PNDIS_PACKET packet; /* only set on the last packet */
    8.36 -  shared_buffer_t *sb;
    8.37 +  shared_buffer_t *hb;
    8.38  } tx_shadow_t;
    8.39  
    8.40  typedef struct {
    8.41 -  PNDIS_BUFFER mdls[MAX_BUFFERS_PER_PACKET];
    8.42 +  PNDIS_BUFFER first_buffer;
    8.43 +  PNDIS_BUFFER curr_buffer;
    8.44 +  shared_buffer_t *first_pb;
    8.45 +  shared_buffer_t *curr_pb;
    8.46    UCHAR header_data[132]; /* maximum possible size of ETH + IP + TCP/UDP headers */
    8.47    ULONG mdl_count;
    8.48 -  USHORT curr_mdl_index;
    8.49    USHORT curr_mdl_offset;
    8.50    USHORT mss;
    8.51    NDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
    8.52 @@ -225,20 +229,6 @@ typedef struct {
    8.53  #define PAGE_LIST_SIZE (max(NET_RX_RING_SIZE, NET_TX_RING_SIZE) * 4)
    8.54  #define MULTICAST_LIST_MAX_SIZE 32
    8.55  
    8.56 -typedef struct
    8.57 -{
    8.58 -  struct xennet_info *xi;
    8.59 -  PMDL page_list[PAGE_LIST_SIZE];
    8.60 -  ULONG page_free;
    8.61 -  ULONG page_free_lowest;
    8.62 -  ULONG page_free_target;
    8.63 -  ULONG page_limit;
    8.64 -  ULONG page_outstanding;
    8.65 -  NDIS_MINIPORT_TIMER timer;
    8.66 -  PKSPIN_LOCK lock;
    8.67 -  BOOLEAN grants_resumed;
    8.68 -} freelist_t;
    8.69 -
    8.70  struct xennet_info
    8.71  {
    8.72    BOOLEAN inactive;
    8.73 @@ -252,7 +242,6 @@ struct xennet_info
    8.74  
    8.75    /* NDIS-related vars */
    8.76    NDIS_HANDLE adapter_handle;
    8.77 -  NDIS_HANDLE packet_pool;
    8.78    NDIS_MINIPORT_INTERRUPT interrupt;
    8.79    ULONG packet_filter;
    8.80    int connected;
    8.81 @@ -278,35 +267,38 @@ struct xennet_info
    8.82    ULONG tx_ring_free;
    8.83    tx_shadow_t tx_shadows[NET_TX_RING_SIZE];
    8.84    NDIS_HANDLE tx_buffer_pool;
    8.85 -#define TX_SHARED_BUFFER_SIZE (PAGE_SIZE >> 3) /* 512 */
    8.86 -//#define TX_SHARED_BUFFERS (NET_TX_RING_SIZE >> 4)
    8.87 -#define TX_SHARED_BUFFERS (NET_TX_RING_SIZE)
    8.88 +#define TX_HEADER_BUFFER_SIZE 512
    8.89 +//#define TX_HEADER_BUFFERS (NET_TX_RING_SIZE >> 2)
    8.90 +#define TX_HEADER_BUFFERS (NET_TX_RING_SIZE)
    8.91    ULONG tx_id_free;
    8.92    USHORT tx_id_list[NET_TX_RING_SIZE];
    8.93 -  ULONG tx_sb_free;
    8.94 -  ULONG tx_sb_list[TX_SHARED_BUFFERS];
    8.95 -  shared_buffer_t tx_sbs[TX_SHARED_BUFFERS];
    8.96 -  
    8.97 -  //freelist_t tx_freelist;
    8.98 +  ULONG tx_hb_free;
    8.99 +  ULONG tx_hb_list[TX_HEADER_BUFFERS];
   8.100 +  shared_buffer_t tx_hbs[TX_HEADER_BUFFERS];
   8.101    KDPC tx_dpc;
   8.102  
   8.103    /* rx_related - protected by rx_lock */
   8.104    KSPIN_LOCK rx_lock;
   8.105    struct netif_rx_front_ring rx;
   8.106    ULONG rx_id_free;
   8.107 -  PNDIS_BUFFER rx_mdls[NET_RX_RING_SIZE];
   8.108 -  freelist_t rx_freelist;
   8.109    packet_info_t rxpi;
   8.110    PNDIS_PACKET rx_packet_list[NET_RX_RING_SIZE * 2];
   8.111    ULONG rx_packet_free;
   8.112    BOOLEAN rx_shutting_down;
   8.113    KEVENT packet_returned_event;
   8.114    //NDIS_MINIPORT_TIMER rx_timer;
   8.115 -  ULONG avg_page_count;
   8.116    KDPC rx_dpc;
   8.117    KTIMER rx_timer;
   8.118    KDPC rx_timer_dpc;
   8.119 -
   8.120 +  NDIS_HANDLE rx_packet_pool;
   8.121 +  NDIS_HANDLE rx_buffer_pool;
   8.122 +  ULONG rx_pb_free;
   8.123 +#define RX_PAGE_BUFFERS (NET_RX_RING_SIZE * 2)
   8.124 +  ULONG rx_pb_list[RX_PAGE_BUFFERS];
   8.125 +  shared_buffer_t rx_pbs[RX_PAGE_BUFFERS];
   8.126 +  USHORT rx_ring_pbs[NET_RX_RING_SIZE];
   8.127 +#define LOOKASIDE_LIST_ALLOC_SIZE 256
   8.128 +  NPAGED_LOOKASIDE_LIST rx_lookaside_list;
   8.129    /* Receive-ring batched refills. */
   8.130    ULONG rx_target;
   8.131    ULONG rx_max_target;
   8.132 @@ -402,9 +394,6 @@ XenNet_SetInformation(
   8.133  #define PARSE_TOO_SMALL 1 /* first buffer is too small */
   8.134  #define PARSE_UNKNOWN_TYPE 2
   8.135  
   8.136 -BOOLEAN
   8.137 -XenNet_IncreasePacketHeader(packet_info_t *pi, ULONG new_header_size);
   8.138 -
   8.139  ULONG
   8.140  XenNet_ParsePacketHeader(packet_info_t *pi);
   8.141  
   8.142 @@ -414,39 +403,11 @@ XenNet_SumIpHeader(
   8.143    USHORT ip4_header_length
   8.144  );
   8.145  
   8.146 -static __forceinline grant_ref_t
   8.147 -get_grant_ref(PMDL mdl)
   8.148 -{
   8.149 -  return *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE));
   8.150 -}
   8.151 -
   8.152 -static __forceinline PUCHAR
   8.153 -XenNet_GetData(
   8.154 -  packet_info_t *pi,
   8.155 -  USHORT req_length,
   8.156 -  PUSHORT length
   8.157 -)
   8.158 -{
   8.159 -  PNDIS_BUFFER mdl = pi->mdls[pi->curr_mdl_index];
   8.160 -  PUCHAR buffer = (PUCHAR)MmGetMdlVirtualAddress(mdl) + pi->curr_mdl_offset;
   8.161 -
   8.162 -  *length = (USHORT)min(req_length, MmGetMdlByteCount(mdl) - pi->curr_mdl_offset);
   8.163 -
   8.164 -  pi->curr_mdl_offset = pi->curr_mdl_offset + *length;
   8.165 -  if (pi->curr_mdl_offset == MmGetMdlByteCount(mdl))
   8.166 -  {
   8.167 -    pi->curr_mdl_index++;
   8.168 -    pi->curr_mdl_offset = 0;
   8.169 -  }
   8.170 -
   8.171 -  return buffer;
   8.172 -}
   8.173 -
   8.174  static __forceinline VOID
   8.175  XenNet_ClearPacketInfo(packet_info_t *pi)
   8.176  {
   8.177  #if 1
   8.178 -  #if 1
   8.179 +  #if 0
   8.180    RtlZeroMemory(&pi->mdl_count, sizeof(packet_info_t) - FIELD_OFFSET(packet_info_t, mdl_count));
   8.181    #else
   8.182    RtlZeroMemory(pi, sizeof(packet_info_t));
   8.183 @@ -458,16 +419,3 @@ XenNet_ClearPacketInfo(packet_info_t *pi
   8.184      pi->data_validated = pi->split_required = 0;
   8.185  #endif
   8.186  }
   8.187 -
   8.188 -VOID
   8.189 -XenFreelist_Init(struct xennet_info *xi, freelist_t *fl, PKSPIN_LOCK lock);
   8.190 -PMDL
   8.191 -XenFreelist_GetPage(freelist_t *fl);
   8.192 -VOID
   8.193 -XenFreelist_PutPage(freelist_t *fl, PMDL mdl);
   8.194 -VOID
   8.195 -XenFreelist_Dispose(freelist_t *fl);
   8.196 -VOID
   8.197 -XenFreelist_ResumeStart(freelist_t *fl);
   8.198 -VOID
   8.199 -XenFreelist_ResumeEnd(freelist_t *fl);
     9.1 --- a/xennet/xennet_common.c	Tue Jan 27 00:47:02 2009 +1100
     9.2 +++ b/xennet/xennet_common.c	Sat Feb 14 13:35:48 2009 +1100
     9.3 @@ -28,7 +28,6 @@ BOOLEAN
     9.4  XenNet_BuildHeader(packet_info_t *pi, ULONG new_header_size)
     9.5  {
     9.6    ULONG bytes_remaining;
     9.7 -  PMDL current_mdl;
     9.8  
     9.9    //FUNCTION_ENTER();
    9.10  
    9.11 @@ -48,7 +47,18 @@ XenNet_BuildHeader(packet_info_t *pi, UL
    9.12    {
    9.13      //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " new_header_size <= pi->first_buffer_length\n"));
    9.14      pi->header_length = new_header_size;
    9.15 -    pi->curr_mdl_offset = (USHORT)new_header_size;
    9.16 +    if (pi->header_length == pi->first_buffer_length)
    9.17 +    {
    9.18 +      NdisGetNextBuffer(pi->curr_buffer, &pi->curr_buffer);
    9.19 +      pi->curr_mdl_offset = 0;
    9.20 +    }
    9.21 +    else
    9.22 +    {
    9.23 +      pi->curr_mdl_offset = (USHORT)new_header_size;
    9.24 +      if (pi->curr_pb)
    9.25 +        pi->curr_pb = pi->curr_pb->next;
    9.26 +    }
    9.27 +    
    9.28      return TRUE;
    9.29    }
    9.30    else if (pi->header != pi->header_data)
    9.31 @@ -60,33 +70,32 @@ XenNet_BuildHeader(packet_info_t *pi, UL
    9.32    
    9.33    bytes_remaining = new_header_size - pi->header_length;
    9.34  
    9.35 -  //KdPrint((__DRIVER_NAME "     A bytes_remaining = %d, pi->curr_mdl_index = %d, pi->mdl_count = %d\n",
    9.36 -  //  bytes_remaining, pi->curr_mdl_index, pi->mdl_count));
    9.37 -  while (bytes_remaining && pi->curr_mdl_index < pi->mdl_count)
    9.38 +  //KdPrint((__DRIVER_NAME "     A bytes_remaining = %d, pi->curr_buffer = %p, pi->mdl_count = %d\n", bytes_remaining, pi->curr_buffer, pi->mdl_count));
    9.39 +  while (bytes_remaining && pi->curr_buffer)
    9.40    {
    9.41      ULONG copy_size;
    9.42      
    9.43 -    //KdPrint((__DRIVER_NAME "     B bytes_remaining = %d, pi->curr_mdl_index = %d, pi->mdl_count = %d\n",
    9.44 -    //  bytes_remaining, pi->curr_mdl_index, pi->mdl_count));
    9.45 -    current_mdl = pi->mdls[pi->curr_mdl_index];
    9.46 -    if (MmGetMdlByteCount(current_mdl))
    9.47 +    ASSERT(pi->curr_buffer);
    9.48 +    //KdPrint((__DRIVER_NAME "     B bytes_remaining = %d, pi->curr_buffer = %p, pi->mdl_count = %d\n", bytes_remaining, pi->curr_buffer, pi->mdl_count));
    9.49 +    if (MmGetMdlByteCount(pi->curr_buffer))
    9.50      {
    9.51 -      copy_size = min(bytes_remaining, MmGetMdlByteCount(current_mdl) - pi->curr_mdl_offset);
    9.52 +      copy_size = min(bytes_remaining, MmGetMdlByteCount(pi->curr_buffer) - pi->curr_mdl_offset);
    9.53        //KdPrint((__DRIVER_NAME "     B copy_size = %d\n", copy_size));
    9.54        memcpy(pi->header + pi->header_length,
    9.55 -        (PUCHAR)MmGetMdlVirtualAddress(current_mdl) + pi->curr_mdl_offset, copy_size);
    9.56 -      pi->curr_mdl_offset = pi->curr_mdl_offset + copy_size;
    9.57 +        (PUCHAR)MmGetMdlVirtualAddress(pi->curr_buffer) + pi->curr_mdl_offset, copy_size);
    9.58 +      pi->curr_mdl_offset = (USHORT)(pi->curr_mdl_offset + copy_size);
    9.59        pi->header_length += copy_size;
    9.60        bytes_remaining -= copy_size;
    9.61      }
    9.62 -    if (pi->curr_mdl_offset == MmGetMdlByteCount(current_mdl))
    9.63 +    if (pi->curr_mdl_offset == MmGetMdlByteCount(pi->curr_buffer))
    9.64      {
    9.65 -      pi->curr_mdl_index++;
    9.66 +      NdisGetNextBuffer(pi->curr_buffer, &pi->curr_buffer);
    9.67 +      if (pi->curr_pb)
    9.68 +        pi->curr_pb = pi->curr_pb->next;
    9.69        pi->curr_mdl_offset = 0;
    9.70      }
    9.71    }
    9.72 -  //KdPrint((__DRIVER_NAME "     C bytes_remaining = %d, pi->curr_mdl_index = %d, pi->mdl_count = %d\n",
    9.73 -  //  bytes_remaining, pi->curr_mdl_index, pi->mdl_count));
    9.74 +  //KdPrint((__DRIVER_NAME "     C bytes_remaining = %d, pi->curr_buffer = %p, pi->mdl_count = %d\n", bytes_remaining, pi->curr_buffer, pi->mdl_count));
    9.75    if (bytes_remaining)
    9.76    {
    9.77      //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " bytes_remaining\n"));
    9.78 @@ -101,12 +110,12 @@ XenNet_ParsePacketHeader(packet_info_t *
    9.79  {
    9.80    //FUNCTION_ENTER();
    9.81  
    9.82 -  ASSERT(pi->mdls[0]);
    9.83 +  ASSERT(pi->first_buffer);
    9.84    
    9.85 -  NdisQueryBufferSafe(pi->mdls[0], (PVOID)&pi->header, &pi->first_buffer_length, NormalPagePriority);
    9.86 +  NdisQueryBufferSafe(pi->first_buffer, (PVOID)&pi->header, &pi->first_buffer_length, NormalPagePriority);
    9.87 +  pi->curr_buffer = pi->first_buffer;
    9.88  
    9.89    pi->header_length = 0;
    9.90 -  pi->curr_mdl_index = 0;
    9.91    pi->curr_mdl_offset = 0;
    9.92      
    9.93    if (!XenNet_BuildHeader(pi, (ULONG)XN_HDR_SIZE))
    9.94 @@ -141,14 +150,6 @@ XenNet_ParsePacketHeader(packet_info_t *
    9.95          KdPrint((__DRIVER_NAME "     packet too small (IP Header + IP Options + TCP Header)\n"));
    9.96          return PARSE_TOO_SMALL;
    9.97        }
    9.98 -#if 0      
    9.99 -      KdPrint((__DRIVER_NAME "     first buffer is only %d bytes long, must be >= %d (1)\n", pi->header_length, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)));
   9.100 -      KdPrint((__DRIVER_NAME "     total_length = %d\n", pi->total_length));
   9.101 -      for (i = 0; i < pi->mdl_count; i++)
   9.102 -      {
   9.103 -        KdPrint((__DRIVER_NAME "     mdl %d length = %d\n", i, MmGetMdlByteCount(pi->mdls[i])));
   9.104 -      }
   9.105 -#endif
   9.106      }
   9.107      break;
   9.108    default:
   9.109 @@ -162,7 +163,7 @@ XenNet_ParsePacketHeader(packet_info_t *
   9.110    case 17: // UDP
   9.111      break;
   9.112    default:
   9.113 -    KdPrint((__DRIVER_NAME "     Not TCP/UDP (%d)\n", pi->ip_proto));
   9.114 +    //KdPrint((__DRIVER_NAME "     Not TCP/UDP (%d)\n", pi->ip_proto));
   9.115      return PARSE_UNKNOWN_TYPE;
   9.116    }
   9.117    pi->ip4_length = GET_NET_PUSHORT(&pi->header[XN_HDR_SIZE + 2]);
   9.118 @@ -170,15 +171,11 @@ XenNet_ParsePacketHeader(packet_info_t *
   9.119  
   9.120    if (pi->header_length < (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + pi->tcp_header_length))
   9.121    {
   9.122 -    if (!XenNet_BuildHeader(pi, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)))
   9.123 +    if (!XenNet_BuildHeader(pi, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + pi->tcp_header_length)))
   9.124      {
   9.125 -      KdPrint((__DRIVER_NAME "     packet too small (IP Header + IP Options + TCP Header + TCP Options)\n"));
   9.126 +      //KdPrint((__DRIVER_NAME "     packet too small (IP Header + IP Options + TCP Header + TCP Options)\n"));
   9.127        return PARSE_TOO_SMALL;
   9.128      }
   9.129 -#if 0    
   9.130 -    KdPrint((__DRIVER_NAME "     first buffer is only %d bytes long, must be >= %d (2)\n", pi->header_length, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + pi->tcp_header_length)));
   9.131 -    return PARSE_TOO_SMALL;
   9.132 -#endif
   9.133    }
   9.134  
   9.135    pi->tcp_length = pi->ip4_length - pi->ip4_header_length - pi->tcp_header_length;
   9.136 @@ -218,168 +215,3 @@ XenNet_SumIpHeader(
   9.137    csum = ~csum;
   9.138    SET_NET_USHORT(&header[XN_HDR_SIZE + 10], (USHORT)csum);
   9.139  }
   9.140 -
   9.141 -/* Called at DISPATCH LEVEL */
   9.142 -static VOID DDKAPI
   9.143 -XenFreelist_Timer(
   9.144 -  PVOID SystemSpecific1,
   9.145 -  PVOID FunctionContext,
   9.146 -  PVOID SystemSpecific2,
   9.147 -  PVOID SystemSpecific3
   9.148 -)
   9.149 -{
   9.150 -  freelist_t *fl = (freelist_t *)FunctionContext;
   9.151 -  PMDL mdl;
   9.152 -  int i;
   9.153 -
   9.154 -  UNREFERENCED_PARAMETER(SystemSpecific1);
   9.155 -  UNREFERENCED_PARAMETER(SystemSpecific2);
   9.156 -  UNREFERENCED_PARAMETER(SystemSpecific3);
   9.157 -
   9.158 -  if (fl->xi->device_state->resume_state != RESUME_STATE_RUNNING && !fl->grants_resumed)
   9.159 -    return;
   9.160 -
   9.161 -  KeAcquireSpinLockAtDpcLevel(fl->lock);
   9.162 -
   9.163 -  //FUNCTION_MSG((" --- timer - page_free_lowest = %d\n", fl->page_free_lowest));
   9.164 -
   9.165 -  if (fl->page_free_lowest > fl->page_free_target) // lots of potential for tuning here
   9.166 -  {
   9.167 -    for (i = 0; i < (int)min(16, fl->page_free_lowest - fl->page_free_target); i++)
   9.168 -    {
   9.169 -      mdl = XenFreelist_GetPage(fl);
   9.170 -      if (!mdl)
   9.171 -        break;
   9.172 -      fl->xi->vectors.GntTbl_EndAccess(fl->xi->vectors.context,
   9.173 -        *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)), 0);
   9.174 -      FreePages(mdl);
   9.175 -      fl->page_outstanding--;
   9.176 -    }
   9.177 -    //FUNCTION_MSG((__DRIVER_NAME " --- timer - freed %d pages\n", i));
   9.178 -  }
   9.179 -
   9.180 -  fl->page_free_lowest = fl->page_free;
   9.181 -
   9.182 -  KeReleaseSpinLockFromDpcLevel(fl->lock);
   9.183 -}
   9.184 -
   9.185 -VOID
   9.186 -XenFreelist_Init(struct xennet_info *xi, freelist_t *fl, PKSPIN_LOCK lock)
   9.187 -{
   9.188 -  fl->xi = xi;
   9.189 -  fl->lock = lock;
   9.190 -  fl->page_free = 0;
   9.191 -  fl->page_free_lowest = 0;
   9.192 -  fl->page_free_target = 16; /* tune this */
   9.193 -  fl->page_limit = 512; /* 2MB */ /* tune this */
   9.194 -  fl->page_outstanding = 0;
   9.195 -  fl->grants_resumed = FALSE;
   9.196 -  NdisMInitializeTimer(&fl->timer, fl->xi->adapter_handle, XenFreelist_Timer, fl);
   9.197 -  NdisMSetPeriodicTimer(&fl->timer, 1000);
   9.198 -}
   9.199 -
   9.200 -PMDL
   9.201 -XenFreelist_GetPage(freelist_t *fl)
   9.202 -{
   9.203 -  PMDL mdl;
   9.204 -  PFN_NUMBER pfn;
   9.205 -  grant_ref_t gref;
   9.206 -
   9.207 -  //ASSERT(!KeTestSpinLock(fl->lock));
   9.208 -
   9.209 -  if (fl->page_free == 0)
   9.210 -  {
   9.211 -    if (fl->page_outstanding >= fl->page_limit)
   9.212 -      return NULL;
   9.213 -    mdl = AllocatePagesExtra(1, sizeof(grant_ref_t));
   9.214 -    if (!mdl)
   9.215 -      return NULL;
   9.216 -    pfn = *MmGetMdlPfnArray(mdl);
   9.217 -    gref = fl->xi->vectors.GntTbl_GrantAccess(
   9.218 -      fl->xi->vectors.context, 0,
   9.219 -      (uint32_t)pfn, FALSE, INVALID_GRANT_REF);
   9.220 -    if (gref == INVALID_GRANT_REF)
   9.221 -      KdPrint((__DRIVER_NAME "     No more grefs\n"));
   9.222 -    *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)) = gref;
   9.223 -    /* we really should check if our grant was successful... */
   9.224 -  }
   9.225 -  else
   9.226 -  {
   9.227 -    fl->page_free--;
   9.228 -    if (fl->page_free < fl->page_free_lowest)
   9.229 -      fl->page_free_lowest = fl->page_free;
   9.230 -    mdl = fl->page_list[fl->page_free];
   9.231 -  }
   9.232 -  fl->page_outstanding++;
   9.233 -  return mdl;
   9.234 -}
   9.235 -
   9.236 -VOID
   9.237 -XenFreelist_PutPage(freelist_t *fl, PMDL mdl)
   9.238 -{
   9.239 -  //ASSERT(!KeTestSpinLock(fl->lock));
   9.240 -
   9.241 -  ASSERT(NdisBufferLength(mdl) == PAGE_SIZE);
   9.242 -
   9.243 -  if (fl->page_free == PAGE_LIST_SIZE)
   9.244 -  {
   9.245 -    KdPrint((__DRIVER_NAME "     page free list full - releasing page\n"));
   9.246 -    /* our page list is full. free the buffer instead. This will be a bit sucky performancewise... */
   9.247 -    fl->xi->vectors.GntTbl_EndAccess(fl->xi->vectors.context,
   9.248 -      *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)), FALSE);
   9.249 -    FreePages(mdl);
   9.250 -  }
   9.251 -  else
   9.252 -  {
   9.253 -    fl->page_list[fl->page_free] = mdl;
   9.254 -    fl->page_free++;
   9.255 -  }
   9.256 -  fl->page_outstanding--;
   9.257 -}
   9.258 -
   9.259 -VOID
   9.260 -XenFreelist_Dispose(freelist_t *fl)
   9.261 -{
   9.262 -  PMDL mdl;
   9.263 -  BOOLEAN TimerCancelled;
   9.264 -
   9.265 -  NdisMCancelTimer(&fl->timer, &TimerCancelled);
   9.266 -
   9.267 -  while(fl->page_free != 0)
   9.268 -  {
   9.269 -    fl->page_free--;
   9.270 -    mdl = fl->page_list[fl->page_free];
   9.271 -    fl->xi->vectors.GntTbl_EndAccess(fl->xi->vectors.context,
   9.272 -      *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)), 0);
   9.273 -    FreePages(mdl);
   9.274 -  }
   9.275 -}
   9.276 -
   9.277 -static VOID
   9.278 -XenFreelist_ReGrantMdl(freelist_t *fl, PMDL mdl)
   9.279 -{
   9.280 -  PFN_NUMBER pfn;
   9.281 -  pfn = *MmGetMdlPfnArray(mdl);
   9.282 -  *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)) = fl->xi->vectors.GntTbl_GrantAccess(
   9.283 -    fl->xi->vectors.context, 0,
   9.284 -    (uint32_t)pfn, FALSE, INVALID_GRANT_REF);
   9.285 -}
   9.286 -
   9.287 -/* re-grant all the pages, as the grant table was wiped on resume */
   9.288 -VOID
   9.289 -XenFreelist_ResumeStart(freelist_t *fl)
   9.290 -{
   9.291 -  ULONG i;
   9.292 -  
   9.293 -  for (i = 0; i < fl->page_free; i++)
   9.294 -  {
   9.295 -    XenFreelist_ReGrantMdl(fl, fl->page_list[i]);
   9.296 -  }
   9.297 -  fl->grants_resumed = TRUE;
   9.298 -}
   9.299 -
   9.300 -VOID
   9.301 -XenFreelist_ResumeEnd(freelist_t *fl)
   9.302 -{
   9.303 -  fl->grants_resumed = FALSE;
   9.304 -}
    10.1 --- a/xennet/xennet_oid.c	Tue Jan 27 00:47:02 2009 +1100
    10.2 +++ b/xennet/xennet_oid.c	Sat Feb 14 13:35:48 2009 +1100
    10.3 @@ -249,9 +249,6 @@ XenNet_QueryInformation(
    10.4            break;
    10.5        }
    10.6  
    10.7 -      KdPrint(("InformationBuffer = %p\n", InformationBuffer));
    10.8 -      KdPrint(("len = %d\n", len));
    10.9 -
   10.10        ntoh = (PNDIS_TASK_OFFLOAD_HEADER)InformationBuffer;
   10.11        if (ntoh->Version != NDIS_TASK_OFFLOAD_VERSION
   10.12          || ntoh->Size != sizeof(*ntoh)
   10.13 @@ -263,8 +260,6 @@ XenNet_QueryInformation(
   10.14          status = NDIS_STATUS_NOT_SUPPORTED;
   10.15          break;
   10.16        }
   10.17 -      KdPrint(("ntoh = %p\n", ntoh));
   10.18 -      KdPrint(("ntoh->Size = %d\n", ntoh->Size));
   10.19        ntoh->OffsetFirstTask = 0; 
   10.20        nto = NULL;
   10.21  
   10.22 @@ -273,14 +268,12 @@ XenNet_QueryInformation(
   10.23          if (ntoh->OffsetFirstTask == 0)
   10.24          {
   10.25            ntoh->OffsetFirstTask = ntoh->Size;
   10.26 -          KdPrint(("ntoh->OffsetFirstTask = %d\n", ntoh->OffsetFirstTask));
   10.27            nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(ntoh) + ntoh->OffsetFirstTask);
   10.28          }
   10.29          else
   10.30          {
   10.31            nto->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
   10.32              + nto->TaskBufferLength;
   10.33 -          KdPrint(("nto->OffsetNextTask = %d\n", nto->OffsetNextTask));
   10.34            nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(nto) + nto->OffsetNextTask);
   10.35          }
   10.36          /* fill in first nto */
   10.37 @@ -320,14 +313,12 @@ XenNet_QueryInformation(
   10.38          if (ntoh->OffsetFirstTask == 0)
   10.39          {
   10.40            ntoh->OffsetFirstTask = ntoh->Size;
   10.41 -          KdPrint(("ntoh->OffsetFirstTask = %d\n", ntoh->OffsetFirstTask));
   10.42            nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(ntoh) + ntoh->OffsetFirstTask);
   10.43          }
   10.44          else
   10.45          {
   10.46            nto->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
   10.47              + nto->TaskBufferLength;
   10.48 -          KdPrint(("nto->OffsetNextTask = %d\n", nto->OffsetNextTask));
   10.49            nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(nto) + nto->OffsetNextTask);
   10.50          }
   10.51    
   10.52 @@ -576,7 +567,10 @@ XenNet_SetInformation(
   10.53        {
   10.54          if (!(multicast_list[i * 6 + 0] & 0x01))
   10.55          {
   10.56 -          KdPrint(("       Address %d is not a multicast address\n", i));
   10.57 +          KdPrint(("       Address %d (%02x:%02x:%02x:%02x:%02x:%02x) is not a multicast address\n", i,
   10.58 +            (ULONG)multicast_list[i * 6 + 0], (ULONG)multicast_list[i * 6 + 1], 
   10.59 +            (ULONG)multicast_list[i * 6 + 2], (ULONG)multicast_list[i * 6 + 3], 
   10.60 +            (ULONG)multicast_list[i * 6 + 4], (ULONG)multicast_list[i * 6 + 5]));
   10.61            status = NDIS_STATUS_MULTICAST_FULL;
   10.62            break;
   10.63          }
    11.1 --- a/xennet/xennet_rx.c	Tue Jan 27 00:47:02 2009 +1100
    11.2 +++ b/xennet/xennet_rx.c	Sat Feb 14 13:35:48 2009 +1100
    11.3 @@ -20,33 +20,74 @@ Foundation, Inc., 51 Franklin Street, Fi
    11.4  
    11.5  #include "xennet.h"
    11.6  
    11.7 +static __inline shared_buffer_t *
    11.8 +get_pb_from_freelist(struct xennet_info *xi)
    11.9 +{
   11.10 +  shared_buffer_t *pb;
   11.11 +  
   11.12 +  if (xi->rx_pb_free == 0)
   11.13 +  {
   11.14 +    KdPrint((__DRIVER_NAME "     Out of pb's\n"));    
   11.15 +    return NULL;
   11.16 +  }
   11.17 +  xi->rx_pb_free--;
   11.18 +
   11.19 +  pb = &xi->rx_pbs[xi->rx_pb_list[xi->rx_pb_free]];
   11.20 +  pb->ref_count++;
   11.21 +  return pb;
   11.22 +}
   11.23 +
   11.24 +static __inline VOID
   11.25 +ref_pb(struct xennet_info *xi, shared_buffer_t *pb)
   11.26 +{
   11.27 +  UNREFERENCED_PARAMETER(xi);
   11.28 +  pb->ref_count++;
   11.29 +  //KdPrint((__DRIVER_NAME "     incremented pb %p ref to %d\n", pb, pb->ref_count));
   11.30 +}
   11.31 +
   11.32 +static __inline VOID
   11.33 +put_pb_on_freelist(struct xennet_info *xi, shared_buffer_t *pb)
   11.34 +{
   11.35 +  pb->ref_count--;
   11.36 +  //KdPrint((__DRIVER_NAME "     decremented pb %p ref to %d\n", pb, pb->ref_count));
   11.37 +  if (pb->ref_count == 0)
   11.38 +  {
   11.39 +    //KdPrint((__DRIVER_NAME "     freeing pb %p\n", pb, pb->ref_count));
   11.40 +    NdisAdjustBufferLength(pb->buffer, PAGE_SIZE);
   11.41 +    NDIS_BUFFER_LINKAGE(pb->buffer) = NULL;
   11.42 +    pb->next = NULL;
   11.43 +    xi->rx_pb_list[xi->rx_pb_free] = pb->id;
   11.44 +    xi->rx_pb_free++;
   11.45 +  }
   11.46 +}
   11.47 +
   11.48 +BOOLEAN ___restored = FALSE;
   11.49 +
   11.50  // Called at DISPATCH_LEVEL with rx lock held
   11.51  static NDIS_STATUS
   11.52 -XenNet_RxBufferAlloc(struct xennet_info *xi)
   11.53 +XenNet_FillRing(struct xennet_info *xi)
   11.54  {
   11.55    unsigned short id;
   11.56 -  PMDL mdl;
   11.57 +  shared_buffer_t *page_buf;
   11.58    ULONG i, notify;
   11.59    ULONG batch_target;
   11.60    RING_IDX req_prod = xi->rx.req_prod_pvt;
   11.61    netif_rx_request_t *req;
   11.62  
   11.63 -//KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   11.64 +  //FUNCTION_ENTER();
   11.65  
   11.66    batch_target = xi->rx_target - (req_prod - xi->rx.rsp_cons);
   11.67  
   11.68    if (batch_target < (xi->rx_target >> 2))
   11.69 +  {
   11.70 +    //FUNCTION_EXIT();
   11.71      return NDIS_STATUS_SUCCESS; /* only refill if we are less than 3/4 full already */
   11.72 +  }
   11.73  
   11.74    for (i = 0; i < batch_target; i++)
   11.75    {
   11.76 -    if (xi->rx_id_free == 0)
   11.77 -    {
   11.78 -      KdPrint((__DRIVER_NAME "     Added %d out of %d buffers to rx ring (ran out of id's)\n", i, batch_target));
   11.79 -      break;
   11.80 -    }
   11.81 -    mdl = XenFreelist_GetPage(&xi->rx_freelist);
   11.82 -    if (!mdl)
   11.83 +    page_buf = get_pb_from_freelist(xi);
   11.84 +    if (!page_buf)
   11.85      {
   11.86        KdPrint((__DRIVER_NAME "     Added %d out of %d buffers to rx ring (no free pages)\n", i, batch_target));
   11.87        break;
   11.88 @@ -55,12 +96,14 @@ XenNet_RxBufferAlloc(struct xennet_info 
   11.89  
   11.90      /* Give to netback */
   11.91      id = (USHORT)((req_prod + i) & (NET_RX_RING_SIZE - 1));
   11.92 -    ASSERT(xi->rx_mdls[id] == NULL);
   11.93 -    xi->rx_mdls[id] = mdl;
   11.94 +    ASSERT(xi->rx_ring_pbs[id] == (USHORT)0xFFFF);
   11.95 +    xi->rx_ring_pbs[id] = page_buf->id;
   11.96      req = RING_GET_REQUEST(&xi->rx, req_prod + i);
   11.97 -    req->gref = get_grant_ref(mdl);
   11.98 +    req->id = id;
   11.99 +    req->gref = (grant_ref_t)(page_buf->logical.QuadPart >> PAGE_SHIFT);
  11.100      ASSERT(req->gref != INVALID_GRANT_REF);
  11.101 -    req->id = id;
  11.102 +    //if (___restored)
  11.103 +    //  KdPrint((__DRIVER_NAME "     putting page_buf %p with id %d and gref %d and physical %p on ring at id %d\n", page_buf, page_buf->id, req->gref, page_buf->logical.LowPart, id));
  11.104    }
  11.105    KeMemoryBarrier();
  11.106    xi->rx.req_prod_pvt = req_prod + i;
  11.107 @@ -70,7 +113,7 @@ XenNet_RxBufferAlloc(struct xennet_info 
  11.108      xi->vectors.EvtChn_Notify(xi->vectors.context, xi->event_channel);
  11.109    }
  11.110  
  11.111 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  11.112 +  //FUNCTION_EXIT();
  11.113  
  11.114    return NDIS_STATUS_SUCCESS;
  11.115  }
  11.116 @@ -85,13 +128,14 @@ get_packet_from_freelist(struct xennet_i
  11.117  
  11.118    if (!xi->rx_packet_free)
  11.119    {
  11.120 -    NdisAllocatePacket(&status, &packet, xi->packet_pool);
  11.121 +    NdisAllocatePacket(&status, &packet, xi->rx_packet_pool);
  11.122      if (status != NDIS_STATUS_SUCCESS)
  11.123      {
  11.124        KdPrint((__DRIVER_NAME "     cannot allocate packet\n"));
  11.125        return NULL;
  11.126      }
  11.127      NDIS_SET_PACKET_HEADER_SIZE(packet, XN_HDR_SIZE);
  11.128 +    NdisZeroMemory(packet->MiniportReservedEx, sizeof(packet->MiniportReservedEx));
  11.129    }
  11.130    else
  11.131    {
  11.132 @@ -116,6 +160,7 @@ put_packet_on_freelist(struct xennet_inf
  11.133    csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
  11.134      packet, TcpIpChecksumPacketInfo);
  11.135    csum_info->Value = 0;
  11.136 +  NdisZeroMemory(packet->MiniportReservedEx, sizeof(packet->MiniportReservedEx));
  11.137    xi->rx_packet_list[xi->rx_packet_free] = packet;
  11.138    xi->rx_packet_free++;
  11.139  }
  11.140 @@ -133,69 +178,125 @@ packet_freelist_dispose(struct xennet_in
  11.141  static PNDIS_PACKET
  11.142  XenNet_MakePacket(struct xennet_info *xi)
  11.143  {
  11.144 +  NDIS_STATUS status;
  11.145    PNDIS_PACKET packet;
  11.146 -  PUCHAR in_buffer;
  11.147 -  PNDIS_BUFFER out_mdl;
  11.148 -  PUCHAR out_buffer;
  11.149 -  USHORT out_offset;
  11.150 -  USHORT out_remaining;
  11.151 -  USHORT length;
  11.152 +  PNDIS_BUFFER out_buffer;
  11.153    USHORT new_ip4_length;
  11.154 -  USHORT i;
  11.155 +  PUCHAR header_va;
  11.156 +  packet_info_t *pi = &xi->rxpi;
  11.157  
  11.158    //FUNCTION_ENTER();
  11.159  
  11.160 -  if (!xi->rxpi.split_required)
  11.161 +  if (!pi->split_required)
  11.162    {
  11.163 +    PNDIS_BUFFER buffer;
  11.164 +    shared_buffer_t *page_buf;
  11.165 +    
  11.166 +    //KdPrint((__DRIVER_NAME "     !split_required\n"));
  11.167 +
  11.168      packet = get_packet_from_freelist(xi);
  11.169      if (packet == NULL)
  11.170      {
  11.171        /* buffers will be freed in MakePackets */
  11.172 +      KdPrint((__DRIVER_NAME "     No free packets\n"));
  11.173        //FUNCTION_EXIT();
  11.174        return NULL;
  11.175      }
  11.176      xi->rx_outstanding++;
  11.177 -    for (i = 0; i < xi->rxpi.mdl_count; i++)
  11.178 -      NdisChainBufferAtBack(packet, xi->rxpi.mdls[i]);
  11.179 +
  11.180 +    // what if we needed to consolidate the header? maybe should put that on instead of all the buffers...
  11.181 +    *(shared_buffer_t **)&packet->MiniportReservedEx[sizeof(LIST_ENTRY)] = pi->first_pb;
  11.182 +    
  11.183 +    buffer = pi->first_buffer;
  11.184 +    page_buf = pi->first_pb;
  11.185 +    //KdPrint((__DRIVER_NAME "     packet = %p, first_buffer = %p, first_pb = %p\n", packet, buffer, page_buf));
  11.186 +    while (buffer)
  11.187 +    {
  11.188 +      PNDIS_BUFFER next_buffer;
  11.189 +      //KdPrint((__DRIVER_NAME "     buffer = %p\n", buffer));
  11.190 +
  11.191 +      NdisGetNextBuffer(buffer, &next_buffer);
  11.192 +      NDIS_BUFFER_LINKAGE(buffer) = NULL;
  11.193 +      NdisChainBufferAtBack(packet, buffer);
  11.194 +      //ref_pb(xi, page_buf);
  11.195 +      
  11.196 +      buffer = next_buffer;
  11.197 +      page_buf = page_buf->next;
  11.198 +    }
  11.199  
  11.200      NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
  11.201    }
  11.202    else
  11.203    {
  11.204 -    out_mdl = XenFreelist_GetPage(&xi->rx_freelist);
  11.205 -    if (!out_mdl)
  11.206 -    {
  11.207 -      //FUNCTION_EXIT();
  11.208 -      return NULL;
  11.209 -    }
  11.210 +    ULONG out_remaining;
  11.211 +    shared_buffer_t *header_buf;
  11.212 +    
  11.213 +    //KdPrint((__DRIVER_NAME "     split_required\n"));
  11.214 +
  11.215      packet = get_packet_from_freelist(xi);
  11.216      if (packet == NULL)
  11.217      {
  11.218 -      XenFreelist_PutPage(&xi->rx_freelist, out_mdl);
  11.219        //FUNCTION_EXIT();
  11.220        return NULL;
  11.221      }
  11.222      xi->rx_outstanding++;
  11.223 -    out_buffer = MmGetMdlVirtualAddress(out_mdl);
  11.224 -    out_offset = XN_HDR_SIZE + xi->rxpi.ip4_header_length + xi->rxpi.tcp_header_length;
  11.225 -    out_remaining = min(xi->rxpi.mss, xi->rxpi.tcp_remaining);
  11.226 -    NdisAdjustBufferLength(out_mdl, out_offset + out_remaining);
  11.227 -    memcpy(out_buffer, xi->rxpi.header, out_offset);
  11.228 -    new_ip4_length = out_remaining + xi->rxpi.ip4_header_length + xi->rxpi.tcp_header_length;
  11.229 -    SET_NET_USHORT(&out_buffer[XN_HDR_SIZE + 2], new_ip4_length);
  11.230 -    SET_NET_ULONG(&out_buffer[XN_HDR_SIZE + xi->rxpi.ip4_header_length + 4], xi->rxpi.tcp_seq);
  11.231 -    xi->rxpi.tcp_seq += out_remaining;
  11.232 -    xi->rxpi.tcp_remaining = xi->rxpi.tcp_remaining - out_remaining;
  11.233 +
  11.234 +    //status = NdisAllocateMemoryWithTag((PUCHAR *)&header_buf, sizeof(shared_buffer_t) + pi->header_length, XENNET_POOL_TAG);
  11.235 +    ASSERT(sizeof(shared_buffer_t) + pi->header_length < LOOKASIDE_LIST_ALLOC_SIZE);
  11.236 +    header_buf = NdisAllocateFromNPagedLookasideList(&xi->rx_lookaside_list);
  11.237 +    ASSERT(header_buf); // lazy
  11.238 +    header_va = (PUCHAR)(header_buf + 1);
  11.239 +    NdisZeroMemory(header_buf, sizeof(shared_buffer_t));
  11.240 +    NdisMoveMemory(header_va, pi->header, pi->header_length);
  11.241 +
  11.242 +    // TODO: if there are only a few bytes left on the first buffer then add them to the header buffer too
  11.243 +
  11.244 +    NdisAllocateBuffer(&status, &out_buffer, xi->rx_buffer_pool, header_va, pi->header_length);
  11.245 +    //KdPrint((__DRIVER_NAME "     about to add buffer with length = %d\n", MmGetMdlByteCount(out_buffer)));
  11.246 +    NdisChainBufferAtBack(packet, out_buffer);
  11.247 +    *(shared_buffer_t **)&packet->MiniportReservedEx[sizeof(LIST_ENTRY)] = header_buf;
  11.248 +    header_buf->next = pi->curr_pb;
  11.249 +
  11.250 +    //KdPrint((__DRIVER_NAME "     header_length = %d\n", pi->header_length));
  11.251 +    //KdPrint((__DRIVER_NAME "     curr_mdl_offset = %d\n", pi->curr_mdl_offset));
  11.252 +    //KdPrint((__DRIVER_NAME "     tcp_remaining = %d\n", pi->tcp_remaining));
  11.253 +    
  11.254 +    //KdPrint((__DRIVER_NAME "     tcp_remaining = %d\n", pi->tcp_remaining));
  11.255 +    out_remaining = (USHORT)min(pi->mss, pi->tcp_remaining);
  11.256 +    new_ip4_length = (USHORT)(pi->ip4_header_length + pi->tcp_header_length + out_remaining);
  11.257 +    SET_NET_USHORT(&header_va[XN_HDR_SIZE + 2], new_ip4_length);
  11.258 +    SET_NET_ULONG(&header_va[XN_HDR_SIZE + pi->ip4_header_length + 4], pi->tcp_seq);
  11.259 +    pi->tcp_seq += out_remaining;
  11.260 +    pi->tcp_remaining = (USHORT)(pi->tcp_remaining - out_remaining);
  11.261      do 
  11.262      {
  11.263 -      ASSERT(xi->rxpi.curr_mdl_index < xi->rxpi.mdl_count);
  11.264 -      in_buffer = XenNet_GetData(&xi->rxpi, out_remaining, &length);
  11.265 -      memcpy(&out_buffer[out_offset], in_buffer, length);
  11.266 -      out_remaining = out_remaining - length;
  11.267 -      out_offset = out_offset + length;
  11.268 +      ULONG in_buffer_offset;
  11.269 +      ULONG in_buffer_length;
  11.270 +      ULONG out_length;
  11.271 +      //UINT tmp_packet_length;
  11.272 +      //KdPrint((__DRIVER_NAME "     curr_buffer = %p\n", pi->curr_buffer));
  11.273 +      //KdPrint((__DRIVER_NAME "     curr_pb = %p\n", pi->curr_pb));
  11.274 +      //KdPrint((__DRIVER_NAME "     out_remaining = %d\n", out_remaining));
  11.275 +      NdisQueryBufferOffset(pi->curr_buffer, &in_buffer_offset, &in_buffer_length);
  11.276 +      out_length = min(out_remaining, in_buffer_length - pi->curr_mdl_offset);
  11.277 +      //KdPrint((__DRIVER_NAME "     out_length = %d\n", out_length));
  11.278 +      NdisCopyBuffer(&status, &out_buffer, xi->rx_buffer_pool, pi->curr_buffer, pi->curr_mdl_offset, out_length);
  11.279 +      //TODO: check status
  11.280 +      //KdPrint((__DRIVER_NAME "     about to add buffer with length = %d\n", MmGetMdlByteCount(out_buffer)));
  11.281 +      NdisChainBufferAtBack(packet, out_buffer);
  11.282 +      //NdisQueryPacketLength(packet, &tmp_packet_length);
  11.283 +      //KdPrint((__DRIVER_NAME "     current packet length = %d\n", tmp_packet_length));
  11.284 +      ref_pb(xi, pi->curr_pb);
  11.285 +      pi->curr_mdl_offset = (USHORT)(pi->curr_mdl_offset + out_length);
  11.286 +      if (pi->curr_mdl_offset == in_buffer_length)
  11.287 +      {
  11.288 +        NdisGetNextBuffer(pi->curr_buffer, &pi->curr_buffer);
  11.289 +        pi->curr_pb = pi->curr_pb->next;
  11.290 +        pi->curr_mdl_offset = 0;
  11.291 +      }
  11.292 +      out_remaining -= out_length;
  11.293      } while (out_remaining != 0);
  11.294 -    NdisChainBufferAtBack(packet, out_mdl);
  11.295 -    XenNet_SumIpHeader(out_buffer, xi->rxpi.ip4_header_length);
  11.296 +    XenNet_SumIpHeader(header_va, pi->ip4_header_length);
  11.297      NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
  11.298    }
  11.299  
  11.300 @@ -317,7 +418,6 @@ XenNet_SumPacketData(
  11.301    }
  11.302    //FUNCTION_EXIT();
  11.303    return TRUE;
  11.304 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  11.305  }
  11.306  
  11.307  static ULONG
  11.308 @@ -333,29 +433,35 @@ XenNet_MakePackets(
  11.309    UCHAR psh;
  11.310    PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
  11.311    ULONG parse_result;  
  11.312 +  packet_info_t *pi = &xi->rxpi;
  11.313 +  PNDIS_BUFFER buffer;
  11.314 +  shared_buffer_t *page_buf;
  11.315  
  11.316    //FUNCTION_ENTER();
  11.317  
  11.318 -  parse_result = XenNet_ParsePacketHeader(&xi->rxpi);
  11.319 +  parse_result = XenNet_ParsePacketHeader(pi);
  11.320  
  11.321    if ((xi->packet_filter & NDIS_PACKET_TYPE_MULTICAST)
  11.322      && !(xi->packet_filter & NDIS_PACKET_TYPE_ALL_MULTICAST)
  11.323 -    && (xi->rxpi.header[0] & 0x01)
  11.324 -    && !(xi->rxpi.header[0] == 0xFF && xi->rxpi.header[1] == 0xFF && xi->rxpi.header[2] == 0xFF
  11.325 -        && xi->rxpi.header[3] == 0xFF && xi->rxpi.header[4] == 0xFF && xi->rxpi.header[5] == 0xFF))
  11.326 +    && (pi->header[0] & 0x01)
  11.327 +    && !(pi->header[0] == 0xFF && pi->header[1] == 0xFF && pi->header[2] == 0xFF
  11.328 +        && pi->header[3] == 0xFF && pi->header[4] == 0xFF && pi->header[5] == 0xFF))
  11.329    {
  11.330      for (i = 0; i < xi->multicast_list_size; i++)
  11.331      {
  11.332 -      if (memcmp(xi->multicast_list[i], xi->rxpi.header, 6) == 0)
  11.333 +      if (memcmp(xi->multicast_list[i], pi->header, 6) == 0)
  11.334          break;
  11.335      }
  11.336      if (i == xi->multicast_list_size)
  11.337 +    {
  11.338 +      //KdPrint((__DRIVER_NAME "     Packet not for my MAC address\n"));
  11.339        goto done;
  11.340 +    }
  11.341    }
  11.342 -  switch (xi->rxpi.ip_proto)
  11.343 +  switch (pi->ip_proto)
  11.344    {
  11.345    case 6:  // TCP
  11.346 -    if (xi->rxpi.split_required)
  11.347 +    if (pi->split_required)
  11.348        break;
  11.349      // fallthrough
  11.350    case 17:  // UDP
  11.351 @@ -372,28 +478,28 @@ XenNet_MakePackets(
  11.352      {
  11.353        csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
  11.354          packet, TcpIpChecksumPacketInfo);
  11.355 -      if (xi->rxpi.csum_blank || xi->rxpi.data_validated)
  11.356 +      if (pi->csum_blank || pi->data_validated)
  11.357        {
  11.358 -        if (xi->setting_csum.V4Receive.TcpChecksum && xi->rxpi.ip_proto == 6)
  11.359 +        if (xi->setting_csum.V4Receive.TcpChecksum && pi->ip_proto == 6)
  11.360          {
  11.361 -          if (!xi->rxpi.tcp_has_options || xi->setting_csum.V4Receive.TcpOptionsSupported)
  11.362 +          if (!pi->tcp_has_options || xi->setting_csum.V4Receive.TcpOptionsSupported)
  11.363            {
  11.364              csum_info->Receive.NdisPacketTcpChecksumSucceeded = TRUE;
  11.365            }
  11.366 -        } else if (xi->setting_csum.V4Receive.UdpChecksum && xi->rxpi.ip_proto == 17)
  11.367 +        } else if (xi->setting_csum.V4Receive.UdpChecksum && pi->ip_proto == 17)
  11.368          {
  11.369            csum_info->Receive.NdisPacketUdpChecksumSucceeded = TRUE;
  11.370          }
  11.371 -        if (xi->rxpi.csum_blank)
  11.372 +        if (pi->csum_blank)
  11.373          {
  11.374 -          XenNet_SumPacketData(&xi->rxpi, packet, TRUE);
  11.375 +          XenNet_SumPacketData(pi, packet, TRUE);
  11.376          }
  11.377        }
  11.378        else if (!xi->config_csum_rx_check)
  11.379        {
  11.380 -        if (xi->setting_csum.V4Receive.TcpChecksum && xi->rxpi.ip_proto == 6)
  11.381 +        if (xi->setting_csum.V4Receive.TcpChecksum && pi->ip_proto == 6)
  11.382          {
  11.383 -          if (XenNet_SumPacketData(&xi->rxpi, packet, FALSE))
  11.384 +          if (XenNet_SumPacketData(pi, packet, FALSE))
  11.385            {
  11.386              csum_info->Receive.NdisPacketTcpChecksumSucceeded = TRUE;
  11.387            }
  11.388 @@ -401,9 +507,9 @@ XenNet_MakePackets(
  11.389            {
  11.390              csum_info->Receive.NdisPacketTcpChecksumFailed = TRUE;
  11.391            }
  11.392 -        } else if (xi->setting_csum.V4Receive.UdpChecksum && xi->rxpi.ip_proto == 17)
  11.393 +        } else if (xi->setting_csum.V4Receive.UdpChecksum && pi->ip_proto == 17)
  11.394          {
  11.395 -          if (XenNet_SumPacketData(&xi->rxpi, packet, FALSE))
  11.396 +          if (XenNet_SumPacketData(pi, packet, FALSE))
  11.397            {
  11.398              csum_info->Receive.NdisPacketUdpChecksumSucceeded = TRUE;
  11.399            }
  11.400 @@ -414,10 +520,9 @@ XenNet_MakePackets(
  11.401          }
  11.402        }
  11.403      }
  11.404 -
  11.405 -    entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
  11.406 +    entry = (PLIST_ENTRY)&packet->MiniportReservedEx[0];
  11.407      InsertTailList(rx_packet_list, entry);
  11.408 -    XenNet_ClearPacketInfo(&xi->rxpi);
  11.409 +    XenNet_ClearPacketInfo(pi);
  11.410      //FUNCTION_EXIT();
  11.411      return 1;
  11.412    default:
  11.413 @@ -429,26 +534,33 @@ XenNet_MakePackets(
  11.414        packet_count = 0;
  11.415        goto done;
  11.416      }
  11.417 -    entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
  11.418 +    entry = (PLIST_ENTRY)&packet->MiniportReservedEx[0];
  11.419      InsertTailList(rx_packet_list, entry);
  11.420 -    XenNet_ClearPacketInfo(&xi->rxpi);
  11.421 +    XenNet_ClearPacketInfo(pi);
  11.422      //FUNCTION_EXIT();
  11.423      return 1;
  11.424    }
  11.425  
  11.426 -  xi->rxpi.tcp_remaining = xi->rxpi.tcp_length;
  11.427 -#if 0 // _index and _offset set by ParseHeader
  11.428 -  if (MmGetMdlByteCount(xi->rxpi.mdls[0]) > (ULONG)(XN_HDR_SIZE + xi->rxpi.ip4_header_length + xi->rxpi.tcp_header_length))
  11.429 -    xi->rxpi.curr_mdl_offset = XN_HDR_SIZE + xi->rxpi.ip4_header_length + xi->rxpi.tcp_header_length;
  11.430 -  else
  11.431 -    xi->rxpi.curr_mdl_index = 1;
  11.432 -#endif
  11.433 +  /* synchronise the pb with the buffer */
  11.434 +  buffer = pi->first_buffer;
  11.435 +  pi->curr_pb = pi->first_pb;
  11.436 +  //KdPrint((__DRIVER_NAME "     first_buffer = %p, curr_buffer = %p, first_pb = %p, curr_pb = %p\n",
  11.437 +  //  pi->first_buffer, pi->curr_buffer, pi->first_pb, pi->curr_pb));
  11.438 +  
  11.439 +  while (pi->curr_pb != NULL && buffer != pi->curr_buffer)
  11.440 +  {
  11.441 +    NdisGetNextBuffer(buffer, &buffer);
  11.442 +    pi->curr_pb = pi->curr_pb->next;
  11.443 +    //KdPrint((__DRIVER_NAME "     buffer = %p, curr_pb = %p\n", buffer, pi->curr_pb));
  11.444 +  }
  11.445 +  
  11.446 +  pi->tcp_remaining = pi->tcp_length;
  11.447  
  11.448    /* we can make certain assumptions here as the following code is only for tcp4 */
  11.449 -  psh = xi->rxpi.header[XN_HDR_SIZE + xi->rxpi.ip4_header_length + 13] & 8;
  11.450 -  while (xi->rxpi.tcp_remaining)
  11.451 +  psh = pi->header[XN_HDR_SIZE + pi->ip4_header_length + 13] & 8;
  11.452 +  while (pi->tcp_remaining)
  11.453    {
  11.454 -    PUCHAR buffer;
  11.455 +    PUCHAR header_va;
  11.456      PMDL mdl;
  11.457      UINT total_length;
  11.458      UINT buffer_length;
  11.459 @@ -467,74 +579,56 @@ XenNet_MakePackets(
  11.460      }
  11.461      if (psh)
  11.462      {
  11.463 -      NdisGetFirstBufferFromPacketSafe(packet, &mdl, &buffer, &buffer_length, &total_length, NormalPagePriority);
  11.464 -      if (xi->rxpi.tcp_remaining)
  11.465 -      {
  11.466 -        buffer[XN_HDR_SIZE + xi->rxpi.ip4_header_length + 13] &= ~8;
  11.467 -      }
  11.468 +      NdisGetFirstBufferFromPacketSafe(packet, &mdl, &header_va, &buffer_length, &total_length, NormalPagePriority);
  11.469 +      if (pi->tcp_remaining)
  11.470 +        header_va[XN_HDR_SIZE + pi->ip4_header_length + 13] &= ~8;
  11.471        else
  11.472 -      {
  11.473 -        buffer[XN_HDR_SIZE + xi->rxpi.ip4_header_length + 13] |= 8;
  11.474 -      }
  11.475 +        header_va[XN_HDR_SIZE + pi->ip4_header_length + 13] |= 8;
  11.476      }
  11.477 -    XenNet_SumPacketData(&xi->rxpi, packet, TRUE);
  11.478 -    entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
  11.479 +    XenNet_SumPacketData(pi, packet, TRUE);
  11.480 +    entry = (PLIST_ENTRY)&packet->MiniportReservedEx[0];
  11.481      InsertTailList(rx_packet_list, entry);
  11.482      packet_count++;
  11.483    }
  11.484  
  11.485  done:
  11.486 -  for (i = 0; i < xi->rxpi.mdl_count; i++)
  11.487 +  //buffer = pi->first_buffer;
  11.488 +  page_buf = pi->first_pb;
  11.489 +  while (page_buf)
  11.490    {
  11.491 -    NdisAdjustBufferLength(xi->rxpi.mdls[i], PAGE_SIZE);
  11.492 -    xi->rxpi.mdls[i]->ByteOffset = 0;
  11.493 -    XenFreelist_PutPage(&xi->rx_freelist, xi->rxpi.mdls[i]);
  11.494 +    //PNDIS_BUFFER next_buffer;
  11.495 +    shared_buffer_t *next_pb;
  11.496 +
  11.497 +    //NdisGetNextBuffer(buffer, &next_buffer);
  11.498 +    next_pb = page_buf->next;
  11.499 +
  11.500 +    //NdisFreeBuffer(buffer);
  11.501 +    put_pb_on_freelist(xi, page_buf);
  11.502 +    
  11.503 +    //buffer = next_buffer;
  11.504 +    page_buf = next_pb;
  11.505    }
  11.506 -  XenNet_ClearPacketInfo(&xi->rxpi);
  11.507 +  XenNet_ClearPacketInfo(pi);
  11.508    //FUNCTION_EXIT();
  11.509    return packet_count;
  11.510  }
  11.511  
  11.512 -typedef struct {
  11.513 -  struct xennet_info *xi;
  11.514 -  BOOLEAN is_timer;
  11.515 -} sync_context_t;
  11.516 -
  11.517  static BOOLEAN
  11.518  XenNet_RxQueueDpcSynchronized(PVOID context)
  11.519  {
  11.520 -  sync_context_t *sc = context;
  11.521 -  BOOLEAN result;
  11.522 -  
  11.523 -  if (!sc->is_timer && sc->xi->config_rx_interrupt_moderation)
  11.524 -  {
  11.525 -    /* if an is_timer dpc is queued it will muck things up for us, so make sure we requeue a !is_timer dpc */
  11.526 -    KeRemoveQueueDpc(&sc->xi->rx_dpc);
  11.527 -  }
  11.528 -  result = KeInsertQueueDpc(&sc->xi->rx_dpc, UlongToPtr(sc->is_timer), NULL);
  11.529 +  struct xennet_info *xi = context;
  11.530 +
  11.531 +  KeInsertQueueDpc(&xi->rx_dpc, NULL, NULL);
  11.532    
  11.533    return TRUE;
  11.534  }
  11.535  
  11.536  #define MAXIMUM_PACKETS_PER_INDICATE 32
  11.537 -#define MAX_PACKETS_PER_INTERRUPT 32
  11.538 -
  11.539 -static VOID
  11.540 -XenNet_RxTimerDpc(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2)
  11.541 -{
  11.542 -  struct xennet_info *xi = context;
  11.543 -  sync_context_t sc;
  11.544 +/*
  11.545 +We limit the number of packets per interrupt so that acks get a chance
  11.546 +under high rx load. The DPC is immediately re-scheduled */
  11.547  
  11.548 -  UNREFERENCED_PARAMETER(dpc);
  11.549 -  UNREFERENCED_PARAMETER(arg1);
  11.550 -  UNREFERENCED_PARAMETER(arg2);
  11.551 -  
  11.552 -  sc.xi = xi;
  11.553 -  sc.is_timer = TRUE;
  11.554 -  xi->vectors.EvtChn_Sync(xi->vectors.context, XenNet_RxQueueDpcSynchronized, &sc);
  11.555 -//#pragma warning(suppress:4054) /* no way around this... */
  11.556 -//  NdisMSynchronizeWithInterrupt(&xi->interrupt, (PVOID)XenNet_RxQueueDpcSynchronized, &sc);
  11.557 -}
  11.558 +#define MAX_PACKETS_PER_INTERRUPT 64
  11.559  
  11.560  // Called at DISPATCH_LEVEL
  11.561  static VOID
  11.562 @@ -546,23 +640,20 @@ XenNet_RxBufferCheck(PKDPC dpc, PVOID co
  11.563    PLIST_ENTRY entry;
  11.564    PNDIS_PACKET packets[MAXIMUM_PACKETS_PER_INDICATE];
  11.565    ULONG packet_count = 0;
  11.566 -  PMDL mdl;
  11.567    struct netif_rx_response *rxrsp = NULL;
  11.568    struct netif_extra_info *ei;
  11.569    USHORT id;
  11.570    int more_to_do = FALSE;
  11.571 -  int page_count = 0;
  11.572 -  ULONG event = 1;
  11.573 -  BOOLEAN is_timer = (BOOLEAN)PtrToUlong(arg1);
  11.574 -  BOOLEAN set_timer = FALSE;
  11.575 +  packet_info_t *pi = &xi->rxpi;
  11.576 +  //NDIS_STATUS status;
  11.577 +  shared_buffer_t *page_buf;
  11.578 +  PNDIS_BUFFER buffer;
  11.579  
  11.580    UNREFERENCED_PARAMETER(dpc);
  11.581    UNREFERENCED_PARAMETER(arg1);
  11.582    UNREFERENCED_PARAMETER(arg2);
  11.583  
  11.584    //FUNCTION_ENTER();
  11.585 -  if (is_timer) 
  11.586 -    KdPrint((__DRIVER_NAME "     RX Timer\n"));
  11.587  
  11.588    ASSERT(xi->connected);
  11.589  
  11.590 @@ -570,9 +661,6 @@ XenNet_RxBufferCheck(PKDPC dpc, PVOID co
  11.591  
  11.592    InitializeListHead(&rx_packet_list);
  11.593  
  11.594 -  if (xi->config_rx_interrupt_moderation)
  11.595 -    KeCancelTimer(&xi->rx_timer);
  11.596 -
  11.597    do {
  11.598      prod = xi->rx.sring->rsp_prod;
  11.599  //KdPrint((__DRIVER_NAME "     prod - cons = %d\n", prod - xi->rx.rsp_cons));    
  11.600 @@ -581,23 +669,25 @@ XenNet_RxBufferCheck(PKDPC dpc, PVOID co
  11.601      for (cons = xi->rx.rsp_cons; cons != prod && packet_count < MAX_PACKETS_PER_INTERRUPT; cons++)
  11.602      {
  11.603        id = (USHORT)(cons & (NET_RX_RING_SIZE - 1));
  11.604 -      ASSERT(xi->rx_mdls[id]);
  11.605 -      mdl = xi->rx_mdls[id];
  11.606 -      xi->rx_mdls[id] = NULL;
  11.607 +      ASSERT(xi->rx_ring_pbs[id]);
  11.608 +      page_buf = &xi->rx_pbs[xi->rx_ring_pbs[id]];
  11.609 +      xi->rx_ring_pbs[id] = 0xFFFF;
  11.610        xi->rx_id_free++;
  11.611 -      if (xi->rxpi.extra_info)
  11.612 +      //KdPrint((__DRIVER_NAME "     got page_buf %p with id %d from ring at id %d\n", page_buf, page_buf->id, id));
  11.613 +      if (pi->extra_info)
  11.614        {
  11.615 -        XenFreelist_PutPage(&xi->rx_freelist, mdl);
  11.616 +        //KdPrint((__DRIVER_NAME "     processing extra info\n"));
  11.617 +        put_pb_on_freelist(xi, page_buf);
  11.618          ei = (struct netif_extra_info *)RING_GET_RESPONSE(&xi->rx, cons);
  11.619 -        xi->rxpi.extra_info = (BOOLEAN)!!(ei->flags & XEN_NETIF_EXTRA_FLAG_MORE);
  11.620 +        pi->extra_info = (BOOLEAN)!!(ei->flags & XEN_NETIF_EXTRA_FLAG_MORE);
  11.621          switch (ei->type)
  11.622          {
  11.623          case XEN_NETIF_EXTRA_TYPE_GSO:
  11.624            switch (ei->u.gso.type)
  11.625            {
  11.626            case XEN_NETIF_GSO_TYPE_TCPV4:
  11.627 -            xi->rxpi.mss = ei->u.gso.size;
  11.628 -            // TODO - put this assertion somewhere ASSERT(header_len + xi->rxpi.mss <= PAGE_SIZE); // this limits MTU to PAGE_SIZE - XN_HEADER_LEN
  11.629 +            pi->mss = ei->u.gso.size;
  11.630 +            // TODO - put this assertion somewhere ASSERT(header_len + pi->mss <= PAGE_SIZE); // this limits MTU to PAGE_SIZE - XN_HEADER_LEN
  11.631              break;
  11.632            default:
  11.633              KdPrint((__DRIVER_NAME "     Unknown GSO type (%d) detected\n", ei->u.gso.type));
  11.634 @@ -618,149 +708,108 @@ XenNet_RxBufferCheck(PKDPC dpc, PVOID co
  11.635          {
  11.636            KdPrint((__DRIVER_NAME "     Error: rxrsp offset %d, size %d\n",
  11.637              rxrsp->offset, rxrsp->status));
  11.638 -          ASSERT(!xi->rxpi.extra_info);
  11.639 -          XenFreelist_PutPage(&xi->rx_freelist, mdl);
  11.640 +          ASSERT(!pi->extra_info);
  11.641 +          put_pb_on_freelist(xi, page_buf);
  11.642            continue;
  11.643          }
  11.644 +        ASSERT(!rxrsp->offset);
  11.645          ASSERT(rxrsp->id == id);
  11.646 -        if (!xi->rxpi.more_frags) // handling the packet's 1st buffer
  11.647 +        if (!pi->more_frags) // handling the packet's 1st buffer
  11.648          {
  11.649            if (rxrsp->flags & NETRXF_csum_blank)
  11.650 -            xi->rxpi.csum_blank = TRUE;
  11.651 +            pi->csum_blank = TRUE;
  11.652            if (rxrsp->flags & NETRXF_data_validated)
  11.653 -            xi->rxpi.data_validated = TRUE;
  11.654 +            pi->data_validated = TRUE;
  11.655          }
  11.656 -        
  11.657 -        NdisAdjustBufferLength(mdl, rxrsp->status);
  11.658 -        xi->rxpi.mdls[xi->rxpi.mdl_count++] = mdl;
  11.659 -#if 0
  11.660 -        if (!xi->rxpi.mdl_count || MmGetMdlByteCount(xi->rxpi.mdls[xi->rxpi.mdl_count - 1]) == PAGE_SIZE)
  11.661 +        //NdisAllocateBuffer(&status, &buffer, xi->rx_buffer_pool, (PUCHAR)page_buf->virtual + rxrsp->offset, rxrsp->status);
  11.662 +        //KdPrint((__DRIVER_NAME "     buffer = %p, offset = %d, len = %d\n", buffer, rxrsp->offset, rxrsp->status));
  11.663 +        //ASSERT(status == NDIS_STATUS_SUCCESS); // lazy
  11.664 +        buffer = page_buf->buffer;
  11.665 +        NdisAdjustBufferLength(buffer, rxrsp->status);
  11.666 +        if (pi->first_pb)
  11.667          {
  11.668 -          /* first buffer or no room in current buffer */
  11.669 -          NdisAdjustBufferLength(mdl, rxrsp->status);
  11.670 -          xi->rxpi.mdls[xi->rxpi.mdl_count++] = mdl;
  11.671 -        }
  11.672 -        else if (MmGetMdlByteCount(xi->rxpi.mdls[xi->rxpi.mdl_count - 1]) + rxrsp->status <= PAGE_SIZE)
  11.673 -        {
  11.674 -          /* this buffer fits entirely in current buffer */
  11.675 -          PMDL dst_mdl = xi->rxpi.mdls[xi->rxpi.mdl_count - 1];
  11.676 -          PUCHAR dst_addr = MmGetMdlVirtualAddress(dst_mdl);
  11.677 -          PUCHAR src_addr = MmGetMdlVirtualAddress(mdl);
  11.678 -          dst_addr += MmGetMdlByteCount(dst_mdl);
  11.679 -          memcpy(dst_addr, src_addr, rxrsp->status);
  11.680 -          NdisAdjustBufferLength(dst_mdl, MmGetMdlByteCount(dst_mdl) + rxrsp->status);
  11.681 -          XenFreelist_PutPage(&xi->rx_freelist, mdl);
  11.682 +          //KdPrint((__DRIVER_NAME "     additional buffer\n"));
  11.683 +          pi->curr_pb->next = page_buf;
  11.684 +          pi->curr_pb = page_buf;
  11.685 +          NDIS_BUFFER_LINKAGE(pi->curr_buffer) = buffer;
  11.686 +          pi->curr_buffer = buffer;
  11.687          }
  11.688          else
  11.689          {
  11.690 -          /* this buffer doesn't fit entirely in current buffer */
  11.691 -          PMDL dst_mdl = xi->rxpi.mdls[xi->rxpi.mdl_count - 1];
  11.692 -          PUCHAR dst_addr = MmGetMdlVirtualAddress(dst_mdl);
  11.693 -          PUCHAR src_addr = MmGetMdlVirtualAddress(mdl);
  11.694 -          ULONG copy_size = PAGE_SIZE - MmGetMdlByteCount(dst_mdl);
  11.695 -          dst_addr += MmGetMdlByteCount(dst_mdl);
  11.696 -          memcpy(dst_addr, src_addr, copy_size);
  11.697 -          NdisAdjustBufferLength(dst_mdl, PAGE_SIZE);
  11.698 -          dst_addr = src_addr;
  11.699 -          src_addr += copy_size;
  11.700 -          copy_size = rxrsp->status - copy_size;
  11.701 -          memmove(dst_addr, src_addr, copy_size); /* use memmove because the regions overlap */
  11.702 -          NdisAdjustBufferLength(mdl, copy_size);
  11.703 -          xi->rxpi.mdls[xi->rxpi.mdl_count++] = mdl;
  11.704 +          pi->first_pb = page_buf;
  11.705 +          pi->curr_pb = page_buf;
  11.706 +          pi->first_buffer = buffer;
  11.707 +          pi->curr_buffer = buffer;
  11.708          }
  11.709 -#endif
  11.710 -        xi->rxpi.extra_info = (BOOLEAN)!!(rxrsp->flags & NETRXF_extra_info);
  11.711 -        xi->rxpi.more_frags = (BOOLEAN)!!(rxrsp->flags & NETRXF_more_data);
  11.712 -        xi->rxpi.total_length = xi->rxpi.total_length + rxrsp->status;
  11.713 +        pi->mdl_count++;
  11.714 +        pi->extra_info = (BOOLEAN)!!(rxrsp->flags & NETRXF_extra_info);
  11.715 +        pi->more_frags = (BOOLEAN)!!(rxrsp->flags & NETRXF_more_data);
  11.716 +        pi->total_length = pi->total_length + rxrsp->status;
  11.717        }
  11.718  
  11.719        /* Packet done, add it to the list */
  11.720 -      if (!xi->rxpi.more_frags && !xi->rxpi.extra_info)
  11.721 +      if (!pi->more_frags && !pi->extra_info)
  11.722        {
  11.723          packet_count += XenNet_MakePackets(xi, &rx_packet_list);
  11.724        }
  11.725 -      if (!more_to_do) {
  11.726 -        page_count++; /* only interested in the number of pages available after the first time around */
  11.727 -      }
  11.728      }
  11.729      xi->rx.rsp_cons = cons;
  11.730  
  11.731 -    if (!more_to_do)
  11.732 -    {
  11.733 -      /* if we were called on the timer then turn off moderation */
  11.734 -      if (is_timer)
  11.735 -        xi->avg_page_count = 0;
  11.736 -      else if (page_count != 0) /* if page_count == 0 then the interrupt wasn't really for us so it's not fair for it to affect the averages... */
  11.737 -        xi->avg_page_count = (xi->avg_page_count * 7 + page_count * 128) / 8;
  11.738 -    }
  11.739      if (packet_count >= MAX_PACKETS_PER_INTERRUPT)
  11.740        break;
  11.741 +
  11.742      more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xi->rx);
  11.743      if (!more_to_do)
  11.744      {
  11.745 -      if (xi->config_rx_interrupt_moderation)
  11.746 -        event = min(max(1, xi->avg_page_count * 3 / 4 / 128), 128);
  11.747 -      else
  11.748 -        event = 1;
  11.749 -      xi->rx.sring->rsp_event = xi->rx.rsp_cons + event;
  11.750 +      xi->rx.sring->rsp_event = xi->rx.rsp_cons + 1;
  11.751        mb();
  11.752        more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xi->rx);
  11.753      }
  11.754    } while (more_to_do);
  11.755  
  11.756 -  if (xi->rxpi.more_frags || xi->rxpi.extra_info)
  11.757 -    KdPrint((__DRIVER_NAME "     Partial receive (more_frags = %d, extra_info = %d, total_length = %d, mdl_count = %d)\n", xi->rxpi.more_frags, xi->rxpi.extra_info, xi->rxpi.total_length, xi->rxpi.mdl_count));
  11.758 +  if (pi->more_frags || pi->extra_info)
  11.759 +    KdPrint((__DRIVER_NAME "     Partial receive (more_frags = %d, extra_info = %d, total_length = %d, mdl_count = %d)\n", pi->more_frags, pi->extra_info, pi->total_length, pi->mdl_count));
  11.760  
  11.761    /* Give netback more buffers */
  11.762 -  XenNet_RxBufferAlloc(xi);
  11.763 -
  11.764 -  //KdPrint((__DRIVER_NAME "     packet_count = %d, page_count = %d, avg_page_count = %d, event = %d\n", packet_count, page_count, xi->avg_page_count / 128, event));
  11.765 +  XenNet_FillRing(xi);
  11.766  
  11.767    if (packet_count >= MAX_PACKETS_PER_INTERRUPT)
  11.768    {
  11.769      /* fire again immediately */
  11.770 -    sync_context_t sc;
  11.771 -    sc.xi = xi;
  11.772 -    sc.is_timer = FALSE;
  11.773 -    xi->vectors.EvtChn_Sync(xi->vectors.context, XenNet_RxQueueDpcSynchronized, &sc);
  11.774 -//#pragma warning(suppress:4054) /* no way around this... */
  11.775 -//    NdisMSynchronizeWithInterrupt(&xi->interrupt, (PVOID)XenNet_RxQueueDpcSynchronized, &sc);
  11.776 +    xi->vectors.EvtChn_Sync(xi->vectors.context, XenNet_RxQueueDpcSynchronized, xi);
  11.777    }
  11.778 -  else if (xi->config_rx_interrupt_moderation)
  11.779 -  {
  11.780 -    if (event > 1)
  11.781 -    {
  11.782 -      set_timer = TRUE;
  11.783 -    }
  11.784 -  }
  11.785 +
  11.786 +  //KdPrint((__DRIVER_NAME "     packet_count = %d, page_count = %d, avg_page_count = %d, event = %d\n", packet_count, page_count, xi->avg_page_count / 128, event));
  11.787 +
  11.788    KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
  11.789  
  11.790    entry = RemoveHeadList(&rx_packet_list);
  11.791    packet_count = 0;
  11.792    while (entry != &rx_packet_list)
  11.793    {
  11.794 -    PNDIS_PACKET packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
  11.795 +    PNDIS_PACKET packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[0]);
  11.796 +    packets[packet_count++] = packet;
  11.797 +#if 0    
  11.798 +    KdPrint((__DRIVER_NAME "     Adding packet %p to indicate list\n", packet));
  11.799 +{
  11.800      PVOID addr;
  11.801      UINT buffer_length;
  11.802      UINT total_length;
  11.803 -    NdisGetFirstBufferFromPacketSafe(packet, &mdl, &addr, &buffer_length, &total_length, NormalPagePriority);
  11.804 -    
  11.805 +    PNDIS_BUFFER buffer;
  11.806 +
  11.807 +    NdisGetFirstBufferFromPacketSafe(packet, &buffer, &addr, &buffer_length, &total_length, NormalPagePriority);
  11.808 +    KdPrint((__DRIVER_NAME "     buffer = %p, addr = %p, buffer_length = %d, total_length = %d\n", buffer, addr, buffer_length, total_length));
  11.809      ASSERT(total_length <= xi->config_mtu + XN_HDR_SIZE);
  11.810 -    packets[packet_count++] = packet;
  11.811 +}   
  11.812 +#endif
  11.813      entry = RemoveHeadList(&rx_packet_list);
  11.814      if (packet_count == MAXIMUM_PACKETS_PER_INDICATE || entry == &rx_packet_list)
  11.815      {
  11.816 +      //KdPrint((__DRIVER_NAME "     Indicating\n"));
  11.817        NdisMIndicateReceivePacket(xi->adapter_handle, packets, packet_count);
  11.818        packet_count = 0;
  11.819      }
  11.820    }
  11.821 -  /* set the timer after we have indicated the packets, as indicating can take a significant amount of time */
  11.822 -  if (set_timer)
  11.823 -  {
  11.824 -    LARGE_INTEGER due_time;
  11.825 -    due_time.QuadPart = -10 * 1000 * 10; /* 10ms */
  11.826 -    KeSetTimer(&xi->rx_timer, due_time, &xi->rx_timer_dpc);
  11.827 -  }
  11.828    //FUNCTION_EXIT();
  11.829  }
  11.830  
  11.831 @@ -773,21 +822,40 @@ XenNet_ReturnPacket(
  11.832    )
  11.833  {
  11.834    struct xennet_info *xi = MiniportAdapterContext;
  11.835 -  PMDL mdl;
  11.836 +  PNDIS_BUFFER buffer;
  11.837 +  shared_buffer_t *page_buf = *(shared_buffer_t **)&Packet->MiniportReservedEx[sizeof(LIST_ENTRY)];
  11.838  
  11.839    //FUNCTION_ENTER();
  11.840  
  11.841 +  //KdPrint((__DRIVER_NAME "     page_buf = %p\n", page_buf));
  11.842 +
  11.843    KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
  11.844  
  11.845 -  NdisUnchainBufferAtBack(Packet, &mdl);
  11.846 -  while (mdl)
  11.847 +  NdisUnchainBufferAtFront(Packet, &buffer);
  11.848 +  while (buffer)
  11.849    {
  11.850 -    //KdPrint((__DRIVER_NAME "     packet = %p, mdl = %p\n", Packet, mdl));
  11.851 -    mdl->ByteOffset = 0;
  11.852 -    NdisAdjustBufferLength(mdl, PAGE_SIZE);
  11.853 -    XenFreelist_PutPage(&xi->rx_freelist, mdl);
  11.854 -    NdisUnchainBufferAtBack(Packet, &mdl);
  11.855 -  }
  11.856 +    shared_buffer_t *next_buf = page_buf->next;
  11.857 +    if (!page_buf->virtual)
  11.858 +    {
  11.859 +      /* this isn't actually a share_buffer, it is some memory allocated for the header - just free it */
  11.860 +      PUCHAR va;
  11.861 +      UINT len;
  11.862 +      NdisQueryBufferSafe(buffer, &va, &len, NormalPagePriority);
  11.863 +      //KdPrint((__DRIVER_NAME "     freeing header buffer %p\n", va - sizeof(shared_buffer_t)));
  11.864 +      //NdisFreeMemory(va - sizeof(shared_buffer_t), len + sizeof(shared_buffer_t), 0);
  11.865 +      NdisFreeToNPagedLookasideList(&xi->rx_lookaside_list, va - sizeof(shared_buffer_t));
  11.866 +      NdisFreeBuffer(buffer);
  11.867 +    }
  11.868 +    else
  11.869 +    {
  11.870 +      //KdPrint((__DRIVER_NAME "     returning page_buf %p with id %d\n", page_buf, page_buf->id));
  11.871 +      if (buffer != page_buf->buffer)
  11.872 +        NdisFreeBuffer(buffer);
  11.873 +      put_pb_on_freelist(xi, page_buf);
  11.874 +    }
  11.875 +    NdisUnchainBufferAtFront(Packet, &buffer);
  11.876 +    page_buf = next_buf;
  11.877 +  }  
  11.878  
  11.879    put_packet_on_freelist(xi, Packet);
  11.880    xi->rx_outstanding--;
  11.881 @@ -795,7 +863,7 @@ XenNet_ReturnPacket(
  11.882    if (!xi->rx_outstanding && xi->rx_shutting_down)
  11.883      KeSetEvent(&xi->packet_returned_event, IO_NO_INCREMENT, FALSE);
  11.884  
  11.885 -  XenNet_RxBufferAlloc(xi);
  11.886 +  XenNet_FillRing(xi);
  11.887  
  11.888    KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
  11.889  
  11.890 @@ -807,63 +875,97 @@ XenNet_ReturnPacket(
  11.891     The ring must be stopped at this point.
  11.892  */
  11.893  
  11.894 -static void
  11.895 -XenNet_RxBufferFree(struct xennet_info *xi)
  11.896 +static VOID
  11.897 +XenNet_PurgeRing(struct xennet_info *xi)
  11.898  {
  11.899    int i;
  11.900 -  PMDL mdl;
  11.901 -
  11.902 -  XenFreelist_Dispose(&xi->rx_freelist);
  11.903 -
  11.904 -  ASSERT(!xi->connected);
  11.905 -
  11.906    for (i = 0; i < NET_RX_RING_SIZE; i++)
  11.907    {
  11.908 -    if (!xi->rx_mdls[i])
  11.909 -      continue;
  11.910 +    if (xi->rx_ring_pbs[i] != 0xFFFF)
  11.911 +    {
  11.912 +      put_pb_on_freelist(xi, &xi->rx_pbs[xi->rx_ring_pbs[i]]);
  11.913 +      xi->rx_ring_pbs[i] = 0xFFFF;
  11.914 +    }
  11.915 +  }
  11.916 +}
  11.917  
  11.918 -    mdl = xi->rx_mdls[i];
  11.919 -    NdisAdjustBufferLength(mdl, PAGE_SIZE);
  11.920 -    XenFreelist_PutPage(&xi->rx_freelist, mdl);
  11.921 +static VOID
  11.922 +XenNet_BufferFree(struct xennet_info *xi)
  11.923 +{
  11.924 +  shared_buffer_t *pb;
  11.925 +
  11.926 +  XenNet_PurgeRing(xi);
  11.927 +
  11.928 +  while ((pb = get_pb_from_freelist(xi)) != NULL)
  11.929 +  {
  11.930 +    NdisFreeBuffer(pb->buffer);
  11.931 +    NdisMFreeSharedMemory(xi->adapter_handle, PAGE_SIZE, TRUE, pb->virtual, pb->logical);
  11.932    }
  11.933  }
  11.934  
  11.935  VOID
  11.936  XenNet_RxResumeStart(xennet_info_t *xi)
  11.937  {
  11.938 -  int i;
  11.939    KIRQL old_irql;
  11.940  
  11.941 +  FUNCTION_ENTER();
  11.942 +
  11.943 +  ___restored = TRUE;  
  11.944    KeAcquireSpinLock(&xi->rx_lock, &old_irql);
  11.945 +  XenNet_PurgeRing(xi);
  11.946 +  KeReleaseSpinLock(&xi->rx_lock, old_irql);
  11.947 +  
  11.948 +  FUNCTION_EXIT();
  11.949 +}
  11.950 +
  11.951 +VOID
  11.952 +XenNet_BufferAlloc(xennet_info_t *xi)
  11.953 +{
  11.954 +  NDIS_STATUS status;
  11.955 +  int i;
  11.956 +  
  11.957 +  xi->rx_id_free = NET_RX_RING_SIZE;
  11.958 +  xi->rx_outstanding = 0;
  11.959 +
  11.960    for (i = 0; i < NET_RX_RING_SIZE; i++)
  11.961    {
  11.962 -    if (xi->rx_mdls[i])
  11.963 -    {
  11.964 -      XenFreelist_PutPage(&xi->rx_freelist, xi->rx_mdls[i]);
  11.965 -      xi->rx_mdls[i] = NULL;
  11.966 -    }
  11.967 +    xi->rx_ring_pbs[i] = 0xFFFF;
  11.968    }
  11.969 -  XenFreelist_ResumeStart(&xi->rx_freelist);
  11.970 -  xi->rx_id_free = NET_RX_RING_SIZE;
  11.971 -  xi->rx_outstanding = 0;
  11.972 -  KeReleaseSpinLock(&xi->rx_lock, old_irql);
  11.973 +  
  11.974 +  for (i = 0; i < RX_PAGE_BUFFERS; i++)
  11.975 +  {
  11.976 +    xi->rx_pbs[i].id = (USHORT)i;
  11.977 +    NdisMAllocateSharedMemory(xi->adapter_handle, PAGE_SIZE, TRUE, &xi->rx_pbs[i].virtual, &xi->rx_pbs[i].logical);
  11.978 +    NdisAllocateBuffer(&status, &xi->rx_pbs[i].buffer, xi->rx_buffer_pool, (PUCHAR)xi->rx_pbs[i].virtual, PAGE_SIZE);
  11.979 +    if (status != STATUS_SUCCESS)
  11.980 +      break;
  11.981 +    xi->rx_pbs[i].ref_count = 1; /* when we put it back it will go to zero */
  11.982 +    put_pb_on_freelist(xi, &xi->rx_pbs[i]);
  11.983 +  }
  11.984 +  if (i == 0)
  11.985 +    KdPrint((__DRIVER_NAME "     Unable to allocate any SharedMemory buffers\n"));
  11.986  }
  11.987  
  11.988 +
  11.989  VOID
  11.990  XenNet_RxResumeEnd(xennet_info_t *xi)
  11.991  {
  11.992    KIRQL old_irql;
  11.993  
  11.994 +  FUNCTION_ENTER();
  11.995 +
  11.996    KeAcquireSpinLock(&xi->rx_lock, &old_irql);
  11.997 -  XenFreelist_ResumeEnd(&xi->rx_freelist);
  11.998 -  XenNet_RxBufferAlloc(xi);
  11.999 +  //XenNet_BufferAlloc(xi);
 11.1000 +  XenNet_FillRing(xi);
 11.1001    KeReleaseSpinLock(&xi->rx_lock, old_irql);
 11.1002 +  
 11.1003 +  FUNCTION_EXIT();
 11.1004  }
 11.1005  
 11.1006  BOOLEAN
 11.1007  XenNet_RxInit(xennet_info_t *xi)
 11.1008  {
 11.1009 -  int i;
 11.1010 +  NDIS_STATUS status;
 11.1011  
 11.1012    FUNCTION_ENTER();
 11.1013  
 11.1014 @@ -873,22 +975,22 @@ XenNet_RxInit(xennet_info_t *xi)
 11.1015    KeInitializeDpc(&xi->rx_dpc, XenNet_RxBufferCheck, xi);
 11.1016    KeSetTargetProcessorDpc(&xi->rx_dpc, 0);
 11.1017    //KeSetImportanceDpc(&xi->rx_dpc, HighImportance);
 11.1018 -  KeInitializeDpc(&xi->rx_timer_dpc, XenNet_RxTimerDpc, xi);
 11.1019 -  xi->avg_page_count = 0;
 11.1020 +  //KeInitializeDpc(&xi->rx_timer_dpc, XenNet_RxTimerDpc, xi);
 11.1021 +  xi->rx_shutting_down = FALSE;
 11.1022  
 11.1023 -  xi->rx_shutting_down = FALSE;
 11.1024 +  XenNet_BufferAlloc(xi);
 11.1025    
 11.1026 -  xi->rx_id_free = NET_RX_RING_SIZE;
 11.1027 -
 11.1028 -  for (i = 0; i < NET_RX_RING_SIZE; i++)
 11.1029 +  NdisAllocatePacketPool(&status, &xi->rx_packet_pool, NET_RX_RING_SIZE * 4,
 11.1030 +    PROTOCOL_RESERVED_SIZE_IN_PACKET);
 11.1031 +  if (status != NDIS_STATUS_SUCCESS)
 11.1032    {
 11.1033 -    xi->rx_mdls[i] = NULL;
 11.1034 +    KdPrint(("NdisAllocatePacketPool failed with 0x%x\n", status));
 11.1035 +    return FALSE;
 11.1036    }
 11.1037  
 11.1038 -  xi->rx_outstanding = 0;
 11.1039 -  XenFreelist_Init(xi, &xi->rx_freelist, &xi->rx_lock);
 11.1040 -
 11.1041 -  XenNet_RxBufferAlloc(xi);
 11.1042 +  NdisInitializeNPagedLookasideList(&xi->rx_lookaside_list, NULL, NULL, 0, LOOKASIDE_LIST_ALLOC_SIZE, XENNET_POOL_TAG, 0);
 11.1043 +  
 11.1044 +  XenNet_FillRing(xi);
 11.1045  
 11.1046    FUNCTION_EXIT();
 11.1047  
 11.1048 @@ -919,12 +1021,12 @@ XenNet_RxShutdown(xennet_info_t *xi)
 11.1049  
 11.1050    KeAcquireSpinLock(&xi->rx_lock, &OldIrql);
 11.1051  
 11.1052 -  XenNet_RxBufferFree(xi);
 11.1053 -
 11.1054 -  XenFreelist_Dispose(&xi->rx_freelist);
 11.1055 +  XenNet_BufferFree(xi);
 11.1056  
 11.1057    packet_freelist_dispose(xi);
 11.1058  
 11.1059 +  NdisFreePacketPool(xi->rx_packet_pool);
 11.1060 +
 11.1061    KeReleaseSpinLock(&xi->rx_lock, OldIrql);
 11.1062  
 11.1063    FUNCTION_EXIT();
    12.1 --- a/xennet/xennet_tx.c	Tue Jan 27 00:47:02 2009 +1100
    12.2 +++ b/xennet/xennet_tx.c	Sat Feb 14 13:35:48 2009 +1100
    12.3 @@ -36,24 +36,26 @@ put_id_on_freelist(struct xennet_info *x
    12.4    xi->tx_id_free++;
    12.5  }
    12.6  
    12.7 -static shared_buffer_t *
    12.8 -get_sb_from_freelist(struct xennet_info *xi)
    12.9 +static __inline shared_buffer_t *
   12.10 +get_hb_from_freelist(struct xennet_info *xi)
   12.11  {
   12.12 -  if (xi->tx_sb_free == 0)
   12.13 +  shared_buffer_t *hb;
   12.14 +  
   12.15 +  if (xi->tx_hb_free == 0)
   12.16    {
   12.17 -    KdPrint((__DRIVER_NAME "     Out of sb's\n"));    
   12.18      return NULL;
   12.19    }
   12.20 -  xi->tx_sb_free--;
   12.21 +  xi->tx_hb_free--;
   12.22  
   12.23 -  return &xi->tx_sbs[xi->tx_sb_list[xi->tx_sb_free]];
   12.24 +  hb = &xi->tx_hbs[xi->tx_hb_list[xi->tx_hb_free]];
   12.25 +  return hb;
   12.26  }
   12.27  
   12.28 -static VOID
   12.29 -put_sb_on_freelist(struct xennet_info *xi, shared_buffer_t *sb)
   12.30 +static __inline VOID
   12.31 +put_hb_on_freelist(struct xennet_info *xi, shared_buffer_t *hb)
   12.32  {
   12.33 -  xi->tx_sb_list[xi->tx_sb_free] = sb->id;
   12.34 -  xi->tx_sb_free++;
   12.35 +  xi->tx_hb_list[xi->tx_hb_free] = hb->id;
   12.36 +  xi->tx_hb_free++;
   12.37  }
   12.38  
   12.39  #define SWAP_USHORT(x) (USHORT)((((x & 0xFF) << 8)|((x >> 8) & 0xFF)))
   12.40 @@ -80,24 +82,13 @@ XenNet_HWSendPacket(struct xennet_info *
   12.41    ULONG sg_element = 0;
   12.42    ULONG sg_offset = 0;
   12.43    ULONG parse_result;
   12.44 -  shared_buffer_t *shared_buf = NULL;
   12.45 -  ULONG i;
   12.46 +  shared_buffer_t *header_buf = NULL;
   12.47    
   12.48    //FUNCTION_ENTER();
   12.49    
   12.50    XenNet_ClearPacketInfo(&pi);
   12.51 -  NdisQueryPacket(packet, NULL, (PUINT)&pi.mdl_count, &pi.mdls[0], (PUINT)&pi.total_length);
   12.52 +  NdisQueryPacket(packet, NULL, (PUINT)&pi.mdl_count, &pi.first_buffer, (PUINT)&pi.total_length);
   12.53    //KdPrint((__DRIVER_NAME "     A - packet = %p, mdl_count = %d, total_length = %d\n", packet, pi.mdl_count, pi.total_length));
   12.54 -  for (i = 1; i < pi.mdl_count; i++)
   12.55 -  {
   12.56 -    NdisGetNextBuffer(pi.mdls[i - 1], &pi.mdls[i])
   12.57 -  }
   12.58 -#if 0
   12.59 -  for (i = 0; i < pi.mdl_count; i++)
   12.60 -  {
   12.61 -    KdPrint((__DRIVER_NAME "     Aa - mdl[%d] va = %p, length = %d\n", i, MmGetMdlVirtualAddress(pi.mdls[i]), MmGetMdlByteCount(pi.mdls[i])));
   12.62 -  }
   12.63 -#endif
   12.64  
   12.65    parse_result = XenNet_ParsePacketHeader(&pi);  
   12.66    //KdPrint((__DRIVER_NAME "     B\n"));
   12.67 @@ -174,6 +165,20 @@ XenNet_HWSendPacket(struct xennet_info *
   12.68      return FALSE;
   12.69    }
   12.70  
   12.71 +  sg = (PSCATTER_GATHER_LIST)NDIS_PER_PACKET_INFO_FROM_PACKET(packet, ScatterGatherListPacketInfo);
   12.72 +  ASSERT(sg != NULL);
   12.73 +
   12.74 +  if (ndis_lso || (pi.header_length && pi.header_length > sg->Elements[sg_element].Length && pi.header == pi.header_data))
   12.75 +  {
   12.76 +    // why is a hb being used for icmp???
   12.77 +    header_buf = get_hb_from_freelist(xi);
   12.78 +    if (!header_buf)
   12.79 +    {
   12.80 +      KdPrint((__DRIVER_NAME "     Full on send - no free hb's\n"));
   12.81 +      return FALSE;
   12.82 +    }
   12.83 +  }
   12.84 +  
   12.85    if (ndis_lso)
   12.86    {    
   12.87      if (parse_result == PARSE_OK)
   12.88 @@ -195,14 +200,6 @@ XenNet_HWSendPacket(struct xennet_info *
   12.89      }
   12.90    }
   12.91  
   12.92 -  sg = (PSCATTER_GATHER_LIST)NDIS_PER_PACKET_INFO_FROM_PACKET(packet, ScatterGatherListPacketInfo);
   12.93 -  ASSERT(sg != NULL);
   12.94 -#if 0
   12.95 -  for (i = 0; i < sg->NumberOfElements; i++)
   12.96 -  {
   12.97 -    KdPrint((__DRIVER_NAME "     Ba - sg->Elements[%d] length = %d\n", i, sg->Elements[i].Length));
   12.98 -  }
   12.99 -#endif
  12.100  /*
  12.101  * See io/netif.h. Must put (A) 1st request, then (B) optional extra_info, then
  12.102  * (C) rest of requests on the ring. Only (A) has csum flags.
  12.103 @@ -213,16 +210,16 @@ XenNet_HWSendPacket(struct xennet_info *
  12.104  // if we coalesced the header then we want to put that on first, otherwise we put on the first sg element
  12.105    tx0 = RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
  12.106    tx0->id = 0xFFFF;
  12.107 -  if (ndis_lso || (pi.header_length && pi.header_length > sg->Elements[sg_element].Length && pi.header == pi.header_data))
  12.108 +  if (header_buf)
  12.109    {
  12.110      ULONG remaining = pi.header_length;
  12.111 -    ASSERT(pi.header_length < TX_SHARED_BUFFER_SIZE);
  12.112 +    ASSERT(pi.header_length < TX_HEADER_BUFFER_SIZE);
  12.113      //KdPrint((__DRIVER_NAME "     D - header_length = %d\n", pi.header_length));
  12.114 -    shared_buf = get_sb_from_freelist(xi);
  12.115 -    memcpy(shared_buf->virtual, pi.header, pi.header_length);
  12.116 -    XenNet_SumIpHeader(shared_buf->virtual, pi.ip4_header_length);
  12.117 -    tx0->gref = (grant_ref_t)(shared_buf->logical.QuadPart >> PAGE_SHIFT);
  12.118 -    tx0->offset = (USHORT)shared_buf->logical.LowPart & (PAGE_SIZE - 1);
  12.119 +    memcpy(header_buf->virtual, pi.header, pi.header_length);
  12.120 +    /* even though we haven't reported that we are capable of it, LSO demands that we calculate the IP Header checksum */
  12.121 +    XenNet_SumIpHeader(header_buf->virtual, pi.ip4_header_length);
  12.122 +    tx0->gref = (grant_ref_t)(header_buf->logical.QuadPart >> PAGE_SHIFT);
  12.123 +    tx0->offset = (USHORT)header_buf->logical.LowPart & (PAGE_SIZE - 1);
  12.124      tx0->size = (USHORT)pi.header_length;
  12.125      ASSERT(tx0->offset + tx0->size <= PAGE_SIZE);
  12.126      ASSERT(tx0->size);
  12.127 @@ -297,7 +294,7 @@ XenNet_HWSendPacket(struct xennet_info *
  12.128    txN->id = get_id_from_freelist(xi);
  12.129  //KdPrint((__DRIVER_NAME "     send - id = %d\n", tx0->id));
  12.130    xi->tx_shadows[txN->id].packet = packet;
  12.131 -  xi->tx_shadows[txN->id].sb = shared_buf;
  12.132 +  xi->tx_shadows[txN->id].hb = header_buf;
  12.133  
  12.134    if (ndis_lso)
  12.135    {
  12.136 @@ -323,6 +320,9 @@ XenNet_SendQueuedPackets(struct xennet_i
  12.137  
  12.138    //FUNCTION_ENTER();
  12.139  
  12.140 +  if (xi->device_state->suspend_resume_state_pdo != SR_STATE_RUNNING)
  12.141 +    return;
  12.142 +
  12.143    entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
  12.144    /* if empty, the above returns head*, not NULL */
  12.145    while (entry != &xi->tx_waiting_pkt_list)
  12.146 @@ -377,10 +377,10 @@ XenNet_TxBufferGC(PKDPC dpc, PVOID conte
  12.147        if (txrsp->status == NETIF_RSP_NULL || txrsp->id == 0xFFFF)
  12.148          continue;
  12.149  
  12.150 -      if (xi->tx_shadows[txrsp->id].sb)
  12.151 +      if (xi->tx_shadows[txrsp->id].hb)
  12.152        {
  12.153 -        put_sb_on_freelist(xi, xi->tx_shadows[txrsp->id].sb);
  12.154 -        xi->tx_shadows[txrsp->id].sb = NULL;
  12.155 +        put_hb_on_freelist(xi, xi->tx_shadows[txrsp->id].hb);
  12.156 +        xi->tx_shadows[txrsp->id].hb = NULL;
  12.157        }
  12.158        
  12.159        if (xi->tx_shadows[txrsp->id].packet)
  12.160 @@ -415,6 +415,17 @@ XenNet_TxBufferGC(PKDPC dpc, PVOID conte
  12.161      NdisMSendComplete(xi->adapter_handle, packet, NDIS_STATUS_SUCCESS);
  12.162    }
  12.163  //KdPrint((__DRIVER_NAME "     packets_outstanding = %d\n", packets_outstanding));
  12.164 +
  12.165 +  if (xi->device_state->suspend_resume_state_pdo == SR_STATE_SUSPENDING
  12.166 +    && xi->device_state->suspend_resume_state_fdo != SR_STATE_SUSPENDING
  12.167 +    && xi->tx_id_free == NET_TX_RING_SIZE)
  12.168 +  {
  12.169 +    KdPrint((__DRIVER_NAME "     Setting SR_STATE_SUSPENDING\n"));
  12.170 +    xi->device_state->suspend_resume_state_fdo = SR_STATE_SUSPENDING;
  12.171 +    KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xi->device_state->pdo_event_channel));
  12.172 +    xi->vectors.EvtChn_Notify(xi->vectors.context, xi->device_state->pdo_event_channel);
  12.173 +  }
  12.174 +
  12.175    //FUNCTION_EXIT();
  12.176  }
  12.177  
  12.178 @@ -457,8 +468,7 @@ XenNet_SendPackets(
  12.179      InsertTailList(&xi->tx_waiting_pkt_list, entry);
  12.180    }
  12.181  
  12.182 -  if (xi->device_state->resume_state == RESUME_STATE_RUNNING)
  12.183 -    XenNet_SendQueuedPackets(xi);
  12.184 +  XenNet_SendQueuedPackets(xi);
  12.185  
  12.186    KeReleaseSpinLock(&xi->tx_lock, OldIrql);
  12.187    
  12.188 @@ -469,26 +479,10 @@ VOID
  12.189  XenNet_TxResumeStart(xennet_info_t *xi)
  12.190  {
  12.191    UNREFERENCED_PARAMETER(xi);
  12.192 -#if 0
  12.193 -  int i;
  12.194 -  KIRQL old_irql;
  12.195  
  12.196 -  KeAcquireSpinLock(&xi->tx_lock, &old_irql);
  12.197 -  for (i = 0; i < NET_TX_RING_SIZE; i++)
  12.198 -  {
  12.199 -    if (xi->tx_mdls[i])
  12.200 -    {
  12.201 -      NdisAdjustBufferLength(xi->tx_mdls[i], PAGE_SIZE);
  12.202 -      XenFreelist_PutPage(&xi->tx_freelist, xi->tx_mdls[i]);
  12.203 -      xi->tx_mdls[i] = NULL;
  12.204 -    }
  12.205 -  }
  12.206 -  xi->tx_id_free = 0;
  12.207 -  xi->tx_no_id_used = 0;
  12.208 -  for (i = 0; i < NET_TX_RING_SIZE; i++)
  12.209 -    put_id_on_freelist(xi, (USHORT)i);
  12.210 -  KeReleaseSpinLock(&xi->tx_lock, old_irql);
  12.211 -#endif
  12.212 +  FUNCTION_ENTER();
  12.213 +    /* nothing to do here - all packets were already sent */
  12.214 +  FUNCTION_EXIT();
  12.215  }
  12.216  
  12.217  VOID
  12.218 @@ -496,9 +490,13 @@ XenNet_TxResumeEnd(xennet_info_t *xi)
  12.219  {
  12.220    KIRQL old_irql;
  12.221  
  12.222 +  FUNCTION_ENTER();
  12.223 +
  12.224    KeAcquireSpinLock(&xi->tx_lock, &old_irql);
  12.225    XenNet_SendQueuedPackets(xi);
  12.226    KeReleaseSpinLock(&xi->tx_lock, old_irql);
  12.227 +
  12.228 +  FUNCTION_EXIT();
  12.229  }
  12.230  
  12.231  BOOLEAN
  12.232 @@ -514,7 +512,7 @@ XenNet_TxInit(xennet_info_t *xi)
  12.233    //KeSetImportanceDpc(&xi->tx_dpc, HighImportance);
  12.234    InitializeListHead(&xi->tx_waiting_pkt_list);
  12.235  
  12.236 -  NdisAllocateBufferPool(&status, &xi->tx_buffer_pool, TX_SHARED_BUFFERS);
  12.237 +  NdisAllocateBufferPool(&status, &xi->tx_buffer_pool, TX_HEADER_BUFFERS);
  12.238    if (status != NDIS_STATUS_SUCCESS)
  12.239    {
  12.240      KdPrint(("NdisAllocateBufferPool failed with 0x%x\n", status));
  12.241 @@ -523,19 +521,19 @@ XenNet_TxInit(xennet_info_t *xi)
  12.242  
  12.243    xi->tx_ring_free = NET_TX_RING_SIZE;
  12.244  
  12.245 -  for (i = 0; i < TX_SHARED_BUFFERS / (PAGE_SIZE / TX_SHARED_BUFFER_SIZE); i++)
  12.246 +  for (i = 0; i < TX_HEADER_BUFFERS / (PAGE_SIZE / TX_HEADER_BUFFER_SIZE); i++)
  12.247    {
  12.248      PVOID virtual;
  12.249      NDIS_PHYSICAL_ADDRESS logical;
  12.250      NdisMAllocateSharedMemory(xi->adapter_handle, PAGE_SIZE, TRUE, &virtual, &logical);
  12.251 -    KdPrint((__DRIVER_NAME "     Allocated SharedMemory at %p\n", virtual));
  12.252 -    for (j = 0; j < PAGE_SIZE / TX_SHARED_BUFFER_SIZE; j++)
  12.253 +    //KdPrint((__DRIVER_NAME "     Allocated SharedMemory at %p\n", virtual));
  12.254 +    for (j = 0; j < PAGE_SIZE / TX_HEADER_BUFFER_SIZE; j++)
  12.255      {
  12.256 -      ULONG index = i * (PAGE_SIZE / TX_SHARED_BUFFER_SIZE) + j;
  12.257 -      xi->tx_sbs[index].id = index;
  12.258 -      xi->tx_sbs[index].virtual = (PUCHAR)virtual + j * TX_SHARED_BUFFER_SIZE;
  12.259 -      xi->tx_sbs[index].logical.QuadPart = logical.QuadPart + j * TX_SHARED_BUFFER_SIZE;
  12.260 -      put_sb_on_freelist(xi, &xi->tx_sbs[index]);
  12.261 +      USHORT index = i * (PAGE_SIZE / TX_HEADER_BUFFER_SIZE) + j;
  12.262 +      xi->tx_hbs[index].id = index;
  12.263 +      xi->tx_hbs[index].virtual = (PUCHAR)virtual + j * TX_HEADER_BUFFER_SIZE;
  12.264 +      xi->tx_hbs[index].logical.QuadPart = logical.QuadPart + j * TX_HEADER_BUFFER_SIZE;
  12.265 +      put_hb_on_freelist(xi, &xi->tx_hbs[index]);
  12.266      }
  12.267    }
  12.268  
    13.1 --- a/xenpci/evtchn.c	Tue Jan 27 00:47:02 2009 +1100
    13.2 +++ b/xenpci/evtchn.c	Sat Feb 14 13:35:48 2009 +1100
    13.3 @@ -48,7 +48,7 @@ EvtChn_DpcBounce(PRKDPC Dpc, PVOID Conte
    13.4  
    13.5    //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    13.6  
    13.7 -  if (action->type == EVT_ACTION_TYPE_DPC)
    13.8 +  if (action->type != EVT_ACTION_TYPE_EMPTY)
    13.9    {
   13.10      action->ServiceRoutine(action->ServiceContext);
   13.11    }
   13.12 @@ -73,8 +73,8 @@ EvtChn_AckEvent(PVOID context, evtchn_po
   13.13    return (BOOLEAN)!!val;
   13.14  }
   13.15  
   13.16 -static DDKAPI BOOLEAN
   13.17 -EvtChn_Interrupt(PKINTERRUPT Interrupt, PVOID Context)
   13.18 +BOOLEAN
   13.19 +EvtChn_EvtInterruptIsr(WDFINTERRUPT interrupt, ULONG message_id)
   13.20  {
   13.21  /*
   13.22  For HVM domains, Xen always triggers the event on CPU0. Because the
   13.23 @@ -83,7 +83,7 @@ to CPU != 0, but we should always use vc
   13.24  */
   13.25    int cpu = 0;
   13.26    vcpu_info_t *vcpu_info;
   13.27 -  PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)Context;
   13.28 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(WdfInterruptGetDevice(interrupt));
   13.29    shared_info_t *shared_info_area = xpdd->shared_info_area;
   13.30    xen_ulong_t evt_words;
   13.31    unsigned long evt_word;
   13.32 @@ -94,13 +94,13 @@ to CPU != 0, but we should always use vc
   13.33    BOOLEAN deferred = FALSE;
   13.34    int i;
   13.35  
   13.36 -  if (xpdd->log_interrupts)
   13.37 +  UNREFERENCED_PARAMETER(message_id);
   13.38 +
   13.39 +  if (xpdd->interrupts_masked)
   13.40    {
   13.41 -    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (cpu = %d)\n", KeGetCurrentProcessorNumber()));
   13.42 +    KdPrint((__DRIVER_NAME "     unhandled interrupt\n"));
   13.43    }
   13.44  
   13.45 -  UNREFERENCED_PARAMETER(Interrupt);
   13.46 -
   13.47    for (i = 0; i < ARRAY_SIZE(xpdd->evtchn_pending_pvt); i++)
   13.48    {
   13.49      if (xpdd->evtchn_pending_pvt[i])
   13.50 @@ -116,7 +116,6 @@ to CPU != 0, but we should always use vc
   13.51  
   13.52    if (xpdd->interrupts_masked)
   13.53    {
   13.54 -    KdPrint((__DRIVER_NAME "     unhandled interrupt\n"));
   13.55      return TRUE;
   13.56    }
   13.57    
   13.58 @@ -148,7 +147,7 @@ to CPU != 0, but we should always use vc
   13.59          KeInsertQueueDpc(&ev_action->Dpc, NULL, NULL);
   13.60          break;
   13.61        case EVT_ACTION_TYPE_SUSPEND:
   13.62 -        //KdPrint((__DRIVER_NAME "     EVT_ACTION_TYPE_SUSPEND\n"));
   13.63 +        KdPrint((__DRIVER_NAME "     EVT_ACTION_TYPE_SUSPEND\n"));
   13.64          for (i = 0; i < ARRAY_SIZE(xpdd->evtchn_pending_pvt); i++)
   13.65          {
   13.66            if (xpdd->ev_actions[i].type == EVT_ACTION_TYPE_IRQ)
   13.67 @@ -162,6 +161,7 @@ to CPU != 0, but we should always use vc
   13.68              xpdd->ev_actions[i].ServiceRoutine(xpdd->ev_actions[i].ServiceContext);
   13.69            }
   13.70          }
   13.71 +        KeInsertQueueDpc(&ev_action->Dpc, NULL, NULL);
   13.72          deferred = TRUE;
   13.73          break;
   13.74        default:
   13.75 @@ -171,12 +171,35 @@ to CPU != 0, but we should always use vc
   13.76      }
   13.77    }
   13.78  
   13.79 -  if (xpdd->log_interrupts)
   13.80 -  {
   13.81 -    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   13.82 -  }
   13.83 +  return handled && !deferred;
   13.84 +}
   13.85  
   13.86 -  return handled && !deferred;
   13.87 +NTSTATUS
   13.88 +EvtChn_EvtInterruptEnable(WDFINTERRUPT interrupt, WDFDEVICE device)
   13.89 +{
   13.90 +  NTSTATUS status = STATUS_SUCCESS;
   13.91 +  
   13.92 +  UNREFERENCED_PARAMETER(interrupt);
   13.93 +  UNREFERENCED_PARAMETER(device);
   13.94 +
   13.95 +  FUNCTION_ENTER();
   13.96 +  FUNCTION_EXIT();
   13.97 +
   13.98 +  return status;
   13.99 +}
  13.100 +
  13.101 +NTSTATUS
  13.102 +EvtChn_EvtInterruptDisable(WDFINTERRUPT interrupt, WDFDEVICE device)
  13.103 +{
  13.104 +  NTSTATUS status = STATUS_SUCCESS;
  13.105 +  
  13.106 +  UNREFERENCED_PARAMETER(interrupt);
  13.107 +  UNREFERENCED_PARAMETER(device);
  13.108 +
  13.109 +  FUNCTION_ENTER();
  13.110 +  FUNCTION_EXIT();
  13.111 +
  13.112 +  return status;
  13.113  }
  13.114  
  13.115  NTSTATUS
  13.116 @@ -346,9 +369,20 @@ EvtChn_Close(PVOID Context, evtchn_port_
  13.117    return;
  13.118  }
  13.119  
  13.120 +VOID
  13.121 +EvtChn_PdoEventChannelDpc(PVOID context)
  13.122 +{
  13.123 +  PXENPCI_DEVICE_DATA xpdd = context;
  13.124 +  
  13.125 +  FUNCTION_ENTER();
  13.126 +  KeSetEvent(&xpdd->pdo_suspend_event, IO_NO_INCREMENT, FALSE);
  13.127 +  FUNCTION_EXIT();
  13.128 +}
  13.129 +
  13.130  NTSTATUS
  13.131  EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
  13.132  {
  13.133 +  ULONGLONG result;
  13.134    int i;
  13.135  
  13.136    FUNCTION_ENTER();
  13.137 @@ -374,16 +408,18 @@ EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
  13.138  
  13.139    KeMemoryBarrier();
  13.140  
  13.141 -  hvm_set_parameter(xpdd, HVM_PARAM_CALLBACK_IRQ, xpdd->irq_number);
  13.142 +  result = hvm_set_parameter(xpdd, HVM_PARAM_CALLBACK_IRQ, xpdd->irq_number);
  13.143 +  KdPrint((__DRIVER_NAME "     hvm_set_parameter(HVM_PARAM_CALLBACK_IRQ, %d) = %d\n", xpdd->irq_number, (ULONG)result));
  13.144  
  13.145    for (i = 0; i < MAX_VIRT_CPUS; i++)
  13.146      xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 0;  
  13.147    xpdd->interrupts_masked = FALSE;
  13.148    KeMemoryBarrier();
  13.149  
  13.150 +  KeInitializeEvent(&xpdd->pdo_suspend_event, SynchronizationEvent, FALSE);
  13.151    xpdd->pdo_event_channel = EvtChn_AllocIpi(xpdd, 0);
  13.152 -  xpdd->ev_actions[xpdd->pdo_event_channel].type = EVT_ACTION_TYPE_SUSPEND;
  13.153 -  EvtChn_Unmask(xpdd, xpdd->pdo_event_channel);
  13.154 +  EvtChn_BindDpc(xpdd, xpdd->pdo_event_channel, EvtChn_PdoEventChannelDpc, xpdd);
  13.155 +  xpdd->ev_actions[xpdd->pdo_event_channel].type = EVT_ACTION_TYPE_SUSPEND; /* override dpc type */
  13.156    
  13.157    KdPrint((__DRIVER_NAME "     pdo_event_channel = %d\n", xpdd->pdo_event_channel));
  13.158  
  13.159 @@ -393,36 +429,7 @@ EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
  13.160  }
  13.161  
  13.162  NTSTATUS
  13.163 -EvtChn_ConnectInterrupt(PXENPCI_DEVICE_DATA xpdd)
  13.164 -{
  13.165 -  NTSTATUS status = STATUS_SUCCESS;
  13.166 -  
  13.167 -  ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
  13.168 -
  13.169 -  status = IoConnectInterrupt(
  13.170 -    &xpdd->interrupt,
  13.171 -  	EvtChn_Interrupt,
  13.172 -  	xpdd,
  13.173 -  	NULL,
  13.174 -  	xpdd->irq_vector,
  13.175 -  	xpdd->irq_level,
  13.176 -  	xpdd->irq_level,
  13.177 -  	xpdd->irq_mode, //LevelSensitive,
  13.178 -  	TRUE,
  13.179 -  	xpdd->irq_affinity,
  13.180 -  	FALSE);
  13.181 -  
  13.182 -  if (!NT_SUCCESS(status))
  13.183 -  {
  13.184 -    KdPrint((__DRIVER_NAME "     IoConnectInterrupt failed 0x%08x\n", status));
  13.185 -    return status;
  13.186 -  }
  13.187 -
  13.188 -  return status;
  13.189 -}
  13.190 -
  13.191 -NTSTATUS
  13.192 -EvtChn_Shutdown(PXENPCI_DEVICE_DATA xpdd)
  13.193 +EvtChn_Suspend(PXENPCI_DEVICE_DATA xpdd)
  13.194  {
  13.195    int i;
  13.196  //  LARGE_INTEGER wait_time;
  13.197 @@ -446,3 +453,9 @@ EvtChn_Shutdown(PXENPCI_DEVICE_DATA xpdd
  13.198  
  13.199    return STATUS_SUCCESS;
  13.200  }
  13.201 +
  13.202 +NTSTATUS
  13.203 +EvtChn_Resume(PXENPCI_DEVICE_DATA xpdd)
  13.204 +{
  13.205 +  return EvtChn_Init(xpdd);
  13.206 +}
  13.207 \ No newline at end of file
    14.1 --- a/xenpci/gnttbl.c	Tue Jan 27 00:47:02 2009 +1100
    14.2 +++ b/xenpci/gnttbl.c	Sat Feb 14 13:35:48 2009 +1100
    14.3 @@ -125,27 +125,6 @@ GntTbl_GrantAccess(
    14.4    return ref;
    14.5  }
    14.6  
    14.7 -#ifdef __MINGW32__
    14.8 -/* from linux/include/asm-i386/cmpxchg.h */
    14.9 -static inline short InterlockedCompareExchange16(
   14.10 -  short volatile *dest,
   14.11 -  short exch,
   14.12 -  short comp)
   14.13 -{
   14.14 -  unsigned long prev;
   14.15 -
   14.16 -  __asm__ __volatile__("lock;"
   14.17 -    "cmpxchgw %w1,%2"
   14.18 -    : "=a"(prev)
   14.19 -    : "r"(exch), "m"(*(dest)), "0"(comp)
   14.20 -    : "memory");
   14.21 -
   14.22 -  FUNCTION_MSG(("Check that I work as expected!\n"));
   14.23 -
   14.24 -  return prev;
   14.25 -}
   14.26 -#endif
   14.27 -
   14.28  BOOLEAN
   14.29  GntTbl_EndAccess(
   14.30    PVOID Context,
   14.31 @@ -183,7 +162,7 @@ GntTbl_QueryMaxFrames(PXENPCI_DEVICE_DAT
   14.32  
   14.33    query.dom = DOMID_SELF;
   14.34  
   14.35 -  rc = HYPERVISOR_grant_table_op(xpdd,GNTTABOP_query_size, &query, 1);
   14.36 +  rc = HYPERVISOR_grant_table_op(xpdd, GNTTABOP_query_size, &query, 1);
   14.37    if ((rc < 0) || (query.status != GNTST_okay))
   14.38    {
   14.39      KdPrint((__DRIVER_NAME "     ***CANNOT QUERY MAX GRANT FRAME***\n"));
   14.40 @@ -193,61 +172,66 @@ GntTbl_QueryMaxFrames(PXENPCI_DEVICE_DAT
   14.41  }
   14.42  
   14.43  VOID
   14.44 -GntTbl_InitMap(PXENPCI_DEVICE_DATA xpdd)
   14.45 +GntTbl_Init(PXENPCI_DEVICE_DATA xpdd)
   14.46  {
   14.47    int i;
   14.48 -  ULONG grant_frames;
   14.49    int grant_entries;
   14.50 -  //KdPrint((__DRIVER_NAME " --> GntTbl_Init\n"));
   14.51 -
   14.52 -  grant_frames = GntTbl_QueryMaxFrames(xpdd);
   14.53 -  grant_entries = min(NR_GRANT_ENTRIES, (grant_frames * PAGE_SIZE / sizeof(grant_entry_t)));
   14.54 -  KdPrint((__DRIVER_NAME "     grant_entries : %d\n", grant_entries));
   14.55 +  
   14.56 +  FUNCTION_ENTER();
   14.57 +  
   14.58 +  KeInitializeSpinLock(&xpdd->grant_lock);
   14.59  
   14.60 -  if (xpdd->gnttab_list)
   14.61 +  xpdd->grant_frames = GntTbl_QueryMaxFrames(xpdd);
   14.62 +  KdPrint((__DRIVER_NAME "     grant_frames = %d\n", xpdd->grant_frames));
   14.63 +  grant_entries = min(NR_GRANT_ENTRIES, (xpdd->grant_frames * PAGE_SIZE / sizeof(grant_entry_t)));
   14.64 +  KdPrint((__DRIVER_NAME "     grant_entries = %d\n", grant_entries));
   14.65 +  
   14.66 +  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
   14.67 +  xpdd->gnttab_table_copy = ExAllocatePoolWithTag(NonPagedPool, xpdd->grant_frames * PAGE_SIZE, XENPCI_POOL_TAG);
   14.68 +  ASSERT(xpdd->gnttab_table_copy); // lazy
   14.69 +  xpdd->gnttab_list = ExAllocatePoolWithTag(NonPagedPool, sizeof(grant_ref_t) * grant_entries, XENPCI_POOL_TAG);
   14.70 +  ASSERT(xpdd->gnttab_list); // lazy
   14.71 +  xpdd->gnttab_table_physical = XenPci_AllocMMIO(xpdd, PAGE_SIZE * xpdd->grant_frames);
   14.72 +  xpdd->gnttab_table = MmMapIoSpace(xpdd->gnttab_table_physical, PAGE_SIZE * xpdd->grant_frames, MmNonCached);
   14.73 +  if (!xpdd->gnttab_table)
   14.74    {
   14.75 -    if (grant_frames > xpdd->max_grant_frames)
   14.76 -    {
   14.77 -      ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
   14.78 -      /* this won't actually work as it will be called at HIGH_IRQL and the free and unmap functions won't work... */
   14.79 -      ExFreePoolWithTag(xpdd->gnttab_list, XENPCI_POOL_TAG);
   14.80 -      MmUnmapIoSpace(xpdd->gnttab_table, PAGE_SIZE * xpdd->max_grant_frames);
   14.81 -      xpdd->gnttab_list = NULL;
   14.82 -    }
   14.83 +    KdPrint((__DRIVER_NAME "     Error Mapping Grant Table Shared Memory\n"));
   14.84 +    // this should be a show stopper...
   14.85 +    return;
   14.86    }
   14.87    
   14.88 -  if (!xpdd->gnttab_list)
   14.89 -  {
   14.90 -    ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
   14.91 -    xpdd->gnttab_list = ExAllocatePoolWithTag(NonPagedPool, sizeof(grant_ref_t) * grant_entries, XENPCI_POOL_TAG);
   14.92 -    xpdd->gnttab_table_physical = XenPci_AllocMMIO(xpdd,
   14.93 -      PAGE_SIZE * grant_frames);
   14.94 -    xpdd->gnttab_table = MmMapIoSpace(xpdd->gnttab_table_physical,
   14.95 -      PAGE_SIZE * grant_frames, MmNonCached);
   14.96 -    if (!xpdd->gnttab_table)
   14.97 -    {
   14.98 -      KdPrint((__DRIVER_NAME "     Error Mapping Grant Table Shared Memory\n"));
   14.99 -      // this should be a show stopper...
  14.100 -      return;
  14.101 -    }
  14.102 -    xpdd->max_grant_frames = grant_frames;
  14.103 -  }
  14.104    RtlZeroMemory(xpdd->gnttab_list, sizeof(grant_ref_t) * grant_entries);
  14.105    xpdd->gnttab_list_free = 0;
  14.106    for (i = NR_RESERVED_ENTRIES; i < grant_entries; i++)
  14.107      GntTbl_PutRef(xpdd, i);
  14.108    
  14.109 -  GntTbl_Map(xpdd, 0, grant_frames - 1);
  14.110 -  RtlZeroMemory(xpdd->gnttab_table, PAGE_SIZE * grant_frames);
  14.111 +  GntTbl_Map(xpdd, 0, xpdd->grant_frames - 1);
  14.112 +
  14.113 +  RtlZeroMemory(xpdd->gnttab_table, PAGE_SIZE * xpdd->grant_frames);
  14.114 +  
  14.115 +  FUNCTION_EXIT();
  14.116  }
  14.117  
  14.118  VOID
  14.119 -GntTbl_Init(PXENPCI_DEVICE_DATA xpdd)
  14.120 +GntTbl_Suspend(PXENPCI_DEVICE_DATA xpdd)
  14.121  {
  14.122 -  //KdPrint((__DRIVER_NAME " --> GntTbl_Init\n"));
  14.123 +  memcpy(xpdd->gnttab_table_copy, xpdd->gnttab_table, xpdd->grant_frames * PAGE_SIZE);
  14.124 +}
  14.125 +
  14.126 +VOID
  14.127 +GntTbl_Resume(PXENPCI_DEVICE_DATA xpdd)
  14.128 +{
  14.129 +  ULONG new_grant_frames;
  14.130 +  ULONG result;
  14.131    
  14.132 -  KeInitializeSpinLock(&xpdd->grant_lock);
  14.133 -  GntTbl_InitMap(xpdd);
  14.134 +  FUNCTION_ENTER();
  14.135    
  14.136 -  //KdPrint((__DRIVER_NAME " <-- GntTbl_Init table mapped at %p\n", gnttab_table));
  14.137 +  new_grant_frames = GntTbl_QueryMaxFrames(xpdd);
  14.138 +  KdPrint((__DRIVER_NAME "     new_grant_frames = %d\n", new_grant_frames));
  14.139 +  ASSERT(new_grant_frames >= xpdd->grant_frames); // lazy
  14.140 +  result = GntTbl_Map(xpdd, 0, xpdd->grant_frames - 1);
  14.141 +  KdPrint((__DRIVER_NAME "     GntTbl_Map result = %d\n", result));
  14.142 +  memcpy(xpdd->gnttab_table, xpdd->gnttab_table_copy, xpdd->grant_frames * PAGE_SIZE);
  14.143 +  
  14.144 +  FUNCTION_EXIT();
  14.145  }
    15.1 --- a/xenpci/makefile.inc	Tue Jan 27 00:47:02 2009 +1100
    15.2 +++ b/xenpci/makefile.inc	Sat Feb 14 13:35:48 2009 +1100
    15.3 @@ -1,5 +1,5 @@
    15.4  _LNG=$(LANGUAGE)
    15.5 -STAMP=stampinf -f $@ -a $(_BUILDARCH) -d * -v $(VERSION)
    15.6 +STAMP=stampinf -f $@ -a $(_BUILDARCH) -d * -v $(VERSION) -k $(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR)
    15.7  
    15.8  $(INF_NAME).inf: $(INF_NAME).inx sources ..\common.inc
    15.9      copy $(@B).inx $@
    16.1 --- a/xenpci/memory.c	Tue Jan 27 00:47:02 2009 +1100
    16.2 +++ b/xenpci/memory.c	Sat Feb 14 13:35:48 2009 +1100
    16.3 @@ -1,8 +1,5 @@
    16.4  #include "xenpci.h"
    16.5  
    16.6 -//static pgentry_t *demand_map_pgt;
    16.7 -//static void *demand_map_area_start;
    16.8 -
    16.9  /* must be called at <= DISPATCH_LEVEL if hypercall_stubs == NULL */
   16.10  
   16.11  NTSTATUS
   16.12 @@ -19,26 +16,25 @@ hvm_get_stubs(PXENPCI_DEVICE_DATA xpdd)
   16.13    *(ULONG*)(xensig + 4) = cpuid_output[2];
   16.14    *(ULONG*)(xensig + 8) = cpuid_output[3];
   16.15    xensig[12] = '\0';
   16.16 -  KdPrint((__DRIVER_NAME " Xen Signature = %s, EAX = 0x%08x\n", xensig, cpuid_output[0]));
   16.17 +  KdPrint((__DRIVER_NAME "     Xen Signature = %s, EAX = 0x%08x\n", xensig, cpuid_output[0]));
   16.18  
   16.19    __cpuid(cpuid_output, 0x40000002);
   16.20    pages = cpuid_output[0];
   16.21    msr = cpuid_output[1];
   16.22 -  //KdPrint((__DRIVER_NAME " Hypercall area is %u pages.\n", pages));
   16.23  
   16.24    if (!xpdd->hypercall_stubs)
   16.25    {
   16.26      ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
   16.27      xpdd->hypercall_stubs = ExAllocatePoolWithTag(NonPagedPool, pages * PAGE_SIZE, XENPCI_POOL_TAG);
   16.28    }
   16.29 -  KdPrint((__DRIVER_NAME " Hypercall area at %p\n", xpdd->hypercall_stubs));
   16.30 +  KdPrint((__DRIVER_NAME "     Hypercall area at %p\n", xpdd->hypercall_stubs));
   16.31  
   16.32    if (!xpdd->hypercall_stubs)
   16.33      return 1;
   16.34    for (i = 0; i < pages; i++) {
   16.35      ULONGLONG pfn;
   16.36      pfn = (MmGetPhysicalAddress(xpdd->hypercall_stubs + i * PAGE_SIZE).QuadPart >> PAGE_SHIFT);
   16.37 -    KdPrint((__DRIVER_NAME " pfn = %16lX\n", pfn));
   16.38 +    KdPrint((__DRIVER_NAME "     pfn = %16lX\n", pfn));
   16.39      __writemsr(msr, (pfn << PAGE_SHIFT) + i);
   16.40    }
   16.41    return STATUS_SUCCESS;
   16.42 @@ -51,40 +47,3 @@ hvm_free_stubs(PXENPCI_DEVICE_DATA xpdd)
   16.43  
   16.44    return STATUS_SUCCESS;
   16.45  }
   16.46 -
   16.47 -#if 0
   16.48 -PVOID
   16.49 -map_frames(PULONG f, ULONG n)
   16.50 -{
   16.51 -  unsigned long x;
   16.52 -  unsigned long y = 0;
   16.53 -  mmu_update_t mmu_updates[16];
   16.54 -  int rc;
   16.55 - 
   16.56 -  for (x = 0; x <= 1024 - n; x += y + 1) {
   16.57 -    for (y = 0; y < n; y++)
   16.58 -      if (demand_map_pgt[x+y] & _PAGE_PRESENT)
   16.59 -        break;
   16.60 -    if (y == n)
   16.61 -      break;
   16.62 -  }
   16.63 -  if (y != n) {
   16.64 -      KdPrint((__DRIVER_NAME " Failed to map %ld frames!\n", n));
   16.65 -      return NULL;
   16.66 -  }
   16.67 -
   16.68 -  for (y = 0; y < n; y++) {
   16.69 -    //mmu_updates[y].ptr = virt_to_mach(&demand_map_pgt[x + y]);
   16.70 -    mmu_updates[y].ptr = MmGetPhysicalAddress(&demand_map_pgt[x + y]).QuadPart;
   16.71 -    mmu_updates[y].val = (f[y] << PAGE_SHIFT) | L1_PROT;
   16.72 -  }
   16.73 -
   16.74 -  rc = HYPERVISOR_mmu_update(mmu_updates, n, NULL, DOMID_SELF);
   16.75 -  if (rc < 0) {
   16.76 -    KdPrint((__DRIVER_NAME " Map %ld failed: %d.\n", n, rc));
   16.77 -    return NULL;
   16.78 -  } else {
   16.79 -    return (PVOID)(ULONG)((ULONG)demand_map_area_start + x * PAGE_SIZE);
   16.80 -  }
   16.81 -}
   16.82 -#endif
    17.1 --- a/xenpci/sources	Tue Jan 27 00:47:02 2009 +1100
    17.2 +++ b/xenpci/sources	Sat Feb 14 13:35:48 2009 +1100
    17.3 @@ -1,8 +1,9 @@
    17.4  !INCLUDE ..\common.inc
    17.5  TARGETNAME=xenpci
    17.6  TARGETTYPE=DRIVER
    17.7 +KMDF_VERSION_MAJOR=1
    17.8  INF_NAME=$(TARGETNAME)
    17.9 -MISCFILES=..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf
   17.10 +MISCFILES=$(INF_NAME).inf
   17.11  TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\wdmsec.lib $(DDK_LIB_PATH)\Rtlver.lib $(DDK_LIB_PATH)\aux_klib.lib
   17.12  AMD64_SOURCES=hypercall.asm
   17.13  I386_SOURCES=tpr_emulate.asm
    18.1 --- a/xenpci/xenbus.c	Tue Jan 27 00:47:02 2009 +1100
    18.2 +++ b/xenpci/xenbus.c	Sat Feb 14 13:35:48 2009 +1100
    18.3 @@ -162,6 +162,8 @@ XenBus_Raw(
    18.4    struct xsd_sockmsg *msg)
    18.5  {
    18.6    struct xsd_sockmsg *reply;
    18.7 +  
    18.8 +  FUNCTION_ENTER();
    18.9  
   18.10    ExAcquireFastMutex(&xpdd->xb_request_mutex);
   18.11    xb_write(xpdd, msg, sizeof(struct xsd_sockmsg) + msg->len);
   18.12 @@ -170,6 +172,8 @@ XenBus_Raw(
   18.13    xpdd->xb_reply = NULL;
   18.14    ExReleaseFastMutex(&xpdd->xb_request_mutex);  
   18.15  
   18.16 +  FUNCTION_EXIT();
   18.17 +    
   18.18    return reply;
   18.19  }
   18.20  
   18.21 @@ -248,11 +252,11 @@ XenBus_Dpc(PVOID ServiceContext)
   18.22  {
   18.23    PXENPCI_DEVICE_DATA xpdd = ServiceContext;
   18.24  
   18.25 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   18.26 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   18.27  
   18.28    KeSetEvent(&xpdd->XenBus_ReadThreadEvent, IO_NO_INCREMENT, FALSE);
   18.29  
   18.30 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   18.31 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   18.32  
   18.33    return;
   18.34  }
   18.35 @@ -268,9 +272,6 @@ XenBus_Connect(PXENPCI_DEVICE_DATA xpdd)
   18.36    pa_xen_store_interface.QuadPart = (ULONGLONG)xen_store_mfn << PAGE_SHIFT;
   18.37    xpdd->xen_store_interface = MmMapIoSpace(pa_xen_store_interface, PAGE_SIZE, MmNonCached);
   18.38  
   18.39 -  EvtChn_BindDpc(xpdd, xpdd->xen_store_evtchn, XenBus_Dpc, xpdd);
   18.40 -
   18.41 -  xpdd->XenBus_ShuttingDown = FALSE;
   18.42    KeMemoryBarrier();
   18.43    
   18.44    return STATUS_SUCCESS;
   18.45 @@ -299,13 +300,12 @@ XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
   18.46    KeInitializeEvent(&xpdd->XenBus_WatchThreadEvent, SynchronizationEvent, FALSE);
   18.47    KeInitializeEvent(&xpdd->xb_request_complete_event, SynchronizationEvent, FALSE);
   18.48  
   18.49 -  xpdd->XenBus_ShuttingDown = FALSE;
   18.50 -
   18.51    status = XenBus_Connect(xpdd);
   18.52    if (!NT_SUCCESS(status))
   18.53    {
   18.54      return status;
   18.55    }
   18.56 +  EvtChn_BindDpc(xpdd, xpdd->xen_store_evtchn, XenBus_Dpc, xpdd);
   18.57  
   18.58    status = PsCreateSystemThread(&thread_handle, THREAD_ALL_ACCESS, NULL, NULL, NULL, XenBus_ReadThreadProc, xpdd);
   18.59    if (!NT_SUCCESS(status))
   18.60 @@ -313,7 +313,6 @@ XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
   18.61      KdPrint((__DRIVER_NAME "     Could not start read thread\n"));
   18.62      return status;
   18.63    }
   18.64 -  KdPrint((__DRIVER_NAME "    Started ReadThread\n"));
   18.65    
   18.66    status = ObReferenceObjectByHandle(thread_handle, THREAD_ALL_ACCESS, NULL, KernelMode, &xpdd->XenBus_ReadThread, NULL);
   18.67    ZwClose(thread_handle);
   18.68 @@ -329,7 +328,6 @@ XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
   18.69      KdPrint((__DRIVER_NAME " Could not start watch thread\n"));
   18.70      return status;
   18.71    }
   18.72 -  KdPrint((__DRIVER_NAME "    Started WatchThread\n"));
   18.73    status = ObReferenceObjectByHandle(thread_handle, THREAD_ALL_ACCESS, NULL, KernelMode, &xpdd->XenBus_WatchThread, NULL);
   18.74    ZwClose(thread_handle);
   18.75    if (!NT_SUCCESS(status))
   18.76 @@ -475,7 +473,7 @@ XenBus_ReadThreadProc(PVOID StartContext
   18.77    for(;;)
   18.78    {
   18.79      KeWaitForSingleObject(&xpdd->XenBus_ReadThreadEvent, Executive, KernelMode, FALSE, NULL);
   18.80 -    //Print((__DRIVER_NAME " +++ thread woken\n"));
   18.81 +    //KdPrint((__DRIVER_NAME " +++ thread woken\n"));
   18.82      if (xpdd->XenBus_ShuttingDown)
   18.83      {
   18.84        KdPrint((__DRIVER_NAME "     Shutdown detected in ReadThreadProc\n"));
   18.85 @@ -483,7 +481,7 @@ XenBus_ReadThreadProc(PVOID StartContext
   18.86      }
   18.87      while (xpdd->xen_store_interface->rsp_prod != xpdd->xen_store_interface->rsp_cons)
   18.88      {
   18.89 -      //KdPrint((__DRIVER_NAME "     a - Rsp_cons %d, rsp_prod %d.\n", xen_store_interface->rsp_cons, xen_store_interface->rsp_prod));
   18.90 +      //KdPrint((__DRIVER_NAME "     a - Rsp_cons %d, rsp_prod %d.\n", xpdd->xen_store_interface->rsp_cons, xpdd->xen_store_interface->rsp_prod));
   18.91        if (xpdd->xen_store_interface->rsp_prod - xpdd->xen_store_interface->rsp_cons < sizeof(msg))
   18.92        {
   18.93          //KdPrint((__DRIVER_NAME " +++ Message incomplete (not even a full header)\n"));
   18.94 @@ -527,7 +525,7 @@ XenBus_ReadThreadProc(PVOID StartContext
   18.95          }
   18.96          else
   18.97          {
   18.98 -          //KdPrint((__DRIVER_NAME " +++ Queue full Path = %s Token = %s\n", path, token));
   18.99 +          KdPrint((__DRIVER_NAME " +++ Queue full Path = %s Token = %s\n", path, token));
  18.100            // drop the message on the floor
  18.101            continue;
  18.102          }
  18.103 @@ -559,6 +557,7 @@ XenBus_WatchThreadProc(PVOID StartContex
  18.104      }
  18.105      while (xpdd->XenBus_WatchRingReadIndex != xpdd->XenBus_WatchRingWriteIndex)
  18.106      {
  18.107 +      //KdPrint((__DRIVER_NAME " +++ watch triggered\n"));
  18.108        xpdd->XenBus_WatchRingReadIndex = 
  18.109          (xpdd->XenBus_WatchRingReadIndex + 1) % WATCH_RING_SIZE;
  18.110        index = atoi(xpdd->XenBus_WatchRing[xpdd->XenBus_WatchRingReadIndex].Token);
  18.111 @@ -639,12 +638,13 @@ XenBus_Resume(PXENPCI_DEVICE_DATA xpdd)
  18.112    {
  18.113      return status;
  18.114    }
  18.115 +  EvtChn_BindDpc(xpdd, xpdd->xen_store_evtchn, XenBus_Dpc, xpdd);
  18.116    
  18.117    for (i = 0; i < MAX_WATCH_ENTRIES; i++)
  18.118    {
  18.119      if (xpdd->XenBus_WatchEntries[i].Active)
  18.120      {
  18.121 -      KdPrint((__DRIVER_NAME "     Adding watch for path = %s\n", xpdd->XenBus_WatchEntries[i].Path));
  18.122 +      //KdPrint((__DRIVER_NAME "     Adding watch for path = %s\n", xpdd->XenBus_WatchEntries[i].Path));
  18.123        XenBus_SendAddWatch(xpdd, XBT_NIL, xpdd->XenBus_WatchEntries[i].Path, i);
  18.124      }
  18.125    }
    19.1 --- a/xenpci/xenbus_device_interface.c	Tue Jan 27 00:47:02 2009 +1100
    19.2 +++ b/xenpci/xenbus_device_interface.c	Sat Feb 14 13:35:48 2009 +1100
    19.3 @@ -19,6 +19,361 @@ Foundation, Inc., 51 Franklin Street, Fi
    19.4  
    19.5  #include "xenpci.h"
    19.6  
    19.7 +
    19.8 +typedef struct {
    19.9 +  LIST_ENTRY entry;
   19.10 +  PVOID data;
   19.11 +  ULONG length;
   19.12 +  ULONG offset;
   19.13 +} xenbus_read_queue_item_t;
   19.14 +
   19.15 +typedef struct
   19.16 +{
   19.17 +  LIST_ENTRY entry;
   19.18 +  CHAR path[128];
   19.19 +  CHAR token[128];
   19.20 +  WDFFILEOBJECT file_object;
   19.21 +} watch_context_t;
   19.22 +
   19.23 +VOID
   19.24 +XenPci_EvtDeviceFileCreate(WDFDEVICE device, WDFREQUEST request, WDFFILEOBJECT file_object)
   19.25 +{
   19.26 +  NTSTATUS status;
   19.27 +  PXENPCI_DEVICE_INTERFACE_DATA xpdid = GetXpdid(file_object);
   19.28 +  WDF_IO_QUEUE_CONFIG queue_config;
   19.29 +  
   19.30 +  FUNCTION_ENTER();
   19.31 +  
   19.32 +  xpdid->type = DEVICE_INTERFACE_TYPE_XENBUS;
   19.33 +  KeInitializeSpinLock(&xpdid->lock);
   19.34 +  InitializeListHead(&xpdid->read_list_head);
   19.35 +  InitializeListHead(&xpdid->watch_list_head);
   19.36 +  xpdid->len = 0;
   19.37 +  WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchManual);
   19.38 +  //queue_config.EvtIoRead = XenPci_EvtIoRead;
   19.39 +  status = WdfIoQueueCreate(device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xpdid->io_queue);
   19.40 +  if (!NT_SUCCESS(status)) {
   19.41 +      KdPrint(("Error creating queue 0x%x\n", status));
   19.42 +      WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
   19.43 +  }
   19.44 +  //WdfIoQueueStop(xpdid->io_queue, NULL, NULL);
   19.45 +
   19.46 +  WdfRequestComplete(request, STATUS_SUCCESS);
   19.47 +  
   19.48 +  FUNCTION_EXIT();
   19.49 +}
   19.50 +
   19.51 +VOID
   19.52 +XenPci_ProcessReadRequest(WDFQUEUE queue, WDFREQUEST request, size_t length)
   19.53 +{
   19.54 +  NTSTATUS status;
   19.55 +  WDFFILEOBJECT file_object = WdfRequestGetFileObject(request);
   19.56 +  PXENPCI_DEVICE_INTERFACE_DATA xpdid = GetXpdid(file_object);
   19.57 +  ULONG dst_length = length;
   19.58 +  ULONG dst_offset = 0;
   19.59 +  ULONG copy_length;
   19.60 +  xenbus_read_queue_item_t *list_entry;
   19.61 +  PVOID buffer;
   19.62 +
   19.63 +  UNREFERENCED_PARAMETER(queue);
   19.64 +  
   19.65 +  status = WdfRequestRetrieveOutputBuffer(request, length, &buffer, NULL);
   19.66 +  if (!NT_SUCCESS(status))
   19.67 +  {
   19.68 +    KdPrint((__DRIVER_NAME, "     WdfRequestRetrieveOutputBuffer failed status = %08x\n", status));
   19.69 +    WdfRequestSetInformation(request, 0);
   19.70 +    return;
   19.71 +  }
   19.72 +  ASSERT(NT_SUCCESS(status)); // lazy?
   19.73 +
   19.74 +  while(dst_offset < dst_length && (list_entry = (xenbus_read_queue_item_t *)RemoveHeadList(&xpdid->read_list_head)) != (xenbus_read_queue_item_t *)&xpdid->read_list_head)
   19.75 +  {
   19.76 +    copy_length = min(list_entry->length - list_entry->offset, dst_length - dst_offset);
   19.77 +    memcpy((PUCHAR)buffer + dst_offset, (PUCHAR)list_entry->data + list_entry->offset, copy_length);
   19.78 +    list_entry->offset += copy_length;
   19.79 +    dst_offset += copy_length;
   19.80 +    if (list_entry->offset == list_entry->length)
   19.81 +    {
   19.82 +      // free the list entry
   19.83 +      // free the data
   19.84 +    }
   19.85 +    else
   19.86 +    {
   19.87 +      InsertHeadList(&xpdid->read_list_head, (PLIST_ENTRY)list_entry);
   19.88 +    }      
   19.89 +  }
   19.90 +  WdfRequestSetInformation(request, dst_offset);
   19.91 +  
   19.92 +  FUNCTION_EXIT();
   19.93 +}
   19.94 +
   19.95 +static VOID
   19.96 +XenPci_IoWatch(char *path, PVOID context)
   19.97 +{
   19.98 +  NTSTATUS status;
   19.99 +  watch_context_t *watch_context = context;
  19.100 +  WDFFILEOBJECT file_object = watch_context->file_object;
  19.101 +  PXENPCI_DEVICE_INTERFACE_DATA xpdid = GetXpdid(file_object);
  19.102 +  KIRQL old_irql;
  19.103 +  struct xsd_sockmsg *rep;
  19.104 +  xenbus_read_queue_item_t *list_entry;
  19.105 +  WDFREQUEST request;
  19.106 +
  19.107 +  FUNCTION_ENTER();
  19.108 +  
  19.109 +  KeAcquireSpinLock(&xpdid->lock, &old_irql);
  19.110 +  
  19.111 +  rep = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct xsd_sockmsg) + strlen(path) + 1 + strlen(watch_context->token) + 1, XENPCI_POOL_TAG);
  19.112 +  rep->type = XS_WATCH_EVENT;
  19.113 +  rep->req_id = 0;
  19.114 +  rep->tx_id = 0;
  19.115 +  rep->len = strlen(path) + 1 + strlen(watch_context->token) + 1;
  19.116 +  strcpy((PCHAR)(rep + 1), path);
  19.117 +  strcpy((PCHAR)(rep + 1) + strlen(path) + 1, watch_context->token);
  19.118 +  
  19.119 +  list_entry = (xenbus_read_queue_item_t *)ExAllocatePoolWithTag(NonPagedPool, sizeof(xenbus_read_queue_item_t), XENPCI_POOL_TAG);
  19.120 +  list_entry->data = rep;
  19.121 +  list_entry->length = sizeof(*rep) + rep->len;
  19.122 +  list_entry->offset = 0;
  19.123 +  InsertTailList(&xpdid->read_list_head, (PLIST_ENTRY)list_entry);
  19.124 +    
  19.125 +  status = WdfIoQueueRetrieveNextRequest(xpdid->io_queue, &request);
  19.126 +  if (NT_SUCCESS(status))
  19.127 +  {
  19.128 +    WDF_REQUEST_PARAMETERS parameters;
  19.129 +    WDF_REQUEST_PARAMETERS_INIT(&parameters);
  19.130 +    WdfRequestGetParameters(request, &parameters);
  19.131 +    
  19.132 +    KdPrint((__DRIVER_NAME "     found pending read - MinorFunction = %d, length = %d\n", (ULONG)parameters.MinorFunction, (ULONG)parameters.Parameters.Read.Length));
  19.133 +    XenPci_ProcessReadRequest(xpdid->io_queue, request, parameters.Parameters.Read.Length);
  19.134 +    KeReleaseSpinLock(&xpdid->lock, old_irql);
  19.135 +    WdfRequestComplete(request, STATUS_SUCCESS);
  19.136 +  }
  19.137 +  else
  19.138 +  {
  19.139 +    KdPrint((__DRIVER_NAME "     no pending read (%08x)\n", status));
  19.140 +    KeReleaseSpinLock(&xpdid->lock, old_irql);
  19.141 +  }
  19.142 +  
  19.143 +  FUNCTION_EXIT();
  19.144 +}
  19.145 +
  19.146 +VOID
  19.147 +XenPci_EvtFileCleanup(WDFFILEOBJECT file_object)
  19.148 +{
  19.149 +  PXENPCI_DEVICE_INTERFACE_DATA xpdid = GetXpdid(file_object);
  19.150 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(WdfFileObjectGetDevice(file_object));
  19.151 +  watch_context_t *watch_context;
  19.152 +  KIRQL old_irql;
  19.153 +  PCHAR msg;
  19.154 +
  19.155 +  FUNCTION_ENTER();
  19.156 +
  19.157 +  KeAcquireSpinLock(&xpdid->lock, &old_irql);
  19.158 +
  19.159 +  while (!IsListEmpty(&xpdid->watch_list_head))
  19.160 +  {
  19.161 +    watch_context = (watch_context_t *)RemoveHeadList(&xpdid->watch_list_head);
  19.162 +    KeReleaseSpinLock(&xpdid->lock, old_irql);
  19.163 +    msg = XenBus_RemWatch(xpdd, XBT_NIL, watch_context->path, XenPci_IoWatch, watch_context);
  19.164 +    if (msg != NULL)
  19.165 +    {
  19.166 +      KdPrint((__DRIVER_NAME "     Error freeing watch (%s)\n", msg));
  19.167 +      XenPci_FreeMem(msg);
  19.168 +    }
  19.169 +    ExFreePoolWithTag(watch_context, XENPCI_POOL_TAG);
  19.170 +    WdfObjectDereference(file_object);
  19.171 +    KeAcquireSpinLock(&xpdid->lock, &old_irql);
  19.172 +  }
  19.173 +
  19.174 +  KeReleaseSpinLock(&xpdid->lock, old_irql);
  19.175 +  
  19.176 +  FUNCTION_EXIT();
  19.177 +}
  19.178 +
  19.179 +VOID
  19.180 +XenPci_EvtFileClose(WDFFILEOBJECT file_object)
  19.181 +{
  19.182 +  UNREFERENCED_PARAMETER(file_object);
  19.183 +  FUNCTION_ENTER();
  19.184 +  FUNCTION_EXIT();
  19.185 +}
  19.186 +
  19.187 +VOID
  19.188 +XenPci_EvtIoRead(WDFQUEUE queue, WDFREQUEST request, size_t length)
  19.189 +{
  19.190 +  NTSTATUS status;
  19.191 +  WDFFILEOBJECT file_object = WdfRequestGetFileObject(request);
  19.192 +  PXENPCI_DEVICE_INTERFACE_DATA xpdid = GetXpdid(file_object);
  19.193 +  KIRQL old_irql;
  19.194 +
  19.195 +  FUNCTION_ENTER();
  19.196 +  status = WdfRequestForwardToIoQueue(request, xpdid->io_queue);
  19.197 +  if (!NT_SUCCESS(status))
  19.198 +  {
  19.199 +    KdPrint((__DRIVER_NAME "     could not forward request (%08x)\n", status));
  19.200 +  }
  19.201 +  KeAcquireSpinLock(&xpdid->lock, &old_irql);
  19.202 +  if (!IsListEmpty(&xpdid->read_list_head))
  19.203 +  {
  19.204 +    status = WdfIoQueueRetrieveNextRequest(xpdid->io_queue, &request);
  19.205 +    if (NT_SUCCESS(status))
  19.206 +    {
  19.207 +      KdPrint((__DRIVER_NAME "     found pending read\n"));
  19.208 +      XenPci_ProcessReadRequest(xpdid->io_queue, request, length);
  19.209 +      KeReleaseSpinLock(&xpdid->lock, old_irql);
  19.210 +      WdfRequestComplete(request, STATUS_SUCCESS);
  19.211 +    }
  19.212 +    else
  19.213 +    {
  19.214 +      KdPrint((__DRIVER_NAME "     no pending read (%08x)\n", status));
  19.215 +      KeReleaseSpinLock(&xpdid->lock, old_irql);
  19.216 +    }
  19.217 +  }
  19.218 +  else
  19.219 +  {
  19.220 +    KdPrint((__DRIVER_NAME "     no data to read\n"));
  19.221 +    KeReleaseSpinLock(&xpdid->lock, old_irql);
  19.222 +  }
  19.223 +  
  19.224 +  FUNCTION_EXIT();
  19.225 +  return;
  19.226 +}
  19.227 +
  19.228 +VOID
  19.229 +XenPci_EvtIoWrite(WDFQUEUE queue, WDFREQUEST request, size_t length)
  19.230 +{
  19.231 +  NTSTATUS status;
  19.232 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(WdfIoQueueGetDevice(queue));
  19.233 +  WDFFILEOBJECT file_object = WdfRequestGetFileObject(request);
  19.234 +  PXENPCI_DEVICE_INTERFACE_DATA xpdid = GetXpdid(file_object);
  19.235 +  KIRQL old_irql;
  19.236 +  PUCHAR buffer;
  19.237 +  PUCHAR src_ptr;
  19.238 +  ULONG src_len;
  19.239 +  PUCHAR dst_ptr;
  19.240 +  ULONG copy_len;
  19.241 +  struct xsd_sockmsg *rep;
  19.242 +  xenbus_read_queue_item_t *list_entry;
  19.243 +  watch_context_t *watch_context;
  19.244 +  PCHAR watch_path;
  19.245 +  PCHAR watch_token;
  19.246 +  PCHAR msg;
  19.247 +  
  19.248 +  FUNCTION_ENTER();
  19.249 +  
  19.250 +  status = WdfRequestRetrieveInputBuffer(request, length, &buffer, NULL);
  19.251 +  ASSERT(NT_SUCCESS(status));
  19.252 +  
  19.253 +  src_ptr = (PUCHAR)buffer;
  19.254 +  src_len = length;
  19.255 +  dst_ptr = xpdid->u.buffer + xpdid->len;
  19.256 +  while (src_len != 0)
  19.257 +  {
  19.258 +    KdPrint((__DRIVER_NAME "     %d bytes of write buffer remaining\n", src_len));
  19.259 +    /* get a complete msg header */
  19.260 +    if (xpdid->len < sizeof(xpdid->u.msg))
  19.261 +    {
  19.262 +      copy_len = min(sizeof(xpdid->u.msg) - xpdid->len, src_len);
  19.263 +      if (!copy_len)
  19.264 +        continue;
  19.265 +      memcpy(dst_ptr, src_ptr, copy_len);
  19.266 +      dst_ptr += copy_len;
  19.267 +      src_ptr += copy_len;
  19.268 +      src_len -= copy_len;
  19.269 +      xpdid->len += copy_len;
  19.270 +    }
  19.271 +    /* exit if we can't get that */
  19.272 +    if (xpdid->len < sizeof(xpdid->u.msg))
  19.273 +      continue;
  19.274 +    /* get a complete msg body */
  19.275 +    if (xpdid->len < sizeof(xpdid->u.msg) + xpdid->u.msg.len)
  19.276 +    {
  19.277 +      copy_len = min(sizeof(xpdid->u.msg) + xpdid->u.msg.len - xpdid->len, src_len);
  19.278 +      if (!copy_len)
  19.279 +        continue;
  19.280 +      memcpy(dst_ptr, src_ptr, copy_len);
  19.281 +      dst_ptr += copy_len;
  19.282 +      src_ptr += copy_len;
  19.283 +      src_len -= copy_len;
  19.284 +      xpdid->len += copy_len;
  19.285 +    }
  19.286 +    /* exit if we can't get that */
  19.287 +    if (xpdid->len < sizeof(xpdid->u.msg) + xpdid->u.msg.len)
  19.288 +    {
  19.289 +      continue;
  19.290 +    }
  19.291 +    
  19.292 +    switch (xpdid->u.msg.type)
  19.293 +    {
  19.294 +    case XS_WATCH:
  19.295 +    case XS_UNWATCH:
  19.296 +      KeAcquireSpinLock(&xpdid->lock, &old_irql);
  19.297 +      watch_context = (watch_context_t *)ExAllocatePoolWithTag(NonPagedPool, sizeof(watch_context_t), XENPCI_POOL_TAG);
  19.298 +      watch_path = xpdid->u.buffer + sizeof(struct xsd_sockmsg);
  19.299 +      watch_token = xpdid->u.buffer + sizeof(struct xsd_sockmsg) + strlen(watch_path) + 1;
  19.300 +      strcpy(watch_context->path, watch_path);
  19.301 +      strcpy(watch_context->token, watch_token);
  19.302 +      watch_context->file_object = file_object;
  19.303 +      if (xpdid->u.msg.type == XS_WATCH)
  19.304 +        InsertTailList(&xpdid->watch_list_head, &watch_context->entry);
  19.305 +      KeReleaseSpinLock(&xpdid->lock, old_irql);
  19.306 +      if (xpdid->u.msg.type == XS_WATCH)
  19.307 +        msg = XenBus_AddWatch(xpdd, XBT_NIL, watch_path, XenPci_IoWatch, watch_context);
  19.308 +      else
  19.309 +        msg = XenBus_RemWatch(xpdd, XBT_NIL, watch_path, XenPci_IoWatch, watch_context);
  19.310 +      KeAcquireSpinLock(&xpdid->lock, &old_irql);
  19.311 +      if (msg != NULL)
  19.312 +      {
  19.313 +        rep = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct xsd_sockmsg) + strlen(msg) + 1, XENPCI_POOL_TAG);
  19.314 +        rep->type = XS_ERROR;
  19.315 +        rep->req_id = xpdid->u.msg.req_id;
  19.316 +        rep->tx_id = xpdid->u.msg.tx_id;
  19.317 +        rep->len = strlen(msg) + 0;
  19.318 +        strcpy((PCHAR)(rep + 1), msg);
  19.319 +        if (xpdid->u.msg.type == XS_WATCH)
  19.320 +          RemoveEntryList(&watch_context->entry);
  19.321 +      }
  19.322 +      else
  19.323 +      {
  19.324 +        if (xpdid->u.msg.type == XS_WATCH)
  19.325 +        {
  19.326 +          WdfObjectReference(file_object);
  19.327 +        }
  19.328 +        else
  19.329 +        {
  19.330 +          RemoveEntryList(&watch_context->entry);
  19.331 +          WdfObjectDereference(file_object);
  19.332 +        }
  19.333 +        rep = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct xsd_sockmsg), XENPCI_POOL_TAG);
  19.334 +        rep->type = xpdid->u.msg.type;
  19.335 +        rep->req_id = xpdid->u.msg.req_id;
  19.336 +        rep->tx_id = xpdid->u.msg.tx_id;
  19.337 +        rep->len = 0;
  19.338 +      }
  19.339 +      KeReleaseSpinLock(&xpdid->lock, old_irql);
  19.340 +      break;
  19.341 +    default:
  19.342 +      rep = XenBus_Raw(xpdd, &xpdid->u.msg);
  19.343 +      break;
  19.344 +    }
  19.345 +    xpdid->len = 0;
  19.346 +    
  19.347 +    KeAcquireSpinLock(&xpdid->lock, &old_irql);
  19.348 +    list_entry = (xenbus_read_queue_item_t *)ExAllocatePoolWithTag(NonPagedPool, sizeof(xenbus_read_queue_item_t), XENPCI_POOL_TAG);
  19.349 +    list_entry->data = rep;
  19.350 +    list_entry->length = sizeof(*rep) + rep->len;
  19.351 +    list_entry->offset = 0;
  19.352 +    InsertTailList(&xpdid->read_list_head, (PLIST_ENTRY)list_entry);
  19.353 +    KeReleaseSpinLock(&xpdid->lock, old_irql);
  19.354 +  }
  19.355 +  KdPrint((__DRIVER_NAME "     completing request with length %d\n", length));
  19.356 +  WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, length);
  19.357 +
  19.358 +  FUNCTION_EXIT();
  19.359 +}
  19.360 +
  19.361 +#if 0
  19.362  NTSTATUS
  19.363  XenPci_Irp_Create_XenBus(PDEVICE_OBJECT device_object, PIRP irp)
  19.364  {
  19.365 @@ -63,13 +418,6 @@ XenPci_Irp_Close_XenBus(PDEVICE_OBJECT d
  19.366    return status;
  19.367  }
  19.368  
  19.369 -typedef struct {
  19.370 -  LIST_ENTRY entry;
  19.371 -  PVOID data;
  19.372 -  ULONG length;
  19.373 -  ULONG offset;
  19.374 -} xenbus_read_queue_item_t;
  19.375 -
  19.376  static NTSTATUS
  19.377  XenPci_Irp_Read_XenBus_Complete(device_interface_xenbus_context_t *dixc, PIRP irp)
  19.378  {
  19.379 @@ -309,3 +657,4 @@ XenPci_Irp_Cleanup_XenBus(PDEVICE_OBJECT
  19.380  
  19.381    return status;
  19.382  }
  19.383 +#endif
  19.384 \ No newline at end of file
    20.1 --- a/xenpci/xenpci.c	Tue Jan 27 00:47:02 2009 +1100
    20.2 +++ b/xenpci/xenpci.c	Sat Feb 14 13:35:48 2009 +1100
    20.3 @@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fi
    20.4  #define SHUTDOWN_PATH "control/shutdown"
    20.5  #define BALLOON_PATH "memory/target"
    20.6  
    20.7 +#if 0
    20.8  #ifdef ALLOC_PRAGMA
    20.9  DRIVER_INITIALIZE DriverEntry;
   20.10  #pragma alloc_text (INIT, DriverEntry)
   20.11 @@ -164,22 +165,109 @@ XenPci_Dummy(PDEVICE_OBJECT device_objec
   20.12    
   20.13    return status;
   20.14  }
   20.15 +#endif
   20.16  
   20.17 -static DDKAPI NTSTATUS
   20.18 -XenPci_AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject)
   20.19 +static NTSTATUS
   20.20 +XenPci_EvtDeviceAdd(WDFDRIVER driver, PWDFDEVICE_INIT device_init)
   20.21  {
   20.22    NTSTATUS status;
   20.23 -  PDEVICE_OBJECT fdo = NULL;
   20.24 +//  PDEVICE_OBJECT fdo = NULL;
   20.25  //  PNP_BUS_INFORMATION busInfo;
   20.26  //  DECLARE_CONST_UNICODE_STRING(DeviceName, L"\\Device\\XenShutdown");
   20.27  //  DECLARE_CONST_UNICODE_STRING(SymbolicName, L"\\DosDevices\\XenShutdown");
   20.28 -//  WDFDEVICE Device;
   20.29 +  WDF_CHILD_LIST_CONFIG child_list_config;
   20.30 +  WDFDEVICE device;
   20.31    PXENPCI_DEVICE_DATA xpdd;
   20.32    UNICODE_STRING reference;
   20.33 -  //PWSTR InterfaceList;
   20.34 +  WDF_OBJECT_ATTRIBUTES device_attributes;
   20.35 +  PNP_BUS_INFORMATION pbi;
   20.36 +  WDF_PNPPOWER_EVENT_CALLBACKS pnp_power_callbacks;
   20.37 +  WDF_INTERRUPT_CONFIG interrupt_config;
   20.38 +  WDF_OBJECT_ATTRIBUTES file_attributes;
   20.39 +  WDF_FILEOBJECT_CONFIG file_config;
   20.40 +  WDF_IO_QUEUE_CONFIG queue_config;
   20.41 +  
   20.42 +  UNREFERENCED_PARAMETER(driver);
   20.43  
   20.44    FUNCTION_ENTER();
   20.45  
   20.46 +  WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnp_power_callbacks);
   20.47 +  pnp_power_callbacks.EvtDeviceD0Entry = XenPci_EvtDeviceD0Entry;
   20.48 +  pnp_power_callbacks.EvtDeviceD0EntryPostInterruptsEnabled = XenPci_EvtDeviceD0EntryPostInterruptsEnabled;
   20.49 +  pnp_power_callbacks.EvtDeviceD0Exit = XenPci_EvtDeviceD0Exit;
   20.50 +  pnp_power_callbacks.EvtDeviceD0ExitPreInterruptsDisabled = XenPci_EvtDeviceD0ExitPreInterruptsDisabled;
   20.51 +  pnp_power_callbacks.EvtDevicePrepareHardware = XenPci_EvtDevicePrepareHardware;
   20.52 +  pnp_power_callbacks.EvtDeviceReleaseHardware = XenPci_EvtDeviceReleaseHardware;
   20.53 +  WdfDeviceInitSetPnpPowerEventCallbacks(device_init, &pnp_power_callbacks);
   20.54 +
   20.55 +  WdfDeviceInitSetDeviceType(device_init, FILE_DEVICE_BUS_EXTENDER);
   20.56 +  WdfDeviceInitSetExclusive(device_init, FALSE);
   20.57 +
   20.58 +  WDF_CHILD_LIST_CONFIG_INIT(&child_list_config, sizeof(XENPCI_PDO_IDENTIFICATION_DESCRIPTION), XenPci_EvtChildListCreateDevice);
   20.59 +  child_list_config.EvtChildListScanForChildren = XenPci_EvtChildListScanForChildren;
   20.60 +  WdfFdoInitSetDefaultChildListConfig(device_init, &child_list_config, WDF_NO_OBJECT_ATTRIBUTES);
   20.61 +
   20.62 +  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&file_attributes, XENPCI_DEVICE_INTERFACE_DATA);
   20.63 +  WDF_FILEOBJECT_CONFIG_INIT(&file_config, XenPci_EvtDeviceFileCreate, XenPci_EvtFileClose, XenPci_EvtFileCleanup);
   20.64 +  WdfDeviceInitSetFileObjectConfig(device_init, &file_config, &file_attributes);
   20.65 +  
   20.66 +  WdfDeviceInitSetIoType(device_init, WdfDeviceIoBuffered);
   20.67 +  
   20.68 +  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&device_attributes, XENPCI_DEVICE_DATA);
   20.69 +  status = WdfDeviceCreate(&device_init, &device_attributes, &device);
   20.70 +  if (!NT_SUCCESS(status)) {
   20.71 +      KdPrint(("Error creating device 0x%x\n", status));
   20.72 +      return status;
   20.73 +  }
   20.74 +
   20.75 +  xpdd = GetXpdd(device);
   20.76 +
   20.77 +  WdfDeviceSetSpecialFileSupport(device, WdfSpecialFilePaging, TRUE);
   20.78 +  WdfDeviceSetSpecialFileSupport(device, WdfSpecialFileHibernation, TRUE);
   20.79 +  WdfDeviceSetSpecialFileSupport(device, WdfSpecialFileDump, TRUE);
   20.80 +
   20.81 +  WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queue_config, WdfIoQueueDispatchParallel);
   20.82 +  queue_config.EvtIoRead = XenPci_EvtIoRead;
   20.83 +  queue_config.EvtIoWrite = XenPci_EvtIoWrite;
   20.84 +  status = WdfIoQueueCreate(device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xpdd->io_queue);
   20.85 +  if (!NT_SUCCESS(status)) {
   20.86 +      KdPrint(("Error creating queue 0x%x\n", status));
   20.87 +      return status;
   20.88 +  }
   20.89 +  
   20.90 +  WDF_INTERRUPT_CONFIG_INIT(&interrupt_config, EvtChn_EvtInterruptIsr, NULL);
   20.91 +  interrupt_config.EvtInterruptEnable  = EvtChn_EvtInterruptEnable;
   20.92 +  interrupt_config.EvtInterruptDisable = EvtChn_EvtInterruptDisable;
   20.93 +
   20.94 +  status = WdfInterruptCreate(device, &interrupt_config, WDF_NO_OBJECT_ATTRIBUTES, &xpdd->interrupt);
   20.95 +  if (!NT_SUCCESS(status))
   20.96 +  {
   20.97 +    KdPrint(("Error creating interrupt 0x%x\n", status));
   20.98 +    return status;
   20.99 +  }
  20.100 +  
  20.101 +  RtlInitUnicodeString(&reference, L"xenbus");
  20.102 +  status = WdfDeviceCreateDeviceInterface(device, &GUID_DEVINTERFACE_XENBUS, &reference);
  20.103 +  if (!NT_SUCCESS(status)) {
  20.104 +      KdPrint(("Error registering device interface 0x%x\n", status));
  20.105 +      return status;
  20.106 +  }
  20.107 +
  20.108 +  pbi.BusTypeGuid = GUID_BUS_TYPE_XEN;
  20.109 +  pbi.LegacyBusType = PNPBus;
  20.110 +  pbi.BusNumber = 0;
  20.111 +  WdfDeviceSetBusInformationForChildren(device, &pbi);
  20.112 +
  20.113 +#if 0
  20.114 +  xpdd->shutdown_prod = 0;
  20.115 +  xpdd->shutdown_cons = 0;
  20.116 +  KeInitializeSpinLock(&xpdd->shutdown_ring_lock);
  20.117 +#endif
  20.118 +
  20.119 +  FUNCTION_EXIT();
  20.120 +  return status;
  20.121 +  
  20.122 +#if 0                                
  20.123    status = IoCreateDevice(DriverObject,
  20.124      sizeof(XENPCI_DEVICE_DATA),
  20.125      NULL,
  20.126 @@ -254,103 +342,53 @@ XenPci_AddDevice(PDRIVER_OBJECT DriverOb
  20.127  
  20.128    FUNCTION_EXIT();
  20.129    return status;
  20.130 +#endif
  20.131  }
  20.132  
  20.133  ULONG qemu_filtered;
  20.134 +ULONG qemu_filtered_by_qemu;
  20.135  ULONG qemu_protocol_version;
  20.136  ULONG tpr_patch_requested;
  20.137  extern PULONG InitSafeBootMode;
  20.138  
  20.139 -static VOID
  20.140 -TestStuff()
  20.141 +VOID
  20.142 +XenPci_HideQemuDevices()
  20.143  {
  20.144 -  int j;
  20.145 -  int i;
  20.146 -  PVOID page, page2;
  20.147 -  PMDL mdl;
  20.148 -  LARGE_INTEGER start_time, end_time;
  20.149 -  KIRQL old_irql;
  20.150 -  KSPIN_LOCK lock;
  20.151 -  NPAGED_LOOKASIDE_LIST la_list;
  20.152 -
  20.153 -  for (j = 0; j < 10; j++)
  20.154 -  {
  20.155 -    KeQuerySystemTime(&start_time);
  20.156 -    for (i = 0; i < 1000000; i++)
  20.157 -    {
  20.158 -      page = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
  20.159 -      page2 = ExAllocatePoolWithTag(NonPagedPool, sizeof(mdl) + 64, XENPCI_POOL_TAG);
  20.160 -      ExFreePoolWithTag(page, XENPCI_POOL_TAG);
  20.161 -      ExFreePoolWithTag(page2, XENPCI_POOL_TAG);
  20.162 -    }
  20.163 -    KeQuerySystemTime(&end_time);
  20.164 -    KdPrint(("ExAllocatePoolWithTag+ExFreePoolWithTag ran in %d ms\n", (end_time.QuadPart - start_time.QuadPart) / 10000));
  20.165 -  }
  20.166 -  for (j = 0; j < 10; j++)
  20.167 -  {
  20.168 -    KeQuerySystemTime(&start_time);
  20.169 -    for (i = 0; i < 1000000; i++)
  20.170 -    {
  20.171 -      mdl = AllocatePage();
  20.172 -      FreePages(mdl);
  20.173 -    }
  20.174 -    KeQuerySystemTime(&end_time);
  20.175 -    KdPrint(("AllocatePage+FreePages ran in %d ms\n", (end_time.QuadPart - start_time.QuadPart) / 10000));
  20.176 -  }
  20.177 -  KeInitializeSpinLock(&lock);
  20.178 -  for (j = 0; j < 10; j++)
  20.179 +  qemu_filtered_by_qemu = FALSE;
  20.180 +  if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2)
  20.181    {
  20.182 -    KeRaiseIrql(DISPATCH_LEVEL, &old_irql);
  20.183 -    KeQuerySystemTime(&start_time);
  20.184 -    for (i = 0; i < 1000000; i++)
  20.185 -    {
  20.186 -      KeAcquireSpinLockAtDpcLevel(&lock);
  20.187 -      KeReleaseSpinLockFromDpcLevel(&lock);
  20.188 -      KeAcquireSpinLockAtDpcLevel(&lock);
  20.189 -      KeReleaseSpinLockFromDpcLevel(&lock);
  20.190 -    }
  20.191 -    KeQuerySystemTime(&end_time);
  20.192 -    KeLowerIrql(old_irql);
  20.193 -    KdPrint(("KeAcquireSpinLockAtDpcLevel+KeReleaseSpinLockFromDpcLevel x 2 ran in %d ms\n", (end_time.QuadPart - start_time.QuadPart) / 10000));
  20.194 -  }
  20.195 -  
  20.196 -  ExInitializeNPagedLookasideList(&la_list, NULL, NULL, 0, PAGE_SIZE, XENPCI_POOL_TAG, 0);
  20.197 -  for (j = 0; j < 10; j++)
  20.198 -  {
  20.199 -    KeRaiseIrql(DISPATCH_LEVEL, &old_irql);
  20.200 -    KeQuerySystemTime(&start_time);
  20.201 -    for (i = 0; i < 1000000; i++)
  20.202 +    qemu_protocol_version = READ_PORT_UCHAR(XEN_IOPORT_VERSION);
  20.203 +    KdPrint((__DRIVER_NAME "     Version = %d\n", qemu_protocol_version));
  20.204 +    switch(qemu_protocol_version)
  20.205      {
  20.206 -      page = ExAllocateFromNPagedLookasideList(&la_list);
  20.207 -      page2 = ExAllocateFromNPagedLookasideList(&la_list);
  20.208 -      ExFreeToNPagedLookasideList(&la_list, page);
  20.209 -      ExFreeToNPagedLookasideList(&la_list, page2);
  20.210 +    case 1:
  20.211 +      WRITE_PORT_USHORT(XEN_IOPORT_PRODUCT, XEN_PV_PRODUCT_NUMBER);
  20.212 +      WRITE_PORT_ULONG(XEN_IOPORT_BUILD, XEN_PV_PRODUCT_BUILD);
  20.213 +      if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) != 0x49d2)
  20.214 +      {
  20.215 +        KdPrint((__DRIVER_NAME "     Blacklisted\n"));
  20.216 +        break;
  20.217 +      }
  20.218 +      /* fall through */
  20.219 +    case 0:
  20.220 +      qemu_filtered = TRUE;
  20.221 +      qemu_filtered_by_qemu = TRUE;
  20.222 +      WRITE_PORT_USHORT(XEN_IOPORT_DEVICE_MASK, QEMU_UNPLUG_ALL_IDE_DISKS|QEMU_UNPLUG_ALL_NICS);
  20.223 +      KdPrint((__DRIVER_NAME "     Disabled qemu devices\n"));
  20.224 +      break;
  20.225 +    default:
  20.226 +      KdPrint((__DRIVER_NAME "     Unknown qemu version %d\n", qemu_protocol_version));
  20.227 +      break;
  20.228      }
  20.229 -    KeQuerySystemTime(&end_time);
  20.230 -    KeLowerIrql(old_irql);
  20.231 -    KdPrint(("ExAllocateFromNPagedLookasideList+ExFreeToNPagedLookasideList ran in %d ms\n", (end_time.QuadPart - start_time.QuadPart) / 10000));
  20.232    }
  20.233 -  ExDeleteNPagedLookasideList(&la_list);
  20.234 -
  20.235 -    for (j = 0; j < 10; j++)
  20.236 -  {
  20.237 -    KeRaiseIrql(DISPATCH_LEVEL, &old_irql);
  20.238 -    KeQuerySystemTime(&start_time);
  20.239 -    for (i = 0; i < 1000000; i++)
  20.240 -    {
  20.241 -      KeMemoryBarrier();
  20.242 -    }
  20.243 -    KeQuerySystemTime(&end_time);
  20.244 -    KeLowerIrql(old_irql);
  20.245 -    KdPrint(("'Nothing ran in %d ms\n", (end_time.QuadPart - start_time.QuadPart) / 10000));
  20.246 -  }
  20.247 -
  20.248  }
  20.249  
  20.250 -NTSTATUS DDKAPI
  20.251 +NTSTATUS
  20.252  DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
  20.253  {
  20.254    NTSTATUS status = STATUS_SUCCESS;
  20.255 +  WDF_DRIVER_CONFIG config;
  20.256 +  WDFDRIVER driver;
  20.257    PCONFIGURATION_INFORMATION conf_info;
  20.258    WCHAR *SystemStartOptions;
  20.259    UNICODE_STRING RegKeyName;
  20.260 @@ -385,7 +423,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
  20.261    KeyPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
  20.262    SystemStartOptions = (WCHAR *)KeyPartialValue->Data;
  20.263  
  20.264 -  KdPrint((__DRIVER_NAME "     SystemStartOptions = %s\n", SystemStartOptions));
  20.265 +  KdPrint((__DRIVER_NAME "     SystemStartOptions = %S\n", SystemStartOptions));
  20.266    
  20.267    if (wcsstr(SystemStartOptions, L"PATCHTPR"))
  20.268    {
  20.269 @@ -401,35 +439,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
  20.270        && !*InitSafeBootMode)
  20.271    {
  20.272      /* see if the qemu method of disabling the PCI devices exists */
  20.273 -    if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2)
  20.274 -    {
  20.275 -      qemu_protocol_version = READ_PORT_UCHAR(XEN_IOPORT_VERSION);
  20.276 -      KdPrint((__DRIVER_NAME "     Version = %d\n", qemu_protocol_version));
  20.277 -      switch(qemu_protocol_version)
  20.278 -      {
  20.279 -      case 1:
  20.280 -        WRITE_PORT_USHORT(XEN_IOPORT_PRODUCT, XEN_PV_PRODUCT_NUMBER);
  20.281 -        WRITE_PORT_ULONG(XEN_IOPORT_BUILD, XEN_PV_PRODUCT_BUILD);
  20.282 -        if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) != 0x49d2)
  20.283 -        {
  20.284 -          KdPrint((__DRIVER_NAME "     Blacklisted\n"));
  20.285 -          break;
  20.286 -        }
  20.287 -        /* fall through */
  20.288 -      case 0:
  20.289 -        qemu_filtered = TRUE;
  20.290 -        WRITE_PORT_USHORT(XEN_IOPORT_DEVICE_MASK, QEMU_UNPLUG_ALL_IDE_DISKS|QEMU_UNPLUG_ALL_NICS);
  20.291 -        KdPrint((__DRIVER_NAME "     Disabled qemu devices\n"));
  20.292 -        break;
  20.293 -      default:
  20.294 -        KdPrint((__DRIVER_NAME "     Unknown qemu version %d\n", qemu_protocol_version));
  20.295 -        break;
  20.296 -      }
  20.297 -    }
  20.298 -    else
  20.299 -    {
  20.300 -      KdPrint((__DRIVER_NAME "     Missing XEN signature\n"));
  20.301 -    }
  20.302 +    XenPci_HideQemuDevices();
  20.303      /* if not, tell the filter to deny the pci devices their resources */
  20.304      if (!qemu_filtered)
  20.305      {
  20.306 @@ -451,6 +461,14 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
  20.307      }
  20.308    }
  20.309  
  20.310 +  WDF_DRIVER_CONFIG_INIT(&config, XenPci_EvtDeviceAdd);
  20.311 +  status = WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, &driver);
  20.312 +
  20.313 +  if (!NT_SUCCESS(status)) {
  20.314 +    KdPrint( ("WdfDriverCreate failed with status 0x%x\n", status));
  20.315 +  }
  20.316 +
  20.317 +#if 0
  20.318    DriverObject->DriverExtension->AddDevice = XenPci_AddDevice;
  20.319    DriverObject->MajorFunction[IRP_MJ_PNP] = XenPci_Pnp;
  20.320    DriverObject->MajorFunction[IRP_MJ_POWER] = XenPci_Power;
  20.321 @@ -461,6 +479,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
  20.322    DriverObject->MajorFunction[IRP_MJ_READ] = XenPci_Irp_Read;
  20.323    DriverObject->MajorFunction[IRP_MJ_WRITE] = XenPci_Irp_Write;
  20.324    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = XenPci_SystemControl;
  20.325 +#endif
  20.326  
  20.327    FUNCTION_EXIT();
  20.328  
    21.1 --- a/xenpci/xenpci.h	Tue Jan 27 00:47:02 2009 +1100
    21.2 +++ b/xenpci/xenpci.h	Sat Feb 14 13:35:48 2009 +1100
    21.3 @@ -26,18 +26,14 @@ Foundation, Inc., 51 Franklin Street, Fi
    21.4  #include <ntifs.h>
    21.5  #include <ntddk.h>
    21.6  
    21.7 -#ifdef __MINGW32__
    21.8 -#include "../mingw/mingw_extras.h"
    21.9 -#else
   21.10  #define DDKAPI
   21.11 -#include <wdm.h>
   21.12 -//#include <wdf.h>
   21.13 +//#include <wdm.h>
   21.14 +#include <wdf.h>
   21.15  #include <initguid.h>
   21.16  #include <wdmguid.h>
   21.17  #include <errno.h>
   21.18  #define NTSTRSAFE_LIB
   21.19  #include <ntstrsafe.h>
   21.20 -#endif
   21.21  
   21.22  #define __DRIVER_NAME "XenPCI"
   21.23  
   21.24 @@ -49,7 +45,7 @@ Foundation, Inc., 51 Franklin Street, Fi
   21.25  #include <hvm/hvm_op.h>
   21.26  #include <sched.h>
   21.27  #include <io/xenbus.h>
   21.28 -#include "io/xs_wire.h"
   21.29 +#include <io/xs_wire.h>
   21.30  
   21.31  #include <xen_public.h>
   21.32  
   21.33 @@ -113,6 +109,7 @@ typedef struct _XENBUS_WATCH_ENTRY {
   21.34  #define CHILD_STATE_DELETED 1
   21.35  #define CHILD_STATE_ADDED 2
   21.36  
   21.37 +#if 0
   21.38  // TODO: tidy up & organize this struct
   21.39  
   21.40  typedef enum {
   21.41 @@ -126,6 +123,7 @@ typedef enum {
   21.42      Removed
   21.43  } DEVICE_PNP_STATE;
   21.44  
   21.45 +#if 0
   21.46  typedef struct
   21.47  {
   21.48    PDEVICE_OBJECT fdo;
   21.49 @@ -141,6 +139,7 @@ typedef struct
   21.50    ULONG device_usage_dump;
   21.51    ULONG device_usage_hibernation;
   21.52  } XENPCI_COMMON, *PXENPCI_COMMON;
   21.53 +#endif
   21.54  
   21.55  static __inline void INIT_PNP_STATE(PXENPCI_COMMON common)
   21.56  {
   21.57 @@ -158,6 +157,7 @@ static __inline void REVERT_PNP_STATE(PX
   21.58  {
   21.59    common->current_pnp_state = common->previous_pnp_state;
   21.60  }
   21.61 +#endif
   21.62  
   21.63  #define SHUTDOWN_RING_SIZE 128
   21.64  
   21.65 @@ -167,11 +167,13 @@ static __inline void REVERT_PNP_STATE(PX
   21.66  #define SUSPEND_STATE_RESUMING  3 /* we are the other side of the suspend and things are starting to get back to normal */
   21.67  
   21.68  typedef struct {  
   21.69 -  XENPCI_COMMON common;
   21.70 +  //XENPCI_COMMON common;
   21.71    
   21.72    BOOLEAN XenBus_ShuttingDown;
   21.73 +  
   21.74 +  BOOLEAN tpr_patched;
   21.75  
   21.76 -  PKINTERRUPT interrupt;
   21.77 +  WDFINTERRUPT interrupt;
   21.78    ULONG irq_number;
   21.79    ULONG irq_vector;
   21.80    KIRQL irq_level;
   21.81 @@ -183,6 +185,7 @@ typedef struct {
   21.82    xen_ulong_t evtchn_pending_pvt[sizeof(xen_ulong_t) * 8];
   21.83    xen_ulong_t evtchn_pending_suspend[sizeof(xen_ulong_t) * 8];
   21.84    evtchn_port_t pdo_event_channel;
   21.85 +  KEVENT pdo_suspend_event;
   21.86    BOOLEAN interrupts_masked;
   21.87    
   21.88    PHYSICAL_ADDRESS platform_mmio_addr;
   21.89 @@ -200,13 +203,12 @@ typedef struct {
   21.90  
   21.91    /* grant related */
   21.92    grant_entry_t *gnttab_table;
   21.93 +  grant_entry_t *gnttab_table_copy;
   21.94    PHYSICAL_ADDRESS gnttab_table_physical;
   21.95    grant_ref_t *gnttab_list;
   21.96    int gnttab_list_free;
   21.97    KSPIN_LOCK grant_lock;
   21.98 -  /* this is the maximum number of grant frames we have memory allocated for */
   21.99 -  /* after a resume it may not be the actual number of grant frames we have though */
  21.100 -  ULONG max_grant_frames;
  21.101 +  ULONG grant_frames;
  21.102  
  21.103    ev_action_t ev_actions[NR_EVENTS];
  21.104  //  unsigned long bound_ports[NR_EVENTS/(8*sizeof(unsigned long))];
  21.105 @@ -229,28 +231,40 @@ typedef struct {
  21.106    KEVENT xb_request_complete_event;
  21.107    struct xsd_sockmsg *xb_reply;
  21.108    
  21.109 -  LIST_ENTRY child_list;
  21.110 +  WDFCHILDLIST child_list;
  21.111    
  21.112    int suspend_state;
  21.113    
  21.114    UNICODE_STRING legacy_interface_name;
  21.115    UNICODE_STRING interface_name;
  21.116    BOOLEAN interface_open;
  21.117 -  
  21.118 +
  21.119 +  WDFQUEUE io_queue;
  21.120 +#if 0
  21.121    KSPIN_LOCK shutdown_ring_lock;
  21.122    CHAR shutdown_ring[SHUTDOWN_RING_SIZE];
  21.123    ULONG shutdown_prod;
  21.124    ULONG shutdown_cons;
  21.125    ULONG shutdown_start; /* the start of the most recent message on the ring */
  21.126    PIRP shutdown_irp;
  21.127 +#endif
  21.128  
  21.129 -  BOOLEAN log_interrupts;
  21.130 +#if 0
  21.131 +  KSPIN_LOCK mmio_freelist_lock;
  21.132 +  PPFN_NUMBER mmio_freelist_base;
  21.133 +  ULONG mmio_freelist_free;
  21.134 +#endif
  21.135 +
  21.136  } XENPCI_DEVICE_DATA, *PXENPCI_DEVICE_DATA;
  21.137  
  21.138 +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_DATA, GetXpdd)
  21.139 +
  21.140  typedef struct {  
  21.141 -  XENPCI_COMMON common;
  21.142 -  PDEVICE_OBJECT bus_pdo;
  21.143 -  PDEVICE_OBJECT bus_fdo;
  21.144 +//  XENPCI_COMMON common;
  21.145 +  WDFDEVICE wdf_device;
  21.146 +  WDFDEVICE wdf_device_bus_fdo;
  21.147 +  //PDEVICE_OBJECT bus_pdo;
  21.148 +  //PDEVICE_OBJECT bus_fdo;
  21.149    BOOLEAN reported_missing;
  21.150    char path[128];
  21.151    char device[128];
  21.152 @@ -273,21 +287,32 @@ typedef struct {
  21.153    
  21.154  } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
  21.155  
  21.156 +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_PDO_DEVICE_DATA, GetXppdd)
  21.157 +
  21.158 +typedef struct {
  21.159 +  WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER header;
  21.160 +  CHAR path[128];
  21.161 +  CHAR device[128];
  21.162 +  ULONG index;
  21.163 +} XENPCI_PDO_IDENTIFICATION_DESCRIPTION, *PXENPCI_PDO_IDENTIFICATION_DESCRIPTION;
  21.164 +
  21.165  typedef struct {
  21.166    DMA_ADAPTER dma_adapter;
  21.167 -  DMA_OPERATIONS dma_operations;
  21.168 +  //DMA_OPERATIONS dma_operations;
  21.169    PXENPCI_PDO_DEVICE_DATA xppdd;
  21.170    dma_driver_extension_t *dma_extension;
  21.171    //ULONG map_register_count;
  21.172    //map_register_t *map_registers;
  21.173  } xen_dma_adapter_t;
  21.174  
  21.175 +#if 0
  21.176  typedef struct
  21.177  {
  21.178    LIST_ENTRY entry;
  21.179    int state;
  21.180    PXENPCI_PDO_DEVICE_DATA context;
  21.181  } XEN_CHILD, *PXEN_CHILD;
  21.182 +#endif
  21.183  
  21.184  #define XEN_INTERFACE_VERSION 1
  21.185  
  21.186 @@ -303,26 +328,45 @@ typedef struct {
  21.187      UCHAR buffer[PAGE_SIZE];
  21.188    } u;
  21.189    LIST_ENTRY read_list_head;
  21.190 -  PIRP pending_read_irp;
  21.191 -} device_interface_xenbus_context_t;
  21.192 +  LIST_ENTRY watch_list_head;
  21.193 +  WDFQUEUE io_queue;
  21.194 +
  21.195 +  //PIRP pending_read_irp;
  21.196 +} XENPCI_DEVICE_INTERFACE_DATA, *PXENPCI_DEVICE_INTERFACE_DATA;
  21.197 +
  21.198 +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_INTERFACE_DATA, GetXpdid)
  21.199 +
  21.200 +EVT_WDF_DEVICE_FILE_CREATE XenPci_EvtDeviceFileCreate;
  21.201 +EVT_WDF_FILE_CLOSE XenPci_EvtFileClose;
  21.202 +EVT_WDF_FILE_CLEANUP XenPci_EvtFileCleanup;
  21.203 +EVT_WDF_IO_QUEUE_IO_READ XenPci_EvtIoRead;
  21.204 +EVT_WDF_IO_QUEUE_IO_WRITE XenPci_EvtIoWrite;
  21.205  
  21.206  #include "hypercall.h"
  21.207  
  21.208  #define XBT_NIL ((xenbus_transaction_t)0)
  21.209  
  21.210 -#if 0
  21.211 -static __inline VOID
  21.212 -XenPci_FreeMem(PVOID Ptr)
  21.213 -{
  21.214 -  ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
  21.215 -}
  21.216 -#endif
  21.217 -
  21.218  NTSTATUS
  21.219  hvm_get_stubs(PXENPCI_DEVICE_DATA xpdd);
  21.220  NTSTATUS
  21.221  hvm_free_stubs(PXENPCI_DEVICE_DATA xpdd);
  21.222  
  21.223 +EVT_WDF_DEVICE_PREPARE_HARDWARE XenPci_EvtDevicePrepareHardware;
  21.224 +EVT_WDF_DEVICE_RELEASE_HARDWARE XenPci_EvtDeviceReleaseHardware;
  21.225 +EVT_WDF_DEVICE_D0_ENTRY XenPci_EvtDeviceD0Entry;
  21.226 +EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED XenPci_EvtDeviceD0EntryPostInterruptsEnabled;
  21.227 +EVT_WDF_DEVICE_D0_EXIT XenPci_EvtDeviceD0Exit;
  21.228 +EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED XenPci_EvtDeviceD0ExitPreInterruptsDisabled;
  21.229 +NTSTATUS
  21.230 +XenPci_EvtChildListCreateDevice(WDFCHILDLIST child_list, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER description_header, PWDFDEVICE_INIT child_init);
  21.231 +VOID
  21.232 +XenPci_EvtChildListScanForChildren(WDFCHILDLIST child_list);
  21.233 +
  21.234 +VOID
  21.235 +XenPci_HideQemuDevices();
  21.236 +extern ULONG qemu_filtered_by_qemu;
  21.237 +
  21.238 +#if 0
  21.239  NTSTATUS
  21.240  XenPci_Power_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
  21.241  NTSTATUS
  21.242 @@ -371,11 +415,12 @@ NTSTATUS
  21.243  XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
  21.244  NTSTATUS
  21.245  XenPci_SystemControl_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
  21.246 +#endif
  21.247  
  21.248  NTSTATUS
  21.249 -XenPci_Pdo_Suspend(PDEVICE_OBJECT device_object);
  21.250 +XenPci_Pdo_Suspend(WDFDEVICE device);
  21.251  NTSTATUS
  21.252 -XenPci_Pdo_Resume(PDEVICE_OBJECT device_object);
  21.253 +XenPci_Pdo_Resume(WDFDEVICE device);
  21.254  
  21.255  VOID
  21.256  XenPci_DumpPdoConfig(PDEVICE_OBJECT device_object);
  21.257 @@ -427,12 +472,16 @@ XenBus_StopThreads(PXENPCI_DEVICE_DATA x
  21.258  PHYSICAL_ADDRESS
  21.259  XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len);
  21.260  
  21.261 +EVT_WDF_INTERRUPT_ISR EvtChn_EvtInterruptIsr;
  21.262 +EVT_WDF_INTERRUPT_ENABLE EvtChn_EvtInterruptEnable;
  21.263 +EVT_WDF_INTERRUPT_DISABLE EvtChn_EvtInterruptDisable;
  21.264 +
  21.265  NTSTATUS
  21.266  EvtChn_Init(PXENPCI_DEVICE_DATA xpdd);
  21.267  NTSTATUS
  21.268 -EvtChn_ConnectInterrupt(PXENPCI_DEVICE_DATA xpdd);
  21.269 +EvtChn_Suspend(PXENPCI_DEVICE_DATA xpdd);
  21.270  NTSTATUS
  21.271 -EvtChn_Shutdown(PXENPCI_DEVICE_DATA xpdd);
  21.272 +EvtChn_Resume(PXENPCI_DEVICE_DATA xpdd);
  21.273  
  21.274  NTSTATUS
  21.275  EvtChn_Mask(PVOID Context, evtchn_port_t Port);
  21.276 @@ -460,7 +509,9 @@ EvtChn_AckEvent(PVOID context, evtchn_po
  21.277  VOID
  21.278  GntTbl_Init(PXENPCI_DEVICE_DATA xpdd);
  21.279  VOID
  21.280 -GntTbl_InitMap(PXENPCI_DEVICE_DATA xpdd);
  21.281 +GntTbl_Suspend(PXENPCI_DEVICE_DATA xpdd);
  21.282 +VOID
  21.283 +GntTbl_Resume(PXENPCI_DEVICE_DATA xpdd);
  21.284  grant_ref_t
  21.285  GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t, int readonly, grant_ref_t ref);
  21.286  BOOLEAN
  21.287 @@ -469,6 +520,9 @@ VOID
  21.288  GntTbl_PutRef(PVOID Context, grant_ref_t ref);
  21.289  grant_ref_t
  21.290  GntTbl_GetRef(PVOID Context);
  21.291 +#if 0
  21.292  int 
  21.293  GntTbl_Map(PVOID Context, unsigned int start_idx, unsigned int end_idx);
  21.294  #endif
  21.295 +
  21.296 +#endif
    22.1 --- a/xenpci/xenpci.inx	Tue Jan 27 00:47:02 2009 +1100
    22.2 +++ b/xenpci/xenpci.inx	Sat Feb 14 13:35:48 2009 +1100
    22.3 @@ -12,20 +12,20 @@ DefaultDestDir = 12
    22.4  ExcludeFromSelect=*
    22.5  
    22.6  [Manufacturer]
    22.7 -%XenGplPv%=XenGplPv,NTx86
    22.8 -%XenGplPv%=XenGplPv,NTamd64
    22.9 -%XenGplPv%=XenGplPv
   22.10 -
   22.11 -[XenGplPv.NTx86]
   22.12 -%XenPCI.DRVDESC%=XenPCI_Inst, PCI\VEN_5853&DEV_0001
   22.13 +%XenGplPv%=XenPCI,NTx86
   22.14 +%XenGplPv%=XenPCI,NTamd64
   22.15 +%XenGplPv%=XenPCI
   22.16  
   22.17 -[XenGplPv.NTAMD64]
   22.18 -%XenPCI.DRVDESC%=XenPCI_Inst, PCI\VEN_5853&DEV_0001
   22.19 +[XenPCI.NTx86]
   22.20 +%XenPCI.DRVDESC%=XenPCI_Device, PCI\VEN_5853&DEV_0001
   22.21  
   22.22 -[XenGplPv]
   22.23 -%XenPCI.DRVDESC%=XenPCI_Inst, PCI\VEN_5853&DEV_0001
   22.24 +[XenPCI.NTAMD64]
   22.25 +%XenPCI.DRVDESC%=XenPCI_Device, PCI\VEN_5853&DEV_0001
   22.26  
   22.27 -[XenPCI_Inst.NT]
   22.28 +[XenPCI]
   22.29 +%XenPCI.DRVDESC%=XenPCI_Device, PCI\VEN_5853&DEV_0001
   22.30 +
   22.31 +[XenPCI_Device.NT]
   22.32  CopyFiles=XenPCI.CopyFiles
   22.33  
   22.34  [XenPCI.CopyFiles]
   22.35 @@ -45,7 +45,7 @@ 1 = %DISK_NAME%,,,.\amd64
   22.36  [SourceDisksNames]
   22.37  1 = %DISK_NAME%,,,.\i386
   22.38  
   22.39 -[XenPCI_Inst.NT.Services]
   22.40 +[XenPCI_Device.NT.Services]
   22.41  AddService=XenPCI,3,XenPCI_Service
   22.42  AddService=XenHide,0,XenHide_Service
   22.43  
   22.44 @@ -69,6 +69,28 @@ DelReg         = XenHide_Service_DelReg
   22.45  [XenHide_Service_DelReg]
   22.46  HKLM,SYSTEM\CurrentControlSet\Control\Class\{4D36E97D-E325-11CE-BFC1-08002BE10318},UpperFilters
   22.47  
   22.48 +[DestinationDirs]
   22.49 +XenPCI_Device_CoInstaller_CopyFiles = 11
   22.50 +
   22.51 +[XenPCI_Device.NT.CoInstallers]
   22.52 +AddReg=XenPCI_Device_CoInstaller_AddReg
   22.53 +CopyFiles=XenPCI_Device_CoInstaller_CopyFiles
   22.54 +
   22.55 +[XenPCI_Device_CoInstaller_AddReg]
   22.56 +HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"
   22.57 +
   22.58 +[XenPCI_Device_CoInstaller_CopyFiles]
   22.59 +WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll
   22.60 +
   22.61 +[SourceDisksFiles]
   22.62 +WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1
   22.63 +
   22.64 +[XenPCI_Device.NT.Wdf]
   22.65 +KmdfService = XenPCI, XenPCI_wdfsect
   22.66 +
   22.67 +[XenPCI_wdfsect]
   22.68 +KmdfLibraryVersion = $KMDFVERSION$
   22.69 +
   22.70  [Strings]
   22.71  XenGplPv = "Xen GPL PV Driver Developers"
   22.72  XenPCI.SVCDESC = "Xen PCI Device Driver"
    23.1 --- a/xenpci/xenpci_fdo.c	Tue Jan 27 00:47:02 2009 +1100
    23.2 +++ b/xenpci/xenpci_fdo.c	Sat Feb 14 13:35:48 2009 +1100
    23.3 @@ -25,6 +25,600 @@ Foundation, Inc., 51 Franklin Street, Fi
    23.4  #define SHUTDOWN_PATH "control/shutdown"
    23.5  #define BALLOON_PATH "memory/target"
    23.6  
    23.7 +static VOID
    23.8 +XenPci_MapHalThenPatchKernel(PXENPCI_DEVICE_DATA xpdd)
    23.9 +{
   23.10 +  NTSTATUS status;
   23.11 +  PAUX_MODULE_EXTENDED_INFO amei;
   23.12 +  ULONG module_info_buffer_size;
   23.13 +  ULONG i;
   23.14 +   
   23.15 +  FUNCTION_ENTER();
   23.16 +
   23.17 +  status = AuxKlibInitialize();
   23.18 +  amei = NULL;
   23.19 +  /* buffer size could change between requesting and allocating - need to loop until we are successful */
   23.20 +  while ((status = AuxKlibQueryModuleInformation(&module_info_buffer_size, sizeof(AUX_MODULE_EXTENDED_INFO), amei)) == STATUS_BUFFER_TOO_SMALL || amei == NULL)
   23.21 +  {
   23.22 +    if (amei != NULL)
   23.23 +      ExFreePoolWithTag(amei, XENPCI_POOL_TAG);
   23.24 +    amei = ExAllocatePoolWithTag(NonPagedPool, module_info_buffer_size, XENPCI_POOL_TAG);
   23.25 +  }
   23.26 +  
   23.27 +  KdPrint((__DRIVER_NAME "     AuxKlibQueryModuleInformation = %d\n", status));
   23.28 +  for (i = 0; i < module_info_buffer_size / sizeof(AUX_MODULE_EXTENDED_INFO); i++)
   23.29 +  {
   23.30 +    if (strcmp((PCHAR)amei[i].FullPathName + amei[i].FileNameOffset, "hal.dll") == 0)
   23.31 +    {
   23.32 +      KdPrint((__DRIVER_NAME "     hal.dll found at %p - %p\n", 
   23.33 +        amei[i].BasicInfo.ImageBase,
   23.34 +        ((PUCHAR)amei[i].BasicInfo.ImageBase) + amei[i].ImageSize));
   23.35 +      XenPci_PatchKernel(xpdd, amei[i].BasicInfo.ImageBase, amei[i].ImageSize);
   23.36 +    }
   23.37 +  }
   23.38 +  ExFreePoolWithTag(amei, XENPCI_POOL_TAG);
   23.39 +  FUNCTION_EXIT();
   23.40 +}
   23.41 +
   23.42 +#if 0
   23.43 +PMDL
   23.44 +XenPCI_AllocMMIO(WDFDEVICE device, ULONG len)
   23.45 +{
   23.46 +  PMDL mdl = ExAllocatePoolWithTag(NonPagedPool, MmSizeOfMdl(0, len), XENPCI_POOL_TAG);
   23.47 +  PVOID va = MmAllocateMappingAddress(len, XENPCI_POOL_TAG);
   23.48 +  
   23.49 +  for (i = 0; i < ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, len);
   23.50 +  
   23.51 +}
   23.52 +#endif
   23.53 +
   23.54 +/*
   23.55 + * Alloc MMIO from the device's MMIO region. There is no corresponding free() fn
   23.56 + */
   23.57 +PHYSICAL_ADDRESS
   23.58 +XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len)
   23.59 +{
   23.60 +  PHYSICAL_ADDRESS addr;
   23.61 +
   23.62 +  len = (len + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
   23.63 +
   23.64 +  addr = xpdd->platform_mmio_addr;
   23.65 +  addr.QuadPart += xpdd->platform_mmio_alloc;
   23.66 +  xpdd->platform_mmio_alloc += len;
   23.67 +
   23.68 +  ASSERT(xpdd->platform_mmio_alloc <= xpdd->platform_mmio_len);
   23.69 +
   23.70 +  return addr;
   23.71 +}
   23.72 +
   23.73 +extern ULONG tpr_patch_requested;
   23.74 +
   23.75 +static NTSTATUS
   23.76 +XenPci_Init(PXENPCI_DEVICE_DATA xpdd)
   23.77 +{
   23.78 +  struct xen_add_to_physmap xatp;
   23.79 +  int ret;
   23.80 +
   23.81 +  FUNCTION_ENTER();
   23.82 +
   23.83 +  hvm_get_stubs(xpdd);
   23.84 +
   23.85 +  if (!xpdd->shared_info_area)
   23.86 +  {
   23.87 +    ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
   23.88 +    /* this should be safe as this part will never be called on resume where IRQL == HIGH_LEVEL */
   23.89 +    xpdd->shared_info_area_unmapped = XenPci_AllocMMIO(xpdd, PAGE_SIZE);
   23.90 +    xpdd->shared_info_area = MmMapIoSpace(xpdd->shared_info_area_unmapped,
   23.91 +      PAGE_SIZE, MmNonCached);
   23.92 +  }
   23.93 +  KdPrint((__DRIVER_NAME "     shared_info_area_unmapped.QuadPart = %lx\n", xpdd->shared_info_area_unmapped.QuadPart));
   23.94 +  xatp.domid = DOMID_SELF;
   23.95 +  xatp.idx = 0;
   23.96 +  xatp.space = XENMAPSPACE_shared_info;
   23.97 +  xatp.gpfn = (xen_pfn_t)(xpdd->shared_info_area_unmapped.QuadPart >> PAGE_SHIFT);
   23.98 +  KdPrint((__DRIVER_NAME "     gpfn = %x\n", xatp.gpfn));
   23.99 +  ret = HYPERVISOR_memory_op(xpdd, XENMEM_add_to_physmap, &xatp);
  23.100 +  KdPrint((__DRIVER_NAME "     hypervisor memory op (XENMAPSPACE_shared_info) ret = %d\n", ret));
  23.101 +  
  23.102 +  FUNCTION_EXIT();
  23.103 +
  23.104 +  return STATUS_SUCCESS;
  23.105 +}
  23.106 +
  23.107 +static NTSTATUS
  23.108 +XenPci_Resume(PXENPCI_DEVICE_DATA xpdd)
  23.109 +{
  23.110 +  return XenPci_Init(xpdd);
  23.111 +}
  23.112 +
  23.113 +static VOID
  23.114 +XenPci_SysrqHandler(char *path, PVOID context)
  23.115 +{
  23.116 +  PXENPCI_DEVICE_DATA xpdd = context;
  23.117 +  char *value;
  23.118 +  char letter;
  23.119 +  char *res;
  23.120 +
  23.121 +  UNREFERENCED_PARAMETER(path);
  23.122 +
  23.123 +  FUNCTION_ENTER();
  23.124 +
  23.125 +  XenBus_Read(xpdd, XBT_NIL, SYSRQ_PATH, &value);
  23.126 +
  23.127 +  KdPrint((__DRIVER_NAME "     SysRq Value = %s\n", value));
  23.128 +
  23.129 +  if (value != NULL && strlen(value) != 0)
  23.130 +  {
  23.131 +    letter = *value;
  23.132 +    res = XenBus_Write(xpdd, XBT_NIL, SYSRQ_PATH, "");
  23.133 +    if (res)
  23.134 +    {
  23.135 +      KdPrint(("Error writing sysrq path\n"));
  23.136 +      XenPci_FreeMem(res);
  23.137 +      return;
  23.138 +    }
  23.139 +  }
  23.140 +  else
  23.141 +  {
  23.142 +    letter = 0;
  23.143 +  }
  23.144 +
  23.145 +  if (value != NULL)
  23.146 +  {
  23.147 +    XenPci_FreeMem(value);
  23.148 +  }
  23.149 +
  23.150 +  switch (letter)
  23.151 +  {
  23.152 +  case 0:
  23.153 +    break;
  23.154 +  case 'B': /* cause a bug check */
  23.155 +    KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000001, 0x00000000, 0x00000000, 0x00000000);
  23.156 +    break;
  23.157 +  default:
  23.158 +    KdPrint(("     Unhandled sysrq letter %c\n", letter));
  23.159 +    break;
  23.160 +  }
  23.161 +
  23.162 +  FUNCTION_EXIT();
  23.163 +}
  23.164 +
  23.165 +#if 0
  23.166 +static VOID
  23.167 +XenPci_PrintPendingInterrupts()
  23.168 +{
  23.169 +  PULONG bitmap = (PULONG)0xFFFE0200;
  23.170 +  int i;
  23.171 +  int j;
  23.172 +  ULONG value;
  23.173 +  
  23.174 +  for (i = 0; i < 8; i++)
  23.175 +  {
  23.176 +    value = bitmap[(7 - i) * 4];
  23.177 +    if (value)
  23.178 +    {
  23.179 +      for (j = 0; j < 32; j++)
  23.180 +      {
  23.181 +        if ((value >> j) & 1)
  23.182 +          KdPrint(("     Interrupt pending on pin %d\n", ((7 - i) << 5) | j));
  23.183 +      }
  23.184 +    }
  23.185 +  }
  23.186 +}
  23.187 +#endif
  23.188 +
  23.189 +static VOID
  23.190 +XenPci_Suspend0(PVOID context)
  23.191 +{
  23.192 +  PXENPCI_DEVICE_DATA xpdd = context;
  23.193 +  ULONG cancelled;
  23.194 +  
  23.195 +  FUNCTION_ENTER();
  23.196 +
  23.197 +  GntTbl_Suspend(xpdd);
  23.198 +  
  23.199 +  cancelled = hvm_shutdown(xpdd, SHUTDOWN_suspend);
  23.200 +  KdPrint((__DRIVER_NAME "     back from suspend, cancelled = %d\n", cancelled));
  23.201 +
  23.202 +  if (qemu_filtered_by_qemu)
  23.203 +  {
  23.204 +    XenPci_HideQemuDevices();
  23.205 +    ASSERT(qemu_filtered_by_qemu);
  23.206 +  } 
  23.207 +
  23.208 +  XenPci_Resume(xpdd);
  23.209 +  GntTbl_Resume(xpdd);
  23.210 +  EvtChn_Resume(xpdd); /* this enables interrupts again too */
  23.211 +
  23.212 +  FUNCTION_EXIT();
  23.213 +}
  23.214 +
  23.215 +static VOID
  23.216 +XenPci_SuspendN(PVOID context)
  23.217 +{
  23.218 +  UNREFERENCED_PARAMETER(context);
  23.219 +  
  23.220 +  FUNCTION_ENTER();
  23.221 +  KdPrint((__DRIVER_NAME "     doing nothing on cpu N\n"));
  23.222 +  FUNCTION_EXIT();
  23.223 +}
  23.224 +
  23.225 +/* Called at PASSIVE_LEVEL */
  23.226 +static VOID DDKAPI
  23.227 +XenPci_SuspendResume(WDFWORKITEM workitem)
  23.228 +{
  23.229 +  NTSTATUS status;
  23.230 +  //KAFFINITY ActiveProcessorMask = 0; // this is for Vista+
  23.231 +  WDFDEVICE device = WdfWorkItemGetParentObject(workitem);
  23.232 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(device);
  23.233 +  WDFCHILDLIST child_list = WdfFdoGetDefaultChildList(device);
  23.234 +  WDF_CHILD_LIST_ITERATOR child_iterator;
  23.235 +  WDFDEVICE child_device;
  23.236 +
  23.237 +  FUNCTION_ENTER();
  23.238 +
  23.239 +  if (xpdd->suspend_state == SUSPEND_STATE_NONE)
  23.240 +  {
  23.241 +    xpdd->suspend_state = SUSPEND_STATE_SCHEDULED;
  23.242 +    KeMemoryBarrier();
  23.243 +
  23.244 +    WDF_CHILD_LIST_ITERATOR_INIT(&child_iterator, WdfRetrievePresentChildren);
  23.245 +    WdfChildListBeginIteration(child_list, &child_iterator);
  23.246 +    while ((status = WdfChildListRetrieveNextDevice(child_list, &child_iterator, &child_device, NULL)) == STATUS_SUCCESS)
  23.247 +    {
  23.248 +      KdPrint((__DRIVER_NAME "     Suspending child\n"));
  23.249 +      XenPci_Pdo_Suspend(child_device);
  23.250 +    }
  23.251 +    KdPrint((__DRIVER_NAME "     WdfChildListRetrieveNextDevice = %08x, STATUS_NO_MORE_ENTRIES = %08x\n", status, STATUS_NO_MORE_ENTRIES));
  23.252 +    WdfChildListEndIteration(child_list, &child_iterator);
  23.253 +
  23.254 +    XenBus_Suspend(xpdd);
  23.255 +    EvtChn_Suspend(xpdd);
  23.256 +    XenPci_HighSync(XenPci_Suspend0, XenPci_SuspendN, xpdd);
  23.257 +
  23.258 +    xpdd->suspend_state = SUSPEND_STATE_RESUMING;
  23.259 +    XenBus_Resume(xpdd);
  23.260 +
  23.261 +    WdfChildListBeginIteration(child_list, &child_iterator);
  23.262 +    while ((status = WdfChildListRetrieveNextDevice(child_list, &child_iterator, &child_device, NULL)) == STATUS_SUCCESS)
  23.263 +    {
  23.264 +      KdPrint((__DRIVER_NAME "     Resuming child\n"));
  23.265 +      XenPci_Pdo_Resume(child_device);
  23.266 +    }
  23.267 +    KdPrint((__DRIVER_NAME "     WdfChildListRetrieveNextDevice = %08x, STATUS_NO_MORE_ENTRIES = %08x\n", status, STATUS_NO_MORE_ENTRIES));
  23.268 +    WdfChildListEndIteration(child_list, &child_iterator);
  23.269 +
  23.270 +    xpdd->suspend_state = SUSPEND_STATE_NONE;
  23.271 +  }
  23.272 +  FUNCTION_EXIT();
  23.273 +}
  23.274 +
  23.275 +static void
  23.276 +XenPci_ShutdownHandler(char *path, PVOID context)
  23.277 +{
  23.278 +  NTSTATUS status;
  23.279 +  WDFDEVICE device = context;
  23.280 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(device);
  23.281 +  char *res;
  23.282 +  char *value;
  23.283 +  //KIRQL old_irql;
  23.284 +  WDF_OBJECT_ATTRIBUTES attributes;
  23.285 +  WDF_WORKITEM_CONFIG workitem_config;
  23.286 +  WDFWORKITEM workitem;
  23.287 +
  23.288 +  UNREFERENCED_PARAMETER(path);
  23.289 +
  23.290 +  FUNCTION_ENTER();
  23.291 +
  23.292 +  res = XenBus_Read(xpdd, XBT_NIL, SHUTDOWN_PATH, &value);
  23.293 +  if (res)
  23.294 +  {
  23.295 +    KdPrint(("Error reading shutdown path - %s\n", res));
  23.296 +    XenPci_FreeMem(res);
  23.297 +    return;
  23.298 +  }
  23.299 +
  23.300 +  KdPrint((__DRIVER_NAME "     Shutdown value = %s\n", value));
  23.301 +
  23.302 +  if (strlen(value) && strcmp(value, "suspend") == 0)
  23.303 +  {
  23.304 +    {
  23.305 +      KdPrint((__DRIVER_NAME "     Suspend detected\n"));
  23.306 +      /* we have to queue this as a work item as we stop the xenbus thread, which we are currently running in! */
  23.307 +      WDF_WORKITEM_CONFIG_INIT(&workitem_config, XenPci_SuspendResume);
  23.308 +      WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
  23.309 +      attributes.ParentObject = device;
  23.310 +      status = WdfWorkItemCreate(&workitem_config, &attributes, &workitem);
  23.311 +      // TODO: check status here
  23.312 +      WdfWorkItemEnqueue(workitem);
  23.313 +    }
  23.314 +  }
  23.315 +
  23.316 +  XenPci_FreeMem(value);
  23.317 +
  23.318 +  FUNCTION_EXIT();
  23.319 +}
  23.320 +
  23.321 +static VOID
  23.322 +XenPci_DeviceWatchHandler(char *path, PVOID context)
  23.323 +{
  23.324 +  char **bits;
  23.325 +  int count;
  23.326 +  char *err;
  23.327 +  char *value;
  23.328 +  PXENPCI_DEVICE_DATA xpdd = context;
  23.329 +
  23.330 +  FUNCTION_ENTER();
  23.331 +
  23.332 +  bits = SplitString(path, '/', 4, &count);
  23.333 +  if (count == 3)
  23.334 +  {
  23.335 +    err = XenBus_Read(xpdd, XBT_NIL, path, &value);
  23.336 +    if (err)
  23.337 +    {
  23.338 +      /* obviously path no longer exists, in which case the removal is being taken care of elsewhere and we shouldn't invalidate now */
  23.339 +      XenPci_FreeMem(err);
  23.340 +    }
  23.341 +    else
  23.342 +    {
  23.343 +      XenPci_FreeMem(value);
  23.344 +      /* we probably have to be a bit smarter here and do nothing if xenpci isn't running yet */
  23.345 +      KdPrint((__DRIVER_NAME "     Invalidating Device Relations\n"));
  23.346 +      //IoInvalidateDeviceRelations(xpdd->common.pdo, BusRelations);
  23.347 +    }
  23.348 +  }
  23.349 +  FreeSplitString(bits, count);
  23.350 +
  23.351 +  FUNCTION_EXIT();
  23.352 +}
  23.353 +
  23.354 +NTSTATUS
  23.355 +XenPci_EvtDevicePrepareHardware (WDFDEVICE device, WDFCMRESLIST resources_raw, WDFCMRESLIST resources_translated)
  23.356 +{
  23.357 +  NTSTATUS status = STATUS_SUCCESS;
  23.358 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(device);
  23.359 +  PCM_PARTIAL_RESOURCE_DESCRIPTOR raw_descriptor, translated_descriptor;
  23.360 +  ULONG i;
  23.361 +
  23.362 +  FUNCTION_ENTER();
  23.363 +  
  23.364 +  ASSERT(WdfCmResourceListGetCount(resources_raw) == WdfCmResourceListGetCount(resources_translated));
  23.365 +  
  23.366 +  for (i = 0; i < WdfCmResourceListGetCount(resources_raw); i++)
  23.367 +  {
  23.368 +    raw_descriptor = WdfCmResourceListGetDescriptor(resources_raw, i);
  23.369 +    translated_descriptor = WdfCmResourceListGetDescriptor(resources_translated, i);
  23.370 +    switch (raw_descriptor->Type) {
  23.371 +    case CmResourceTypePort:
  23.372 +      KdPrint((__DRIVER_NAME "     IoPort Address(%x) Length: %d\n", translated_descriptor->u.Port.Start.LowPart, translated_descriptor->u.Port.Length));
  23.373 +      xpdd->platform_ioport_addr = translated_descriptor->u.Port.Start.LowPart;
  23.374 +      xpdd->platform_ioport_len = translated_descriptor->u.Port.Length;
  23.375 +      break;
  23.376 +    case CmResourceTypeMemory:
  23.377 +      KdPrint((__DRIVER_NAME "     Memory mapped CSR:(%x:%x) Length:(%d)\n", translated_descriptor->u.Memory.Start.LowPart, translated_descriptor->u.Memory.Start.HighPart, translated_descriptor->u.Memory.Length));
  23.378 +      KdPrint((__DRIVER_NAME "     Memory flags = %04X\n", translated_descriptor->Flags));
  23.379 +#if 0      
  23.380 +      mmio_freelist_free = 0;
  23.381 +      for (j = 0; j < translated_descriptor->u.Memory.Length >> PAGE_SHIFT; j++)
  23.382 +        put_mmio_on_freelist((xpdd->platform_mmio_addr >> PAGE_SHIFT) + j);
  23.383 +#endif
  23.384 +      xpdd->platform_mmio_addr = translated_descriptor->u.Memory.Start;
  23.385 +      xpdd->platform_mmio_len = translated_descriptor->u.Memory.Length;
  23.386 +      xpdd->platform_mmio_flags = translated_descriptor->Flags;
  23.387 +      break;
  23.388 +    case CmResourceTypeInterrupt:
  23.389 +	    xpdd->irq_level = (KIRQL)translated_descriptor->u.Interrupt.Level;
  23.390 +  	  xpdd->irq_vector = translated_descriptor->u.Interrupt.Vector;
  23.391 +	    xpdd->irq_affinity = translated_descriptor->u.Interrupt.Affinity;
  23.392 +      xpdd->irq_mode = (translated_descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)?Latched:LevelSensitive;
  23.393 +      xpdd->irq_number = raw_descriptor->u.Interrupt.Vector;      
  23.394 +      KdPrint((__DRIVER_NAME "     irq_number = %03x\n", raw_descriptor->u.Interrupt.Vector));
  23.395 +      KdPrint((__DRIVER_NAME "     irq_vector = %03x\n", translated_descriptor->u.Interrupt.Vector));
  23.396 +      KdPrint((__DRIVER_NAME "     irq_level = %03x\n", translated_descriptor->u.Interrupt.Level));
  23.397 +      KdPrint((__DRIVER_NAME "     irq_mode = %s\n", (xpdd->irq_mode == Latched)?"Latched":"LevelSensitive"));
  23.398 +      switch(translated_descriptor->ShareDisposition)
  23.399 +      {
  23.400 +      case CmResourceShareDeviceExclusive:
  23.401 +        KdPrint((__DRIVER_NAME "     ShareDisposition = CmResourceShareDeviceExclusive\n"));
  23.402 +        break;
  23.403 +      case CmResourceShareDriverExclusive:
  23.404 +        KdPrint((__DRIVER_NAME "     ShareDisposition = CmResourceShareDriverExclusive\n"));
  23.405 +        break;
  23.406 +      case CmResourceShareShared:
  23.407 +        KdPrint((__DRIVER_NAME "     ShareDisposition = CmResourceShareShared\n"));
  23.408 +        break;
  23.409 +      default:
  23.410 +        KdPrint((__DRIVER_NAME "     ShareDisposition = %d\n", translated_descriptor->ShareDisposition));
  23.411 +        break;
  23.412 +      }
  23.413 +      break;
  23.414 +    case CmResourceTypeDevicePrivate:
  23.415 +      KdPrint((__DRIVER_NAME "     Private Data: 0x%02x 0x%02x 0x%02x\n", translated_descriptor->u.DevicePrivate.Data[0], translated_descriptor->u.DevicePrivate.Data[1], translated_descriptor->u.DevicePrivate.Data[2]));
  23.416 +      break;
  23.417 +    default:
  23.418 +      KdPrint((__DRIVER_NAME "     Unhandled resource type (0x%x)\n", translated_descriptor->Type));
  23.419 +      break;
  23.420 +    }
  23.421 +  }
  23.422 +
  23.423 +  FUNCTION_EXIT();
  23.424 +  
  23.425 +  return status;
  23.426 +}
  23.427 +
  23.428 +NTSTATUS
  23.429 +XenPci_EvtDeviceD0Entry(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
  23.430 +{
  23.431 +  NTSTATUS status = STATUS_SUCCESS;
  23.432 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(device);
  23.433 +
  23.434 +  UNREFERENCED_PARAMETER(previous_state);
  23.435 +
  23.436 +  FUNCTION_ENTER();
  23.437 +  
  23.438 +  XenPci_Init(xpdd);
  23.439 +  if (tpr_patch_requested && !xpdd->tpr_patched)
  23.440 +  {
  23.441 +    XenPci_MapHalThenPatchKernel(xpdd);
  23.442 +    xpdd->tpr_patched = TRUE;
  23.443 +  }
  23.444 +  GntTbl_Init(xpdd);
  23.445 +  EvtChn_Init(xpdd);
  23.446 +
  23.447 +  FUNCTION_EXIT();
  23.448 +
  23.449 +  return status;
  23.450 +}
  23.451 +
  23.452 +NTSTATUS
  23.453 +XenPci_EvtDeviceD0EntryPostInterruptsEnabled(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
  23.454 +{
  23.455 +  NTSTATUS status = STATUS_SUCCESS;
  23.456 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(device);
  23.457 +  PCHAR response;
  23.458 +
  23.459 +  UNREFERENCED_PARAMETER(previous_state);
  23.460 +
  23.461 +  FUNCTION_ENTER();
  23.462 +  
  23.463 +  XenBus_Init(xpdd);
  23.464 +
  23.465 +  response = XenBus_AddWatch(xpdd, XBT_NIL, SYSRQ_PATH, XenPci_SysrqHandler, xpdd);
  23.466 +  
  23.467 +  response = XenBus_AddWatch(xpdd, XBT_NIL, SHUTDOWN_PATH, XenPci_ShutdownHandler, device);
  23.468 +
  23.469 +  response = XenBus_AddWatch(xpdd, XBT_NIL, "device", XenPci_DeviceWatchHandler, xpdd);
  23.470 +
  23.471 +#if 0
  23.472 +  response = XenBus_AddWatch(xpdd, XBT_NIL, BALLOON_PATH, XenPci_BalloonHandler, Device);
  23.473 +  KdPrint((__DRIVER_NAME "     balloon watch response = '%s'\n", response));
  23.474 +#endif
  23.475 +
  23.476 +#if 0
  23.477 +  status = IoSetDeviceInterfaceState(&xpdd->legacy_interface_name, TRUE);
  23.478 +  if (!NT_SUCCESS(status))
  23.479 +  {
  23.480 +    KdPrint((__DRIVER_NAME "     IoSetDeviceInterfaceState (legacy) failed with status 0x%08x\n", status));
  23.481 +  }
  23.482 +
  23.483 +  status = IoSetDeviceInterfaceState(&xpdd->interface_name, TRUE);
  23.484 +  if (!NT_SUCCESS(status))
  23.485 +  {
  23.486 +    KdPrint((__DRIVER_NAME "     IoSetDeviceInterfaceState failed with status 0x%08x\n", status));
  23.487 +  }
  23.488 +#endif
  23.489 +
  23.490 +  FUNCTION_EXIT();
  23.491 +  
  23.492 +  return status;
  23.493 +}
  23.494 +
  23.495 +NTSTATUS
  23.496 +XenPci_EvtDeviceD0ExitPreInterruptsDisabled(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state)
  23.497 +{
  23.498 +  NTSTATUS status = STATUS_SUCCESS;
  23.499 +  
  23.500 +  UNREFERENCED_PARAMETER(device);
  23.501 +  UNREFERENCED_PARAMETER(target_state);
  23.502 +  
  23.503 +  FUNCTION_ENTER();
  23.504 +  FUNCTION_EXIT();
  23.505 +  
  23.506 +  return status;
  23.507 +}
  23.508 +
  23.509 +NTSTATUS
  23.510 +XenPci_EvtDeviceD0Exit(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state)
  23.511 +{
  23.512 +  NTSTATUS status = STATUS_SUCCESS;
  23.513 +  
  23.514 +  UNREFERENCED_PARAMETER(device);
  23.515 +  UNREFERENCED_PARAMETER(target_state);
  23.516 +  
  23.517 +  FUNCTION_ENTER();
  23.518 +  FUNCTION_EXIT();
  23.519 +  
  23.520 +  return status;
  23.521 +}
  23.522 +
  23.523 +NTSTATUS
  23.524 +XenPci_EvtDeviceReleaseHardware(WDFDEVICE device, WDFCMRESLIST resources_translated)
  23.525 +{
  23.526 +  NTSTATUS status = STATUS_SUCCESS;
  23.527 +  
  23.528 +  UNREFERENCED_PARAMETER(device);
  23.529 +  UNREFERENCED_PARAMETER(resources_translated);
  23.530 +  
  23.531 +  FUNCTION_ENTER();
  23.532 +  FUNCTION_EXIT();
  23.533 +  
  23.534 +  return status;
  23.535 +}
  23.536 +
  23.537 +VOID
  23.538 +XenPci_EvtChildListScanForChildren(WDFCHILDLIST child_list)
  23.539 +{
  23.540 +  NTSTATUS status;
  23.541 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(WdfChildListGetDevice(child_list));
  23.542 +  char *msg;
  23.543 +  char **devices;
  23.544 +  char **instances;
  23.545 +  int i, j;
  23.546 +  CHAR path[128];
  23.547 +  XENPCI_PDO_IDENTIFICATION_DESCRIPTION child_description;
  23.548 +  
  23.549 +  FUNCTION_ENTER();
  23.550 +
  23.551 +  WdfChildListBeginScan(child_list);
  23.552 +
  23.553 +  msg = XenBus_List(xpdd, XBT_NIL, "device", &devices);
  23.554 +  if (!msg)
  23.555 +  {
  23.556 +    for (i = 0; devices[i]; i++)
  23.557 +    {
  23.558 +      RtlStringCbPrintfA(path, ARRAY_SIZE(path), "device/%s", devices[i]);
  23.559 +      msg = XenBus_List(xpdd, XBT_NIL, path, &instances);
  23.560 +      if (!msg)
  23.561 +      {
  23.562 +        for (j = 0; instances[j]; j++)
  23.563 +        {
  23.564 +          /* the device comparison is done as a memory compare so zero-ing the structure is important */
  23.565 +          RtlZeroMemory(&child_description, sizeof(child_description));
  23.566 +          WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&child_description.header, sizeof(child_description));
  23.567 +          RtlStringCbPrintfA(path, ARRAY_SIZE(path), "device/%s/%s", devices[i], instances[j]);
  23.568 +          RtlStringCbCopyA(child_description.path, ARRAY_SIZE(child_description.path), path);
  23.569 +          RtlStringCbCopyA(child_description.device, ARRAY_SIZE(child_description.device), devices[i]);
  23.570 +          child_description.index = atoi(instances[j]);
  23.571 +          status = WdfChildListAddOrUpdateChildDescriptionAsPresent(child_list, &child_description.header, NULL);
  23.572 +          if (!NT_SUCCESS(status))
  23.573 +          {
  23.574 +            KdPrint((__DRIVER_NAME "     WdfChildListAddOrUpdateChildDescriptionAsPresent failed with status 0x%08x\n", status));
  23.575 +          }
  23.576 +          XenPci_FreeMem(instances[j]);
  23.577 +        }
  23.578 +        XenPci_FreeMem(instances);
  23.579 +      }
  23.580 +      else
  23.581 +      {
  23.582 +        // wtf do we do here???
  23.583 +        KdPrint((__DRIVER_NAME "     Failed to list %s tree\n", devices[i]));
  23.584 +      }
  23.585 +      XenPci_FreeMem(devices[i]);
  23.586 +    }
  23.587 +    XenPci_FreeMem(devices);
  23.588 +  }
  23.589 +  else
  23.590 +  {
  23.591 +    // wtf do we do here???
  23.592 +    KdPrint((__DRIVER_NAME "     Failed to list device tree\n"));
  23.593 +  }
  23.594 +
  23.595 +  WdfChildListEndScan(child_list);
  23.596 +  
  23.597 +  FUNCTION_EXIT();
  23.598 +}
  23.599 +
  23.600 +#if 0
  23.601  #if 0
  23.602  static VOID
  23.603  XenBus_BalloonHandler(char *Path, PVOID Data);
  23.604 @@ -106,99 +700,6 @@ XenPci_Dummy_Fdo(PDEVICE_OBJECT device_o
  23.605    return status;
  23.606  }
  23.607  
  23.608 -/*
  23.609 - * Alloc MMIO from the device's MMIO region. There is no corresponding free() fn
  23.610 - */
  23.611 -PHYSICAL_ADDRESS
  23.612 -XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len)
  23.613 -{
  23.614 -  PHYSICAL_ADDRESS addr;
  23.615 -
  23.616 -  len = (len + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
  23.617 -
  23.618 -  addr = xpdd->platform_mmio_addr;
  23.619 -  addr.QuadPart += xpdd->platform_mmio_alloc;
  23.620 -  xpdd->platform_mmio_alloc += len;
  23.621 -
  23.622 -  ASSERT(xpdd->platform_mmio_alloc <= xpdd->platform_mmio_len);
  23.623 -
  23.624 -  return addr;
  23.625 -}
  23.626 -
  23.627 -static VOID
  23.628 -XenPci_MapHalThenPatchKernel(PXENPCI_DEVICE_DATA xpdd)
  23.629 -{
  23.630 -  NTSTATUS status;
  23.631 -  PAUX_MODULE_EXTENDED_INFO amei;
  23.632 -  ULONG module_info_buffer_size;
  23.633 -  ULONG i;
  23.634 -   
  23.635 -  FUNCTION_ENTER();
  23.636 -
  23.637 -  status = AuxKlibInitialize();
  23.638 -  amei = NULL;
  23.639 -  /* buffer size could change between requesting and allocating - need to loop until we are successful */
  23.640 -  while ((status = AuxKlibQueryModuleInformation(&module_info_buffer_size, sizeof(AUX_MODULE_EXTENDED_INFO), amei)) == STATUS_BUFFER_TOO_SMALL || amei == NULL)
  23.641 -  {
  23.642 -    if (amei != NULL)
  23.643 -      ExFreePoolWithTag(amei, XENPCI_POOL_TAG);
  23.644 -    amei = ExAllocatePoolWithTag(NonPagedPool, module_info_buffer_size, XENPCI_POOL_TAG);
  23.645 -  }
  23.646 -  
  23.647 -  KdPrint((__DRIVER_NAME "     AuxKlibQueryModuleInformation = %d\n", status));
  23.648 -  for (i = 0; i < module_info_buffer_size / sizeof(AUX_MODULE_EXTENDED_INFO); i++)
  23.649 -  {
  23.650 -    if (strcmp((PCHAR)amei[i].FullPathName + amei[i].FileNameOffset, "hal.dll") == 0)
  23.651 -    {
  23.652 -      KdPrint((__DRIVER_NAME "     hal.dll found at %p - %p\n", 
  23.653 -        amei[i].BasicInfo.ImageBase,
  23.654 -        ((PUCHAR)amei[i].BasicInfo.ImageBase) + amei[i].ImageSize));
  23.655 -      XenPci_PatchKernel(xpdd, amei[i].BasicInfo.ImageBase, amei[i].ImageSize);
  23.656 -    }
  23.657 -  }
  23.658 -  ExFreePoolWithTag(amei, XENPCI_POOL_TAG);
  23.659 -  FUNCTION_EXIT();
  23.660 -}
  23.661 -
  23.662 -extern ULONG tpr_patch_requested;
  23.663 -
  23.664 -static NTSTATUS
  23.665 -XenPci_Init(PXENPCI_DEVICE_DATA xpdd)
  23.666 -{
  23.667 -  struct xen_add_to_physmap xatp;
  23.668 -  int ret;
  23.669 -
  23.670 -  FUNCTION_ENTER();
  23.671 -
  23.672 -  hvm_get_stubs(xpdd);
  23.673 -
  23.674 -  if (!xpdd->shared_info_area_unmapped.QuadPart)
  23.675 -  {
  23.676 -    ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
  23.677 -    /* this should be safe as this part will never be called on resume where IRQL == HIGH_LEVEL */
  23.678 -    xpdd->shared_info_area_unmapped = XenPci_AllocMMIO(xpdd, PAGE_SIZE);
  23.679 -    xpdd->shared_info_area = MmMapIoSpace(xpdd->shared_info_area_unmapped,
  23.680 -      PAGE_SIZE, MmNonCached);
  23.681 -  }
  23.682 -  KdPrint((__DRIVER_NAME "     shared_info_area_unmapped.QuadPart = %lx\n", xpdd->shared_info_area_unmapped.QuadPart));
  23.683 -  xatp.domid = DOMID_SELF;
  23.684 -  xatp.idx = 0;
  23.685 -  xatp.space = XENMAPSPACE_shared_info;
  23.686 -  xatp.gpfn = (xen_pfn_t)(xpdd->shared_info_area_unmapped.QuadPart >> PAGE_SHIFT);
  23.687 -  KdPrint((__DRIVER_NAME "     gpfn = %x\n", xatp.gpfn));
  23.688 -  ret = HYPERVISOR_memory_op(xpdd, XENMEM_add_to_physmap, &xatp);
  23.689 -  KdPrint((__DRIVER_NAME "     hypervisor memory op (XENMAPSPACE_shared_info) ret = %d\n", ret));
  23.690 -  
  23.691 -  if (tpr_patch_requested)
  23.692 -  {
  23.693 -    XenPci_MapHalThenPatchKernel(xpdd);
  23.694 -  }
  23.695 -
  23.696 -  FUNCTION_EXIT();
  23.697 -
  23.698 -  return STATUS_SUCCESS;
  23.699 -}
  23.700 -
  23.701  static NTSTATUS
  23.702  XenPci_Pnp_IoCompletion(PDEVICE_OBJECT device_object, PIRP irp, PVOID context)
  23.703  {
  23.704 @@ -652,42 +1153,6 @@ XenPci_SysrqHandler(char *path, PVOID co
  23.705    FUNCTION_EXIT();
  23.706  }
  23.707  
  23.708 -static VOID
  23.709 -XenPci_DeviceWatchHandler(char *path, PVOID context)
  23.710 -{
  23.711 -  char **bits;
  23.712 -  int count;
  23.713 -  char *err;
  23.714 -  char *value;
  23.715 -  PXENPCI_DEVICE_DATA xpdd = context;
  23.716 -
  23.717 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  23.718 -
  23.719 -//  KdPrint((__DRIVER_NAME "     path = %s\n", path));
  23.720 -  bits = SplitString(path, '/', 4, &count);
  23.721 -//  KdPrint((__DRIVER_NAME "     count = %d\n", count));
  23.722 -
  23.723 -  if (count == 3)
  23.724 -  {
  23.725 -    err = XenBus_Read(xpdd, XBT_NIL, path, &value);
  23.726 -    if (err)
  23.727 -    {
  23.728 -      /* obviously path no longer exists, in which case the removal is being taken care of elsewhere and we shouldn't invalidate now */
  23.729 -      XenPci_FreeMem(err);
  23.730 -    }
  23.731 -    else
  23.732 -    {
  23.733 -      XenPci_FreeMem(value);
  23.734 -      /* we probably have to be a bit smarter here and do nothing if xenpci isn't running yet */
  23.735 -      KdPrint((__DRIVER_NAME "     Invalidating Device Relations\n"));
  23.736 -      IoInvalidateDeviceRelations(xpdd->common.pdo, BusRelations);
  23.737 -    }
  23.738 -  }
  23.739 -  FreeSplitString(bits, count);
  23.740 -
  23.741 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  23.742 -}
  23.743 -
  23.744  static DDKAPI VOID
  23.745  XenPci_Pnp_StartDeviceCallback(PDEVICE_OBJECT device_object, PVOID context)
  23.746  {
  23.747 @@ -704,14 +1169,15 @@ XenPci_Pnp_StartDeviceCallback(PDEVICE_O
  23.748  
  23.749    EvtChn_Init(xpdd);
  23.750    EvtChn_ConnectInterrupt(xpdd);
  23.751 -
  23.752    XenBus_Init(xpdd);
  23.753  
  23.754    response = XenBus_AddWatch(xpdd, XBT_NIL, SYSRQ_PATH, XenPci_SysrqHandler, xpdd);
  23.755    KdPrint((__DRIVER_NAME "     sysrqwatch response = '%s'\n", response));
  23.756    
  23.757 +#if 0
  23.758    response = XenBus_AddWatch(xpdd, XBT_NIL, SHUTDOWN_PATH, XenPci_ShutdownHandler, xpdd);
  23.759    KdPrint((__DRIVER_NAME "     shutdown watch response = '%s'\n", response));
  23.760 +#endif
  23.761  
  23.762    response = XenBus_AddWatch(xpdd, XBT_NIL, "device", XenPci_DeviceWatchHandler, xpdd);
  23.763    KdPrint((__DRIVER_NAME "     device watch response = '%s'\n", response));
  23.764 @@ -1565,6 +2031,8 @@ XenPci_SystemControl_Fdo(PDEVICE_OBJECT 
  23.765    return status;
  23.766  }
  23.767  
  23.768 +#endif
  23.769 +
  23.770  #if 0
  23.771  static VOID
  23.772  XenPci_BalloonHandler(char *Path, PVOID Data)
    24.1 --- a/xenpci/xenpci_highsync.c	Tue Jan 27 00:47:02 2009 +1100
    24.2 +++ b/xenpci/xenpci_highsync.c	Sat Feb 14 13:35:48 2009 +1100
    24.3 @@ -24,6 +24,7 @@ struct {
    24.4    volatile LONG         nr_spinning;
    24.5    KDPC                  dpcs[MAX_VIRT_CPUS];
    24.6    KEVENT                highsync_complete_event;
    24.7 +  KIRQL                 sync_level;
    24.8    PXENPCI_HIGHSYNC_FUNCTION function0;
    24.9    PXENPCI_HIGHSYNC_FUNCTION functionN;  
   24.10    PVOID                 context;
   24.11 @@ -45,23 +46,17 @@ XenPci_HighSyncCallFunction0(
   24.12    UNREFERENCED_PARAMETER(SystemArgument2);
   24.13  
   24.14    FUNCTION_ENTER();
   24.15 -  FUNCTION_MSG("(CPU = %d)\n", KeGetCurrentProcessorNumber());
   24.16 -
   24.17    ActiveProcessorCount = (ULONG)KeNumberProcessors;
   24.18 -
   24.19 -  KeRaiseIrql(HIGH_LEVEL, &old_irql);
   24.20 +  __asm cli;  
   24.21 +  KeRaiseIrql(highsync_info->sync_level, &old_irql);
   24.22    while (highsync_info->nr_spinning < (LONG)ActiveProcessorCount - 1)
   24.23    {
   24.24      KeStallExecutionProcessor(1);
   24.25      KeMemoryBarrier();
   24.26    }
   24.27 -
   24.28 -  KdPrint((__DRIVER_NAME "     A\n"));
   24.29    highsync_info->function0(highsync_info->context);
   24.30 -  KdPrint((__DRIVER_NAME  "     B\n"));
   24.31    KeLowerIrql(old_irql);
   24.32 -  KdPrint((__DRIVER_NAME  "     C\n"));
   24.33 -  
   24.34 +  __asm sti;
   24.35    highsync_info->do_spin = FALSE;
   24.36    KeMemoryBarrier();  
   24.37    
   24.38 @@ -71,8 +66,6 @@ XenPci_HighSyncCallFunction0(
   24.39      KeStallExecutionProcessor(1);
   24.40      KeMemoryBarrier();
   24.41    }
   24.42 -  KdPrint((__DRIVER_NAME  "     D\n"));
   24.43 -
   24.44    KeSetEvent(&highsync_info->highsync_complete_event, IO_NO_INCREMENT, FALSE);
   24.45  
   24.46    FUNCTION_EXIT();
   24.47 @@ -96,7 +89,7 @@ XenPci_HighSyncCallFunctionN(
   24.48    FUNCTION_MSG("(CPU = %d)\n", KeGetCurrentProcessorNumber());
   24.49  
   24.50    KdPrint((__DRIVER_NAME "     CPU %d spinning...\n", KeGetCurrentProcessorNumber()));
   24.51 -  KeRaiseIrql(HIGH_LEVEL, &old_irql);
   24.52 +  KeRaiseIrql(highsync_info->sync_level, &old_irql);
   24.53    InterlockedIncrement(&highsync_info->nr_spinning);
   24.54    while(highsync_info->do_spin)
   24.55    {
   24.56 @@ -127,11 +120,12 @@ XenPci_HighSync(PXENPCI_HIGHSYNC_FUNCTIO
   24.57    highsync_info->function0 = function0;
   24.58    highsync_info->functionN = functionN;
   24.59    highsync_info->context = context;
   24.60 +  highsync_info->sync_level = HIGH_LEVEL;
   24.61  
   24.62    ActiveProcessorCount = (ULONG)KeNumberProcessors;
   24.63  
   24.64    /* Go to HIGH_LEVEL to prevent any races with Dpc's on the current processor */
   24.65 -  KeRaiseIrql(HIGH_LEVEL, &old_irql);
   24.66 +  KeRaiseIrql(highsync_info->sync_level, &old_irql);
   24.67  
   24.68    highsync_info->do_spin = TRUE;
   24.69    for (i = 0; i < ActiveProcessorCount; i++)
   24.70 @@ -146,6 +140,7 @@ XenPci_HighSync(PXENPCI_HIGHSYNC_FUNCTIO
   24.71      KeInsertQueueDpc(&highsync_info->dpcs[i], NULL, NULL);
   24.72    }
   24.73    KdPrint((__DRIVER_NAME "     All Dpc's queued\n"));
   24.74 +
   24.75    KeMemoryBarrier();
   24.76    KeLowerIrql(old_irql);
   24.77  
    25.1 --- a/xenpci/xenpci_pdo.c	Tue Jan 27 00:47:02 2009 +1100
    25.2 +++ b/xenpci/xenpci_pdo.c	Sat Feb 14 13:35:48 2009 +1100
    25.3 @@ -24,6 +24,1897 @@ Foundation, Inc., 51 Franklin Street, Fi
    25.4  #pragma warning(disable : 4200) // zero-sized array
    25.5  #pragma warning(disable: 4127) // conditional expression is constant
    25.6  
    25.7 +static VOID
    25.8 +XenPci_IS_InterfaceReference(PVOID context)
    25.9 +{
   25.10 +  UNREFERENCED_PARAMETER(context);
   25.11 +  FUNCTION_ENTER();
   25.12 +  FUNCTION_EXIT();
   25.13 +}
   25.14 +
   25.15 +static VOID
   25.16 +XenPci_IS_InterfaceDereference(PVOID context)
   25.17 +{
   25.18 +  UNREFERENCED_PARAMETER(context);
   25.19 +  FUNCTION_ENTER();
   25.20 +  FUNCTION_EXIT();
   25.21 +}
   25.22 +
   25.23 +static BOOLEAN
   25.24 +XenPci_BIS_TranslateBusAddress(PVOID context, PHYSICAL_ADDRESS bus_address, ULONG length, PULONG address_space, PPHYSICAL_ADDRESS translated_address)
   25.25 +{
   25.26 +  UNREFERENCED_PARAMETER(context);
   25.27 +  UNREFERENCED_PARAMETER(length);
   25.28 +  /* actually this isn't right - should look up the gref for the physical address and work backwards from that */
   25.29 +  FUNCTION_ENTER();
   25.30 +  if (*address_space != 0)
   25.31 +  {
   25.32 +    KdPrint((__DRIVER_NAME "      Cannot map I/O space\n"));
   25.33 +    FUNCTION_EXIT();
   25.34 +    return FALSE;
   25.35 +  }
   25.36 +  *translated_address = bus_address;
   25.37 +  FUNCTION_EXIT();
   25.38 +  return TRUE;
   25.39 +}
   25.40 +
   25.41 +static VOID
   25.42 +XenPci_DOP_PutDmaAdapter(PDMA_ADAPTER dma_adapter)
   25.43 +{
   25.44 +  UNREFERENCED_PARAMETER(dma_adapter);
   25.45 +  
   25.46 +  FUNCTION_ENTER();
   25.47 +  // decrement ref count
   25.48 +  FUNCTION_EXIT();
   25.49 +
   25.50 +  return;
   25.51 +}
   25.52 +
   25.53 +static PVOID
   25.54 +XenPci_DOP_AllocateCommonBuffer(
   25.55 +  PDMA_ADAPTER DmaAdapter,
   25.56 +  ULONG Length,
   25.57 +  PPHYSICAL_ADDRESS LogicalAddress,
   25.58 +  BOOLEAN CacheEnabled
   25.59 +)
   25.60 +{
   25.61 +  xen_dma_adapter_t *xen_dma_adapter;
   25.62 +  PXENPCI_DEVICE_DATA xpdd;
   25.63 +  PVOID buffer;
   25.64 +  PFN_NUMBER pfn;
   25.65 +  grant_ref_t gref;
   25.66 +  
   25.67 +  UNREFERENCED_PARAMETER(DmaAdapter);
   25.68 +  UNREFERENCED_PARAMETER(CacheEnabled);
   25.69 +  
   25.70 +  //FUNCTION_ENTER();
   25.71 +
   25.72 +  xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
   25.73 +  xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
   25.74 +
   25.75 +  //KdPrint((__DRIVER_NAME "     Length = %d\n", Length));
   25.76 +  
   25.77 +  buffer = ExAllocatePoolWithTag(NonPagedPool, Length, XENPCI_POOL_TAG);
   25.78 +
   25.79 +  pfn = (PFN_NUMBER)(MmGetPhysicalAddress(buffer).QuadPart >> PAGE_SHIFT);
   25.80 +  ASSERT(pfn);
   25.81 +  gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, pfn, FALSE, INVALID_GRANT_REF);
   25.82 +  ASSERT(gref);
   25.83 +  LogicalAddress->QuadPart = (gref << PAGE_SHIFT) | (PtrToUlong(buffer) & (PAGE_SIZE - 1));
   25.84 +  
   25.85 +  //FUNCTION_EXIT();
   25.86 +  return buffer;
   25.87 +}
   25.88 +
   25.89 +static VOID
   25.90 +XenPci_DOP_FreeCommonBuffer(
   25.91 +  PDMA_ADAPTER dma_adapter,
   25.92 +  ULONG length,
   25.93 +  PHYSICAL_ADDRESS logical_address,
   25.94 +  PVOID virtual_address,
   25.95 +  BOOLEAN cache_enabled
   25.96 +)
   25.97 +{
   25.98 +  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)dma_adapter;
   25.99 +  PXENPCI_DEVICE_DATA xpdd;
  25.100 +  grant_ref_t gref;
  25.101 +
  25.102 +  UNREFERENCED_PARAMETER(dma_adapter);
  25.103 +  UNREFERENCED_PARAMETER(length);
  25.104 +  UNREFERENCED_PARAMETER(logical_address);
  25.105 +  UNREFERENCED_PARAMETER(cache_enabled);
  25.106 +
  25.107 +  FUNCTION_ENTER();
  25.108 +
  25.109 +  xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
  25.110 +
  25.111 +  gref = (grant_ref_t)(logical_address.QuadPart >> PAGE_SHIFT);
  25.112 +  GntTbl_EndAccess(xpdd, gref, FALSE);
  25.113 +  
  25.114 +  ExFreePoolWithTag(virtual_address, XENPCI_POOL_TAG);
  25.115 +
  25.116 +  FUNCTION_EXIT();
  25.117 +}
  25.118 +
  25.119 +static NTSTATUS
  25.120 +XenPci_DOP_AllocateAdapterChannel(
  25.121 +    IN PDMA_ADAPTER  DmaAdapter,
  25.122 +    IN PDEVICE_OBJECT  DeviceObject,
  25.123 +    IN ULONG  NumberOfMapRegisters,
  25.124 +    IN PDRIVER_CONTROL  ExecutionRoutine,
  25.125 +    IN PVOID  Context
  25.126 +    )
  25.127 +{
  25.128 +  IO_ALLOCATION_ACTION action;
  25.129 +  
  25.130 +  UNREFERENCED_PARAMETER(DmaAdapter);
  25.131 +  UNREFERENCED_PARAMETER(NumberOfMapRegisters);
  25.132 +  
  25.133 +  FUNCTION_ENTER();
  25.134 +  action = ExecutionRoutine(DeviceObject, DeviceObject->CurrentIrp, UlongToPtr(64), Context);
  25.135 +  
  25.136 +  switch (action)
  25.137 +  {
  25.138 +  case KeepObject:
  25.139 +    KdPrint((__DRIVER_NAME "     KeepObject\n"));
  25.140 +    break;
  25.141 +  case DeallocateObject:
  25.142 +    KdPrint((__DRIVER_NAME "     DeallocateObject\n"));
  25.143 +    break;
  25.144 +  case DeallocateObjectKeepRegisters:
  25.145 +    KdPrint((__DRIVER_NAME "     DeallocateObjectKeepRegisters\n"));
  25.146 +    break;
  25.147 +  default:
  25.148 +    KdPrint((__DRIVER_NAME "     Unknown action %d\n", action));
  25.149 +    break;
  25.150 +  }
  25.151 +  FUNCTION_EXIT();
  25.152 +  return STATUS_SUCCESS;
  25.153 +}
  25.154 +
  25.155 +static BOOLEAN
  25.156 +XenPci_DOP_FlushAdapterBuffers(
  25.157 +  PDMA_ADAPTER DmaAdapter,
  25.158 +  PMDL Mdl,
  25.159 +  PVOID MapRegisterBase,
  25.160 +  PVOID CurrentVa,
  25.161 +  ULONG Length,
  25.162 +  BOOLEAN WriteToDevice)
  25.163 +{
  25.164 +  UNREFERENCED_PARAMETER(DmaAdapter);
  25.165 +  UNREFERENCED_PARAMETER(Mdl);
  25.166 +  UNREFERENCED_PARAMETER(MapRegisterBase);
  25.167 +  UNREFERENCED_PARAMETER(CurrentVa);
  25.168 +  UNREFERENCED_PARAMETER(Length);
  25.169 +  UNREFERENCED_PARAMETER(WriteToDevice);
  25.170 +
  25.171 +  FUNCTION_ENTER();
  25.172 +  FUNCTION_EXIT();
  25.173 +  return TRUE;
  25.174 +}
  25.175 +
  25.176 +static VOID
  25.177 +XenPci_DOP_FreeAdapterChannel(
  25.178 +    IN PDMA_ADAPTER  DmaAdapter
  25.179 +    )
  25.180 +{
  25.181 +  UNREFERENCED_PARAMETER(DmaAdapter);
  25.182 +
  25.183 +  FUNCTION_ENTER();
  25.184 +  FUNCTION_EXIT();
  25.185 +}
  25.186 +
  25.187 +static VOID
  25.188 +XenPci_DOP_FreeMapRegisters(
  25.189 +  PDMA_ADAPTER DmaAdapter,
  25.190 +  PVOID MapRegisterBase,
  25.191 +  ULONG NumberOfMapRegisters)
  25.192 +{
  25.193 +  UNREFERENCED_PARAMETER(DmaAdapter);
  25.194 +  UNREFERENCED_PARAMETER(MapRegisterBase);
  25.195 +  UNREFERENCED_PARAMETER(NumberOfMapRegisters);
  25.196 +
  25.197 +  FUNCTION_ENTER();
  25.198 +  FUNCTION_EXIT();
  25.199 +}
  25.200 +
  25.201 +static PHYSICAL_ADDRESS
  25.202 +XenPci_DOP_MapTransfer(
  25.203 +    PDMA_ADAPTER DmaAdapter,
  25.204 +    PMDL Mdl,
  25.205 +    PVOID MapRegisterBase,
  25.206 +    PVOID CurrentVa,
  25.207 +    PULONG Length,
  25.208 +    BOOLEAN WriteToDevice)
  25.209 +{
  25.210 +  PHYSICAL_ADDRESS physical;
  25.211 +  
  25.212 +  UNREFERENCED_PARAMETER(DmaAdapter);
  25.213 +  UNREFERENCED_PARAMETER(Mdl);
  25.214 +  UNREFERENCED_PARAMETER(MapRegisterBase);
  25.215 +  UNREFERENCED_PARAMETER(CurrentVa);
  25.216 +  UNREFERENCED_PARAMETER(Length);
  25.217 +  UNREFERENCED_PARAMETER(WriteToDevice);
  25.218 +
  25.219 +  FUNCTION_ENTER();
  25.220 +  
  25.221 +  physical.QuadPart = 0;
  25.222 +  
  25.223 +  FUNCTION_EXIT();
  25.224 +  return physical;
  25.225 +}
  25.226 +
  25.227 +static ULONG
  25.228 +XenPci_DOP_GetDmaAlignment(
  25.229 +  PDMA_ADAPTER DmaAdapter)
  25.230 +{
  25.231 +  UNREFERENCED_PARAMETER(DmaAdapter);
  25.232 +
  25.233 +  FUNCTION_ENTER();
  25.234 +  FUNCTION_EXIT();
  25.235 +  return 0;
  25.236 +}
  25.237 +
  25.238 +static ULONG
  25.239 +XenPci_DOP_ReadDmaCounter(
  25.240 +  PDMA_ADAPTER DmaAdapter)
  25.241 +{
  25.242 +  UNREFERENCED_PARAMETER(DmaAdapter);
  25.243 +
  25.244 +  FUNCTION_ENTER();
  25.245 +  FUNCTION_EXIT();
  25.246 +  return 0;
  25.247 +}
  25.248 +
  25.249 +static NTSTATUS
  25.250 +XenPci_DOP_GetScatterGatherList(
  25.251 +  PDMA_ADAPTER DmaAdapter,
  25.252 +  PDEVICE_OBJECT DeviceObject,
  25.253 +  PMDL Mdl,
  25.254 +  PVOID CurrentVa,
  25.255 +  ULONG Length,
  25.256 +  PDRIVER_LIST_CONTROL ExecutionRoutine,
  25.257 +  PVOID Context,
  25.258 +  BOOLEAN WriteToDevice)
  25.259 +{
  25.260 +  UNREFERENCED_PARAMETER(DmaAdapter);
  25.261 +  UNREFERENCED_PARAMETER(DeviceObject);
  25.262 +  UNREFERENCED_PARAMETER(Mdl);
  25.263 +  UNREFERENCED_PARAMETER(CurrentVa);
  25.264 +  UNREFERENCED_PARAMETER(Length);
  25.265 +  UNREFERENCED_PARAMETER(ExecutionRoutine);
  25.266 +  UNREFERENCED_PARAMETER(Context);
  25.267 +  UNREFERENCED_PARAMETER(WriteToDevice);
  25.268 +
  25.269 +  FUNCTION_ENTER();
  25.270 +  FUNCTION_EXIT();
  25.271 +  return STATUS_SUCCESS;
  25.272 +}
  25.273 +
  25.274 +#define MAP_TYPE_VIRTUAL  1
  25.275 +#define MAP_TYPE_MDL      2
  25.276 +#define MAP_TYPE_REMAPPED 3
  25.277 +
  25.278 +typedef struct {
  25.279 +  ULONG map_type;
  25.280 +  PVOID aligned_buffer;
  25.281 +  PVOID unaligned_buffer;
  25.282 +  ULONG copy_length;
  25.283 +} sg_extra_t;
  25.284 +
  25.285 +static VOID
  25.286 +XenPci_DOP_PutScatterGatherList(
  25.287 +    IN PDMA_ADAPTER DmaAdapter,
  25.288 +    IN PSCATTER_GATHER_LIST ScatterGather,
  25.289 +    IN BOOLEAN WriteToDevice
  25.290 +    )
  25.291 +{
  25.292 +  xen_dma_adapter_t *xen_dma_adapter;
  25.293 +  PXENPCI_DEVICE_DATA xpdd;
  25.294 +  ULONG i;
  25.295 +  sg_extra_t *sg_extra;
  25.296 +
  25.297 +  UNREFERENCED_PARAMETER(WriteToDevice);
  25.298 +  
  25.299 +  //FUNCTION_ENTER();
  25.300 +
  25.301 +  xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
  25.302 +  xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
  25.303 +  
  25.304 +  sg_extra = (sg_extra_t *)((PUCHAR)ScatterGather + FIELD_OFFSET(SCATTER_GATHER_LIST, Elements) +
  25.305 +    (sizeof(SCATTER_GATHER_ELEMENT)) * ScatterGather->NumberOfElements);
  25.306 +
  25.307 +  switch (sg_extra->map_type)
  25.308 +  {
  25.309 +  case MAP_TYPE_REMAPPED:
  25.310 +    for (i = 0; i < ScatterGather->NumberOfElements; i++)
  25.311 +    {
  25.312 +      grant_ref_t gref;
  25.313 +      gref = (grant_ref_t)(ScatterGather->Elements[i].Address.QuadPart >> PAGE_SHIFT);
  25.314 +      GntTbl_EndAccess(xpdd, gref, FALSE);
  25.315 +      ScatterGather->Elements[i].Address.QuadPart = -1;
  25.316 +    }
  25.317 +    if (!WriteToDevice)
  25.318 +      memcpy(sg_extra->unaligned_buffer, sg_extra->aligned_buffer, sg_extra->copy_length);
  25.319 +    ExFreePoolWithTag(sg_extra->aligned_buffer, XENPCI_POOL_TAG);
  25.320 +    break;
  25.321 +  case MAP_TYPE_MDL:
  25.322 +    for (i = 0; i < ScatterGather->NumberOfElements; i++)
  25.323 +    {
  25.324 +      grant_ref_t gref;
  25.325 +      gref = (grant_ref_t)(ScatterGather->Elements[i].Address.QuadPart >> PAGE_SHIFT);
  25.326 +      GntTbl_EndAccess(xpdd, gref, FALSE);
  25.327 +      ScatterGather->Elements[i].Address.QuadPart = -1;
  25.328 +    }
  25.329 +    break;
  25.330 +  case MAP_TYPE_VIRTUAL:
  25.331 +    break;
  25.332 +  }
  25.333 +  //FUNCTION_EXIT();
  25.334 +}
  25.335 +
  25.336 +static NTSTATUS
  25.337 +XenPci_DOP_CalculateScatterGatherList(
  25.338 +  PDMA_ADAPTER DmaAdapter,
  25.339 +  PMDL Mdl,
  25.340 +  PVOID CurrentVa,
  25.341 +  ULONG Length,
  25.342 +  PULONG ScatterGatherListSize,
  25.343 +  PULONG NumberOfMapRegisters
  25.344 +  )
  25.345 +{
  25.346 +  ULONG elements;
  25.347 +  PMDL curr_mdl;
  25.348 +  
  25.349 +  UNREFERENCED_PARAMETER(DmaAdapter);
  25.350 +  UNREFERENCED_PARAMETER(Mdl);
  25.351 +  
  25.352 +  FUNCTION_ENTER();
  25.353 +  
  25.354 +  KdPrint((__DRIVER_NAME "     Mdl = %p\n", Mdl));
  25.355 +  KdPrint((__DRIVER_NAME "     CurrentVa = %p\n", CurrentVa));
  25.356 +  KdPrint((__DRIVER_NAME "     Length = %d\n", Length));
  25.357 +  if (Mdl)
  25.358 +  {
  25.359 +    for (curr_mdl = Mdl, elements = 0; curr_mdl; curr_mdl = curr_mdl->Next)
  25.360 +      elements += ADDRESS_AND_SIZE_TO_SPAN_PAGES(CurrentVa, Length);
  25.361 +  }
  25.362 +  else
  25.363 +  {
  25.364 +    elements = ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, Length) + 1;
  25.365 +  }
  25.366 +  
  25.367 +  *ScatterGatherListSize = FIELD_OFFSET(SCATTER_GATHER_LIST, Elements)
  25.368 +    + sizeof(SCATTER_GATHER_ELEMENT) * elements
  25.369 +    + sizeof(sg_extra_t);
  25.370 +  if (NumberOfMapRegisters)
  25.371 +    *NumberOfMapRegisters = 1;
  25.372 +
  25.373 +  KdPrint((__DRIVER_NAME "     ScatterGatherListSize = %d\n", *ScatterGatherListSize));
  25.374 +
  25.375 +  FUNCTION_EXIT();
  25.376 +  return STATUS_SUCCESS;
  25.377 +}
  25.378 +
  25.379 +static NTSTATUS
  25.380 +XenPci_DOP_BuildScatterGatherList(
  25.381 +  IN PDMA_ADAPTER DmaAdapter,
  25.382 +  IN PDEVICE_OBJECT DeviceObject,
  25.383 +  IN PMDL Mdl,
  25.384 +  IN PVOID CurrentVa,
  25.385 +  IN ULONG Length,
  25.386 +  IN PDRIVER_LIST_CONTROL ExecutionRoutine,
  25.387 +  IN PVOID Context,
  25.388 +  IN BOOLEAN WriteToDevice,
  25.389 +  IN PVOID ScatterGatherBuffer,
  25.390 +  IN ULONG ScatterGatherBufferLength)
  25.391 +{
  25.392 +  ULONG i;
  25.393 +  PSCATTER_GATHER_LIST sglist = ScatterGatherBuffer;
  25.394 +  PUCHAR ptr;
  25.395 +  ULONG remaining = Length;
  25.396 +  ULONG total_remaining;
  25.397 +  xen_dma_adapter_t *xen_dma_adapter;
  25.398 +  PXENPCI_DEVICE_DATA xpdd;
  25.399 +  sg_extra_t *sg_extra;
  25.400 +  PMDL curr_mdl;
  25.401 +  ULONG map_type;
  25.402 +  ULONG sg_element;
  25.403 +  ULONG offset;
  25.404 +  PFN_NUMBER pfn;
  25.405 +  grant_ref_t gref;
  25.406 +  
  25.407 +  UNREFERENCED_PARAMETER(WriteToDevice);
  25.408 +
  25.409 +  //FUNCTION_ENTER();
  25.410 +
  25.411 +  xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
  25.412 +  xpdd = GetXpdd(xen_dma_adapter->xppdd->wdf_device_bus_fdo);
  25.413 +
  25.414 +  ASSERT(Mdl);
  25.415 +  if (xen_dma_adapter->dma_extension)
  25.416 +  {
  25.417 +    if (xen_dma_adapter->dma_extension->need_virtual_address(DeviceObject->CurrentIrp))
  25.418 +    {
  25.419 +      ASSERT(!Mdl->Next); /* can only virtual a single buffer */
  25.420 +      map_type = MAP_TYPE_VIRTUAL;
  25.421 +      sglist->NumberOfElements = 1;
  25.422 +    }
  25.423 +    else
  25.424 +    {
  25.425 +      ULONG alignment = xen_dma_adapter->dma_extension->get_alignment(DeviceObject->CurrentIrp);
  25.426 +      if (PtrToUlong(CurrentVa) & (alignment - 1))
  25.427 +      {
  25.428 +        ASSERT(!Mdl->Next); /* can only remap a single buffer */
  25.429 +        map_type = MAP_TYPE_REMAPPED;
  25.430 +        sglist->NumberOfElements = ADDRESS_AND_SIZE_TO_SPAN_PAGES(NULL, Length);
  25.431 +      }
  25.432 +      else
  25.433 +      {
  25.434 +        map_type = MAP_TYPE_MDL;
  25.435 +        for (curr_mdl = Mdl, sglist->NumberOfElements = 0; curr_mdl; curr_mdl = curr_mdl->Next)
  25.436 +          sglist->NumberOfElements += ADDRESS_AND_SIZE_TO_SPAN_PAGES(
  25.437 +            MmGetMdlVirtualAddress(curr_mdl), MmGetMdlByteCount(curr_mdl));
  25.438 +      }
  25.439 +    }
  25.440 +  }
  25.441 +  else
  25.442 +  {
  25.443 +    map_type = MAP_TYPE_MDL;
  25.444 +    for (curr_mdl = Mdl, sglist->NumberOfElements = 0; curr_mdl; curr_mdl = curr_mdl->Next)
  25.445 +      sglist->NumberOfElements += ADDRESS_AND_SIZE_TO_SPAN_PAGES(
  25.446 +        MmGetMdlVirtualAddress(curr_mdl), MmGetMdlByteCount(curr_mdl));
  25.447 +  }
  25.448 +  if (ScatterGatherBufferLength < FIELD_OFFSET(SCATTER_GATHER_LIST, Elements) +
  25.449 +    sizeof(SCATTER_GATHER_ELEMENT) * sglist->NumberOfElements + sizeof(sg_extra_t))
  25.450 +  {
  25.451 +    return STATUS_BUFFER_TOO_SMALL;
  25.452 +  }
  25.453 +  
  25.454 +  sg_extra = (sg_extra_t *)((PUCHAR)sglist + FIELD_OFFSET(SCATTER_GATHER_LIST, Elements) +
  25.455 +    (sizeof(SCATTER_GATHER_ELEMENT)) * sglist->NumberOfElements);
  25.456 +  
  25.457 +  sg_extra->map_type = map_type;
  25.458 +  switch (map_type)
  25.459 +  {
  25.460 +  case MAP_TYPE_MDL:
  25.461 +    //KdPrint((__DRIVER_NAME "     MAP_TYPE_MDL\n"));
  25.462 +    total_remaining = Length;
  25.463 +    for (sg_element = 0, curr_mdl = Mdl; curr_mdl; curr_mdl = curr_mdl->Next)
  25.464 +    {
  25.465 +      remaining = MmGetMdlByteCount(curr_mdl);
  25.466 +      if (!MmGetMdlByteOffset(Mdl) && (PtrToUlong(CurrentVa) & (PAGE_SIZE - 1)))
  25.467 +        offset = (PtrToUlong(CurrentVa) & (PAGE_SIZE - 1));
  25.468 +      else
  25.469 +        offset = MmGetMdlByteOffset(curr_mdl);
  25.470 +      for (i = 0; i < ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(curr_mdl), MmGetMdlByteCount(curr_mdl)); i++)
  25.471 +      {
  25.472 +//KdPrint((__DRIVER_NAME "     element = %d\n", sg_element));
  25.473 +//KdPrint((__DRIVER_NAME "     remaining = %d\n", remaining));
  25.474 +        pfn = MmGetMdlPfnArray(curr_mdl)[i];
  25.475 +        ASSERT(pfn);
  25.476 +        gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, pfn, FALSE, INVALID_GRANT_REF);
  25.477 +        ASSERT(gref != INVALID_GRANT_REF);
  25.478 +        sglist->Elements[sg_element].Address.QuadPart = (LONGLONG)(gref << PAGE_SHIFT) | offset;
  25.479 +        sglist->Elements[sg_element].Length = min(min(PAGE_SIZE - offset, remaining), total_remaining);
  25.480 +        total_remaining -= sglist->Elements[sg_element].Length;
  25.481 +        remaining -= sglist->Elements[sg_element].Length;
  25.482 +        offset = 0;
  25.483 +        sg_element++;
  25.484 +      }
  25.485 +    }
  25.486 +    break;
  25.487 +  case MAP_TYPE_REMAPPED:
  25.488 +    //KdPrint((__DRIVER_NAME "     MAP_TYPE_REMAPPED\n"));
  25.489 +    sg_extra->aligned_buffer = ExAllocatePoolWithTag(NonPagedPool, max(Length, PAGE_SIZE), XENPCI_POOL_TAG);
  25.490 +    if (!sg_extra->aligned_buffer)
  25.491 +    {
  25.492 +      //KdPrint((__DRIVER_NAME "     MAP_TYPE_REMAPPED buffer allocation failed - requested va = %p, length = %d\n", CurrentVa, Length));
  25.493 +      return STATUS_INSUFFICIENT_RESOURCES;
  25.494 +    }
  25.495 +    sg_extra->unaligned_buffer = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
  25.496 +    ASSERT(sg_extra->unaligned_buffer); /* lazy */
  25.497 +    if (!MmGetMdlByteOffset(Mdl) && (PtrToUlong(CurrentVa) & (PAGE_SIZE - 1)))
  25.498 +      sg_extra->unaligned_buffer = (PUCHAR)sg_extra->unaligned_buffer + (PtrToUlong(CurrentVa) & (PAGE_SIZE - 1));
  25.499 +    sg_extra->copy_length = Length;
  25.500 +    if (WriteToDevice)
  25.501 +      memcpy(sg_extra->aligned_buffer, sg_extra->unaligned_buffer, sg_extra->copy_length);
  25.502 +    for (sg_element = 0, remaining = Length; 
  25.503 +      sg_element < ADDRESS_AND_SIZE_TO_SPAN_PAGES(sg_extra->aligned_buffer, Length); sg_element++)
  25.504 +    {
  25.505 +      pfn = (PFN_NUMBER)(MmGetPhysicalAddress((PUCHAR)sg_extra->aligned_buffer + (sg_element << PAGE_SHIFT)).QuadPart >> PAGE_SHIFT);
  25.506 +      ASSERT(pfn);
  25.507 +      gref = (grant_ref_t)GntTbl_GrantAccess(xpdd, 0, pfn, FALSE, INVALID_GRANT_REF);
  25.508 +      ASSERT(gref);
  25.509 +      sglist->Elements[sg_element].Address.QuadPart = (ULONGLONG)gref << PAGE_SHIFT;
  25.510 +      sglist->Elements[sg_element].Length = min(PAGE_SIZE, remaining);
  25.511 +      remaining -= sglist->Elements[sg_element].Length;
  25.512 +    }
  25.513 +    break;
  25.514 +  case MAP_TYPE_VIRTUAL:
  25.515 +    //KdPrint((__DRIVER_NAME "     MAP_TYPE_VIRTUAL\n"));
  25.516 +    ptr = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
  25.517 +    ASSERT(ptr); /* lazy */
  25.518 +    if (!MmGetMdlByteOffset(Mdl) && (PtrToUlong(CurrentVa) & (PAGE_SIZE - 1)))
  25.519 +      ptr += (PtrToUlong(CurrentVa) & (PAGE_SIZE - 1));
  25.520 +    sglist->Elements[0].Address.QuadPart = (ULONGLONG)ptr;
  25.521 +    sglist->Elements[0].Length = Length;
  25.522 +    break;
  25.523 +  }
  25.524 +#if 0
  25.525 +  KdPrint((__DRIVER_NAME "     Mdl = %p, CurrentVa = %p, Mdl->Va = %p, Offset = %d, Length = %d\n", 
  25.526 +    Mdl, CurrentVa, MmGetMdlVirtualAddress(Mdl), MmGetMdlByteOffset(Mdl), Length));
  25.527 +  for (i = 0; i < sglist->NumberOfElements; i++)
  25.528 +  {
  25.529 +    KdPrint((__DRIVER_NAME "     sge[%d]->Address = %08x%08x, Length = %d\n", i, sglist->Elements[i].Address.HighPart,
  25.530 +      sglist->Elements[i].Address.LowPart, sglist->Elements[i].Length));
  25.531 +  }
  25.532 +#endif
  25.533 +  ExecutionRoutine(DeviceObject, DeviceObject->CurrentIrp, ScatterGatherBuffer, Context);
  25.534 +
  25.535 +  //FUNCTION_EXIT();
  25.536 +  
  25.537 +  return STATUS_SUCCESS;
  25.538 +}
  25.539 +
  25.540 +static NTSTATUS
  25.541 +XenPci_DOP_BuildMdlFromScatterGatherList(
  25.542 +  PDMA_ADAPTER DmaAdapter,
  25.543 +  PSCATTER_GATHER_LIST ScatterGather,
  25.544 +  PMDL OriginalMdl,
  25.545 +  PMDL *TargetMdl)
  25.546 +{
  25.547 +  UNREFERENCED_PARAMETER(DmaAdapter);
  25.548 +  UNREFERENCED_PARAMETER(ScatterGather);
  25.549 +  UNREFERENCED_PARAMETER(OriginalMdl);
  25.550 +  UNREFERENCED_PARAMETER(TargetMdl);
  25.551 +
  25.552 +  FUNCTION_ENTER();
  25.553 +  FUNCTION_EXIT();
  25.554 +  return STATUS_UNSUCCESSFUL;
  25.555 +}
  25.556 +
  25.557 +static PDMA_ADAPTER
  25.558 +XenPci_BIS_GetDmaAdapter(PVOID context, PDEVICE_DESCRIPTION device_description, PULONG number_of_map_registers)
  25.559 +{
  25.560 +  xen_dma_adapter_t *xen_dma_adapter;
  25.561 +  PDEVICE_OBJECT curr, prev;
  25.562 +  PDRIVER_OBJECT fdo_driver_object;
  25.563 +  PVOID fdo_driver_extension;
  25.564 +  
  25.565 +  UNREFERENCED_PARAMETER(device_description);
  25.566 +  
  25.567 +  FUNCTION_ENTER();
  25.568 +
  25.569 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  25.570 +  KdPrint((__DRIVER_NAME "     Device Description = %p:\n", device_description));
  25.571 +  KdPrint((__DRIVER_NAME "      Version  = %d\n", device_description->Version));
  25.572 +  KdPrint((__DRIVER_NAME "      Master = %d\n", device_description->Master));
  25.573 +  KdPrint((__DRIVER_NAME "      ScatterGather = %d\n", device_description->ScatterGather));
  25.574 +  KdPrint((__DRIVER_NAME "      DemandMode = %d\n", device_description->DemandMode));
  25.575 +  KdPrint((__DRIVER_NAME "      AutoInitialize = %d\n", device_description->AutoInitialize));
  25.576 +  KdPrint((__DRIVER_NAME "      Dma32BitAddresses = %d\n", device_description->Dma32BitAddresses));
  25.577 +  KdPrint((__DRIVER_NAME "      IgnoreCount = %d\n", device_description->IgnoreCount));
  25.578 +  KdPrint((__DRIVER_NAME "      Dma64BitAddresses = %d\n", device_description->Dma64BitAddresses));
  25.579 +  KdPrint((__DRIVER_NAME "      BusNumber = %d\n", device_description->BusNumber));
  25.580 +  KdPrint((__DRIVER_NAME "      DmaChannel = %d\n", device_description->DmaChannel));
  25.581 +  KdPrint((__DRIVER_NAME "      InterfaceType = %d\n", device_description->InterfaceType));
  25.582 +  KdPrint((__DRIVER_NAME "      DmaWidth = %d\n", device_description->DmaWidth));
  25.583 +  KdPrint((__DRIVER_NAME "      DmaSpeed = %d\n", device_description->DmaSpeed));
  25.584 +  KdPrint((__DRIVER_NAME "      MaximumLength = %d\n", device_description->MaximumLength));
  25.585 +  KdPrint((__DRIVER_NAME "      DmaPort = %d\n", device_description->DmaPort));
  25.586 +  
  25.587 +/*
  25.588 +we have to allocate PAGE_SIZE bytes here because Windows thinks this is
  25.589 +actually an ADAPTER_OBJECT, and then the verifier crashes because
  25.590 +Windows accessed beyond the end of the structure :(
  25.591 +*/
  25.592 +  xen_dma_adapter = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
  25.593 +  RtlZeroMemory(xen_dma_adapter, PAGE_SIZE);
  25.594 +  xen_dma_adapter->dma_adapter.Version = 2;
  25.595 +  xen_dma_adapter->dma_adapter.Size = sizeof(DMA_ADAPTER); //xen_dma_adapter_t);
  25.596 +  xen_dma_adapter->dma_adapter.DmaOperations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DMA_OPERATIONS), XENPCI_POOL_TAG);
  25.597 +  //xen_dma_adapter->dma_adapter.DmaOperations = &xen_dma_adapter->dma_operations;
  25.598 +  xen_dma_adapter->dma_adapter.DmaOperations->Size = sizeof(DMA_OPERATIONS);
  25.599 +  xen_dma_adapter->dma_adapter.DmaOperations->PutDmaAdapter = XenPci_DOP_PutDmaAdapter;
  25.600 +  xen_dma_adapter->dma_adapter.DmaOperations->AllocateCommonBuffer = XenPci_DOP_AllocateCommonBuffer;
  25.601 +  xen_dma_adapter->dma_adapter.DmaOperations->FreeCommonBuffer = XenPci_DOP_FreeCommonBuffer;
  25.602 +  xen_dma_adapter->dma_adapter.DmaOperations->AllocateAdapterChannel = XenPci_DOP_AllocateAdapterChannel;
  25.603 +  xen_dma_adapter->dma_adapter.DmaOperations->FlushAdapterBuffers = XenPci_DOP_FlushAdapterBuffers;
  25.604 +  xen_dma_adapter->dma_adapter.DmaOperations->FreeAdapterChannel = XenPci_DOP_FreeAdapterChannel;
  25.605 +  xen_dma_adapter->dma_adapter.DmaOperations->FreeMapRegisters = XenPci_DOP_FreeMapRegisters;
  25.606 +  xen_dma_adapter->dma_adapter.DmaOperations->MapTransfer = XenPci_DOP_MapTransfer;
  25.607 +  xen_dma_adapter->dma_adapter.DmaOperations->GetDmaAlignment = XenPci_DOP_GetDmaAlignment;
  25.608 +  xen_dma_adapter->dma_adapter.DmaOperations->ReadDmaCounter = XenPci_DOP_ReadDmaCounter;
  25.609 +  xen_dma_adapter->dma_adapter.DmaOperations->GetScatterGatherList = XenPci_DOP_GetScatterGatherList;
  25.610 +  xen_dma_adapter->dma_adapter.DmaOperations->PutScatterGatherList = XenPci_DOP_PutScatterGatherList;
  25.611 +  xen_dma_adapter->dma_adapter.DmaOperations->CalculateScatterGatherList = XenPci_DOP_CalculateScatterGatherList;
  25.612 +  xen_dma_adapter->dma_adapter.DmaOperations->BuildScatterGatherList = XenPci_DOP_BuildScatterGatherList;
  25.613 +  xen_dma_adapter->dma_adapter.DmaOperations->BuildMdlFromScatterGatherList = XenPci_DOP_BuildMdlFromScatterGatherList;
  25.614 +  xen_dma_adapter->xppdd = context;
  25.615 +  xen_dma_adapter->dma_extension = NULL;
  25.616 +
  25.617 +  KdPrint((__DRIVER_NAME "     About to call IoGetAttachedDeviceReference\n"));
  25.618 +  curr = IoGetAttachedDeviceReference(WdfDeviceWdmGetDeviceObject(xen_dma_adapter->xppdd->wdf_device));
  25.619 +  //curr = WdfDeviceWdmGetAttachedDevice(xen_dma_adapter->xppdd->wdf_device);
  25.620 +  KdPrint((__DRIVER_NAME "     Before start of loop - curr = %p\n", curr));
  25.621 +  while (curr != NULL)
  25.622 +  {
  25.623 +    fdo_driver_object = curr->DriverObject;
  25.624 +    KdPrint((__DRIVER_NAME "     fdo_driver_object = %p\n", fdo_driver_object));
  25.625 +    if (fdo_driver_object)
  25.626 +    {
  25.627 +      fdo_driver_extension = IoGetDriverObjectExtension(fdo_driver_object, UlongToPtr(XEN_DMA_DRIVER_EXTENSION_MAGIC));
  25.628 +      if (fdo_driver_extension)
  25.629 +      {
  25.630 +        xen_dma_adapter->dma_extension = (dma_driver_extension_t *)fdo_driver_extension;
  25.631 +        ObDereferenceObject(curr);
  25.632 +        break;
  25.633 +      }
  25.634 +    }
  25.635 +    prev = curr;
  25.636 +    curr = IoGetLowerDeviceObject(curr);
  25.637 +    ObDereferenceObject(prev);
  25.638 +  }
  25.639 +  KdPrint((__DRIVER_NAME "     End of loop\n"));
  25.640 +
  25.641 +  *number_of_map_registers = 1024; //1024; /* why not... */
  25.642 +
  25.643 +  FUNCTION_EXIT();
  25.644 +
  25.645 +  return &xen_dma_adapter->dma_adapter;
  25.646 +}
  25.647 +
  25.648 +static ULONG
  25.649 +XenPci_BIS_SetBusData(PVOID context, ULONG data_type, PVOID buffer, ULONG offset, ULONG length)
  25.650 +{
  25.651 +  UNREFERENCED_PARAMETER(context);
  25.652 +  UNREFERENCED_PARAMETER(data_type);
  25.653 +  UNREFERENCED_PARAMETER(buffer);
  25.654 +  UNREFERENCED_PARAMETER(offset);
  25.655 +  UNREFERENCED_PARAMETER(length);
  25.656 +  
  25.657 +  FUNCTION_ENTER();
  25.658 +  FUNCTION_EXIT();
  25.659 +  return 0;
  25.660 +}
  25.661 +
  25.662 +static ULONG
  25.663 +XenPci_BIS_GetBusData(PVOID context, ULONG data_type, PVOID buffer, ULONG offset, ULONG length)
  25.664 +{
  25.665 +  UNREFERENCED_PARAMETER(context);
  25.666 +  UNREFERENCED_PARAMETER(data_type);
  25.667 +  UNREFERENCED_PARAMETER(buffer);
  25.668 +  UNREFERENCED_PARAMETER(offset);
  25.669 +  UNREFERENCED_PARAMETER(length);
  25.670 +  
  25.671 +  FUNCTION_ENTER();
  25.672 +  FUNCTION_EXIT();
  25.673 +  return 0;
  25.674 +}
  25.675 +
  25.676 +/*
  25.677 +Called at PASSIVE_LEVEL(?)
  25.678 +Called during restore
  25.679 +*/
  25.680 +
  25.681 +static ULONG
  25.682 +XenPci_ReadBackendState(PXENPCI_PDO_DEVICE_DATA xppdd)
  25.683 +{
  25.684 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  25.685 +  char path[128];
  25.686 +  char *value;
  25.687 +  char *err;
  25.688 +  ULONG backend_state;
  25.689 +  
  25.690 +  RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
  25.691 +  err = XenBus_Read(xpdd, XBT_NIL, path, &value);
  25.692 +  if (err)
  25.693 +  {
  25.694 +    XenPci_FreeMem(err);
  25.695 +    return XenbusStateUnknown;
  25.696 +  }
  25.697 +  else
  25.698 +  {
  25.699 +    backend_state = atoi(value);
  25.700 +    XenPci_FreeMem(value);
  25.701 +    return backend_state;
  25.702 +  }
  25.703 +}
  25.704 +
  25.705 +static VOID
  25.706 +XenPci_BackEndStateHandler(char *path, PVOID context)
  25.707 +{
  25.708 +  WDFDEVICE device = context;
  25.709 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  25.710 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  25.711 +  ULONG new_backend_state;
  25.712 +
  25.713 +#if !DBG
  25.714 +  UNREFERENCED_PARAMETER(path);
  25.715 +#endif
  25.716 +  
  25.717 +  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  25.718 +
  25.719 +  /* check that path == device/id/state */
  25.720 +  //RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
  25.721 +  new_backend_state = XenPci_ReadBackendState(xppdd);
  25.722 +  if (new_backend_state == XenbusStateUnknown)
  25.723 +  {
  25.724 +    if (xpdd->suspend_state != SUSPEND_STATE_NONE)
  25.725 +      return;
  25.726 +    KdPrint(("Failed to read %s, assuming closed\n", path));
  25.727 +    new_backend_state = XenbusStateClosed;
  25.728 +  }
  25.729 +
  25.730 +  if (xppdd->backend_state == new_backend_state)
  25.731 +  {
  25.732 +    KdPrint((__DRIVER_NAME "     state unchanged\n"));
  25.733 +    //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  25.734 +    return;
  25.735 +  }
  25.736 +
  25.737 +  xppdd->backend_state = new_backend_state;
  25.738 +
  25.739 +  switch (xppdd->backend_state)
  25.740 +  {
  25.741 +  case XenbusStateUnknown:
  25.742 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Unknown (%s)\n", path));  
  25.743 +    break;
  25.744 +
  25.745 +  case XenbusStateInitialising:
  25.746 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialising (%s)\n", path));  
  25.747 +    break;
  25.748 +
  25.749 +  case XenbusStateInitWait:
  25.750 +    KdPrint((__DRIVER_NAME "     Backend State Changed to InitWait (%s)\n", path));  
  25.751 +    break;
  25.752 +
  25.753 +  case XenbusStateInitialised:
  25.754 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialised (%s)\n", path));  
  25.755 +    break;
  25.756 +
  25.757 +  case XenbusStateConnected:
  25.758 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Connected (%s)\n", path));    
  25.759 +    break;
  25.760 +
  25.761 +  case XenbusStateClosing:
  25.762 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Closing (%s)\n", path));  
  25.763 +    if (xpdd->suspend_state == SUSPEND_STATE_NONE)
  25.764 +    {
  25.765 +      WdfPdoRequestEject(device);
  25.766 +#if 0
  25.767 +      if (xppdd->common.device_usage_paging
  25.768 +        || xppdd->common.device_usage_dump
  25.769 +        || xppdd->common.device_usage_hibernation)
  25.770 +      {
  25.771 +        KdPrint((__DRIVER_NAME "     Not closing device because it is in use\n"));
  25.772 +        /* in use by page file, dump file, or hiber file - can't close */
  25.773 +        /* we should probably re-check if the device usage changes in the future */
  25.774 +      }
  25.775 +      else
  25.776 +      {
  25.777 +        
  25.778 +        if (xppdd->common.current_pnp_state == Started)
  25.779 +        {
  25.780 +          KdPrint((__DRIVER_NME "     Sending RequestDeviceEject\n"));
  25.781 +          WdfPdoRequestEject(device);
  25.782 +        }
  25.783 +        else
  25.784 +        {
  25.785 +          KdPrint((__DRIVER_NAME "     Not closing device because it is not started\n"));
  25.786 +        }
  25.787 +      }
  25.788 +#endif
  25.789 +    }
  25.790 +    break;
  25.791 +
  25.792 +  case XenbusStateClosed:
  25.793 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Closed (%s)\n", path));  
  25.794 +    break;
  25.795 +
  25.796 +  default:
  25.797 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Undefined = %d (%s)\n", xppdd->backend_state, path));
  25.798 +    break;
  25.799 +  }
  25.800 +
  25.801 +  KeSetEvent(&xppdd->backend_state_event, 1, FALSE);
  25.802 +
  25.803 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  25.804 +
  25.805 +  return;
  25.806 +}
  25.807 +
  25.808 +static NTSTATUS
  25.809 +XenPci_GetBackendAndAddWatch(WDFDEVICE device)
  25.810 +{
  25.811 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  25.812 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  25.813 +  char path[128];
  25.814 +  PCHAR res;
  25.815 +  PCHAR value;
  25.816 +
  25.817 +  /* Get backend path */
  25.818 +  RtlStringCbPrintfA(path, ARRAY_SIZE(path),
  25.819 +    "%s/backend", xppdd->path);
  25.820 +  res = XenBus_Read(xpdd, XBT_NIL, path, &value);
  25.821 +  if (res)
  25.822 +  {
  25.823 +    KdPrint((__DRIVER_NAME "    Failed to read backend path\n"));
  25.824 +    XenPci_FreeMem(res);
  25.825 +    return STATUS_UNSUCCESSFUL;
  25.826 +  }
  25.827 +  RtlStringCbCopyA(xppdd->backend_path, ARRAY_SIZE(xppdd->backend_path), value);
  25.828 +  XenPci_FreeMem(value);
  25.829 +
  25.830 +  /* Add watch on backend state */
  25.831 +  RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
  25.832 +  XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, device);
  25.833 +  
  25.834 +  return STATUS_SUCCESS;
  25.835 +}
  25.836 +
  25.837 +static PMDL
  25.838 +XenConfig_MakeConfigPage(WDFDEVICE device)
  25.839 +{
  25.840 +  //PXENCONFIG_DEVICE_DATA xcdd = (PXENCONFIG_DEVICE_DATA)device_object->DeviceExtension;
  25.841 +  //PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
  25.842 +  //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
  25.843 +  PMDL mdl;
  25.844 +  PUCHAR ptr;
  25.845 +  PDEVICE_OBJECT curr, prev;
  25.846 +  PDRIVER_OBJECT fdo_driver_object;
  25.847 +  PUCHAR fdo_driver_extension;
  25.848 +  
  25.849 +  FUNCTION_ENTER();
  25.850 +  
  25.851 +  mdl = AllocateUncachedPage();
  25.852 +  ptr = MmGetMdlVirtualAddress(mdl);
  25.853 +  curr = IoGetAttachedDeviceReference(WdfDeviceWdmGetDeviceObject(device));
  25.854 +  //curr = WdfDeviceWdmGetAttachedDevice(device);
  25.855 +  while (curr != NULL)
  25.856 +  {
  25.857 +    fdo_driver_object = curr->DriverObject;
  25.858 +    KdPrint((__DRIVER_NAME "     fdo_driver_object = %p\n", fdo_driver_object));
  25.859 +    if (fdo_driver_object)
  25.860 +    {
  25.861 +      fdo_driver_extension = IoGetDriverObjectExtension(fdo_driver_object, UlongToPtr(XEN_INIT_DRIVER_EXTENSION_MAGIC));
  25.862 +      KdPrint((__DRIVER_NAME "     fdo_driver_extension = %p\n", fdo_driver_extension));
  25.863 +      if (fdo_driver_extension)
  25.864 +      {
  25.865 +        memcpy(ptr, fdo_driver_extension, PAGE_SIZE);
  25.866 +        ObDereferenceObject(curr);
  25.867 +        break;
  25.868 +      }
  25.869 +    }
  25.870 +    prev = curr;
  25.871 +    curr = IoGetLowerDeviceObject(curr);
  25.872 +    ObDereferenceObject(prev);
  25.873 +  }
  25.874 +  
  25.875 +  FUNCTION_EXIT();
  25.876 +  
  25.877 +  return mdl;
  25.878 +}
  25.879 +
  25.880 +static NTSTATUS
  25.881 +XenPci_EvtChn_Bind(PVOID context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
  25.882 +{
  25.883 +  WDFDEVICE device = context;
  25.884 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  25.885 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  25.886 +  
  25.887 +  return EvtChn_Bind(xpdd, Port, ServiceRoutine, ServiceContext);
  25.888 +}
  25.889 +
  25.890 +static NTSTATUS
  25.891 +XenPci_EvtChn_BindDpc(PVOID context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
  25.892 +{
  25.893 +  WDFDEVICE device = context;
  25.894 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  25.895 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  25.896 +  
  25.897 +  return EvtChn_BindDpc(xpdd, Port, ServiceRoutine, ServiceContext);
  25.898 +}
  25.899 +
  25.900 +static NTSTATUS
  25.901 +XenPci_EvtChn_Unbind(PVOID context, evtchn_port_t Port)
  25.902 +{
  25.903 +  WDFDEVICE device = context;
  25.904 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  25.905 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  25.906 +  
  25.907 +  return EvtChn_Unbind(xpdd, Port);
  25.908 +}
  25.909 +
  25.910 +static NTSTATUS
  25.911 +XenPci_EvtChn_Mask(PVOID context, evtchn_port_t Port)
  25.912 +{
  25.913 +  WDFDEVICE device = context;
  25.914 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  25.915 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  25.916 +  
  25.917 +  return EvtChn_Mask(xpdd, Port);
  25.918 +}
  25.919 +
  25.920 +static NTSTATUS
  25.921 +XenPci_EvtChn_Unmask(PVOID context, evtchn_port_t Port)
  25.922 +{
  25.923 +  WDFDEVICE device = context;
  25.924 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  25.925 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  25.926 +  
  25.927 +  return EvtChn_Unmask(xpdd, Port);
  25.928 +}
  25.929 +
  25.930 +static NTSTATUS
  25.931 +XenPci_EvtChn_Notify(PVOID context, evtchn_port_t Port)
  25.932 +{
  25.933 +  WDFDEVICE device = context;
  25.934 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  25.935 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  25.936 +  
  25.937 +  return EvtChn_Notify(xpdd, Port);
  25.938 +}
  25.939 +
  25.940 +static BOOLEAN
  25.941 +XenPci_EvtChn_AckEvent(PVOID context, evtchn_port_t port)
  25.942 +{
  25.943 +  WDFDEVICE device = context;
  25.944 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  25.945 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  25.946 +  
  25.947 +  return EvtChn_AckEvent(xpdd, port);
  25.948 +}
  25.949 +
  25.950 +typedef struct {
  25.951 +  PXEN_EVTCHN_SYNC_ROUTINE sync_routine;
  25.952 +  PVOID sync_context;
  25.953 +} sync_context_t;
  25.954 +
  25.955 +static BOOLEAN
  25.956 +XenPci_EvtChn_Sync_Routine(WDFINTERRUPT interrupt, WDFCONTEXT context)
  25.957 +{
  25.958 +  sync_context_t *wdf_sync_context = context;
  25.959 +  UNREFERENCED_PARAMETER(interrupt);
  25.960 +  return wdf_sync_context->sync_routine(wdf_sync_context->sync_context);
  25.961 +}
  25.962 +
  25.963 +static BOOLEAN
  25.964 +XenPci_EvtChn_Sync(PVOID context, PXEN_EVTCHN_SYNC_ROUTINE sync_routine, PVOID sync_context)
  25.965 +{
  25.966 +  WDFDEVICE device = context;
  25.967 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  25.968 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  25.969 +  sync_context_t wdf_sync_context;
  25.970 +  
  25.971 +  wdf_sync_context.sync_routine = sync_routine;
  25.972 +  wdf_sync_context.sync_context = sync_context;
  25.973 +  
  25.974 +  return WdfInterruptSynchronize(xpdd->interrupt, XenPci_EvtChn_Sync_Routine, &wdf_sync_context);
  25.975 +}
  25.976 +
  25.977 +static grant_ref_t
  25.978 +XenPci_GntTbl_GrantAccess(PVOID context, domid_t domid, uint32_t frame, int readonly, grant_ref_t ref)
  25.979 +{
  25.980 +  WDFDEVICE device = context;
  25.981 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  25.982 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  25.983 +  
  25.984 +  return GntTbl_GrantAccess(xpdd, domid, frame, readonly, ref);
  25.985 +}
  25.986 +
  25.987 +static BOOLEAN
  25.988 +XenPci_GntTbl_EndAccess(PVOID context, grant_ref_t ref, BOOLEAN keepref)
  25.989 +{
  25.990 +  WDFDEVICE device = context;
  25.991 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  25.992 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  25.993 +  
  25.994 +  return GntTbl_EndAccess(xpdd, ref, keepref);
  25.995 +}
  25.996 +
  25.997 +static VOID
  25.998 +XenPci_GntTbl_PutRef(PVOID context, grant_ref_t ref)
  25.999 +{
 25.1000 +  WDFDEVICE device = context;
 25.1001 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1002 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1003 +  
 25.1004 +  GntTbl_PutRef(xpdd, ref);
 25.1005 +}
 25.1006 +
 25.1007 +static grant_ref_t
 25.1008 +XenPci_GntTbl_GetRef(PVOID context)
 25.1009 +{
 25.1010 +  WDFDEVICE device = context;
 25.1011 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1012 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1013 +  
 25.1014 +  return GntTbl_GetRef(xpdd);
 25.1015 +}
 25.1016 +
 25.1017 +PCHAR
 25.1018 +XenPci_XenBus_Read(PVOID context, xenbus_transaction_t xbt, char *path, char **value)
 25.1019 +{
 25.1020 +  WDFDEVICE device = context;
 25.1021 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1022 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1023 +  return XenBus_Read(xpdd, xbt, path, value);
 25.1024 +}
 25.1025 +
 25.1026 +PCHAR
 25.1027 +XenPci_XenBus_Write(PVOID context, xenbus_transaction_t xbt, char *path, char *value)
 25.1028 +{
 25.1029 +  WDFDEVICE device = context;
 25.1030 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1031 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1032 +  return XenBus_Write(xpdd, xbt, path, value);
 25.1033 +}
 25.1034 +
 25.1035 +PCHAR
 25.1036 +XenPci_XenBus_Printf(PVOID context, xenbus_transaction_t xbt, char *path, char *fmt, ...)
 25.1037 +{
 25.1038 +  //PXENPCI_PDO_DEVICE_DATA xppdd = Context;
 25.1039 +  //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
 25.1040 +  //return XenBus_Printf(xpdd, xbt, path, value);
 25.1041 +  UNREFERENCED_PARAMETER(context);
 25.1042 +  UNREFERENCED_PARAMETER(xbt);
 25.1043 +  UNREFERENCED_PARAMETER(path);
 25.1044 +  UNREFERENCED_PARAMETER(fmt);
 25.1045 +  return NULL;
 25.1046 +}
 25.1047 +
 25.1048 +PCHAR
 25.1049 +XenPci_XenBus_StartTransaction(PVOID context, xenbus_transaction_t *xbt)
 25.1050 +{
 25.1051 +  WDFDEVICE device = context;
 25.1052 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1053 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1054 +  return XenBus_StartTransaction(xpdd, xbt);
 25.1055 +}
 25.1056 +
 25.1057 +PCHAR
 25.1058 +XenPci_XenBus_EndTransaction(PVOID context, xenbus_transaction_t xbt, int abort, int *retry)
 25.1059 +{
 25.1060 +  WDFDEVICE device = context;
 25.1061 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1062 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1063 +  return XenBus_EndTransaction(xpdd, xbt, abort, retry);
 25.1064 +}
 25.1065 +
 25.1066 +PCHAR
 25.1067 +XenPci_XenBus_List(PVOID context, xenbus_transaction_t xbt, char *prefix, char ***contents)
 25.1068 +{
 25.1069 +  WDFDEVICE device = context;
 25.1070 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1071 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1072 +  return XenBus_List(xpdd, xbt, prefix, contents);
 25.1073 +}
 25.1074 +
 25.1075 +PCHAR
 25.1076 +XenPci_XenBus_AddWatch(PVOID context, xenbus_transaction_t xbt, char *path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext)
 25.1077 +{
 25.1078 +  WDFDEVICE device = context;
 25.1079 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1080 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1081 +  PCHAR retval;
 25.1082 +  
 25.1083 +  FUNCTION_ENTER();
 25.1084 +  retval = XenBus_AddWatch(xpdd, xbt, path, ServiceRoutine, ServiceContext);
 25.1085 +  if (retval == NULL)
 25.1086 +  {
 25.1087 +    KdPrint((__DRIVER_NAME "     XenPci_XenBus_AddWatch - %s = NULL\n", path));
 25.1088 +  }
 25.1089 +  else
 25.1090 +  {
 25.1091 +    KdPrint((__DRIVER_NAME "     XenPci_XenBus_AddWatch - %s = %s\n", path, retval));
 25.1092 +  }
 25.1093 +  FUNCTION_EXIT();
 25.1094 +  return retval;
 25.1095 +}
 25.1096 +
 25.1097 +PCHAR
 25.1098 +XenPci_XenBus_RemWatch(PVOID context, xenbus_transaction_t xbt, char *path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext)
 25.1099 +{
 25.1100 +  WDFDEVICE device = context;
 25.1101 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1102 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1103 +  return XenBus_RemWatch(xpdd, xbt, path, ServiceRoutine, ServiceContext);
 25.1104 +}
 25.1105 +
 25.1106 +/*
 25.1107 +Called at PASSIVE_LEVEL
 25.1108 +Called during restore
 25.1109 +*/
 25.1110 +
 25.1111 +static NTSTATUS
 25.1112 +XenPci_ChangeFrontendState(WDFDEVICE device, ULONG frontend_state_set, ULONG backend_state_response, ULONG maximum_wait_ms)
 25.1113 +{
 25.1114 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1115 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1116 +  LARGE_INTEGER timeout;
 25.1117 +  ULONG remaining;
 25.1118 +  ULONG thiswait;
 25.1119 +  char path[128];
 25.1120 +  
 25.1121 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
 25.1122 +
 25.1123 +  RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
 25.1124 +  XenBus_Printf(xpdd, XBT_NIL, path, "%d", frontend_state_set);
 25.1125 +
 25.1126 +  remaining = maximum_wait_ms;
 25.1127 +
 25.1128 +  while (xppdd->backend_state != backend_state_response)
 25.1129 +  {
 25.1130 +    thiswait = min((LONG)remaining, 1000); // 1 second or remaining time, whichever is less
 25.1131 +    timeout.QuadPart = (LONGLONG)-1 * thiswait * 1000 * 10;
 25.1132 +    if (KeWaitForSingleObject(&xppdd->backend_state_event, Executive, KernelMode, FALSE, &timeout) == STATUS_TIMEOUT)
 25.1133 +    {
 25.1134 +      remaining -= thiswait;
 25.1135 +      if (remaining == 0)
 25.1136 +      {
 25.1137 +        KdPrint((__DRIVER_NAME "     Timed out waiting for %d!\n", backend_state_response));
 25.1138 +        return STATUS_UNSUCCESSFUL;
 25.1139 +      }
 25.1140 +      KdPrint((__DRIVER_NAME "     Still waiting for %d (currently %d)...\n", backend_state_response, xppdd->backend_state));
 25.1141 +    }
 25.1142 +  }
 25.1143 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
 25.1144 +  return STATUS_SUCCESS;
 25.1145 +}
 25.1146 +
 25.1147 +static NTSTATUS
 25.1148 +XenPci_XenConfigDevice(WDFDEVICE device);
 25.1149 +
 25.1150 +static NTSTATUS
 25.1151 +XenPci_XenShutdownDevice(PVOID context)
 25.1152 +{
 25.1153 +  WDFDEVICE device = context;
 25.1154 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1155 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1156 +  PUCHAR in_ptr;
 25.1157 +  ULONG i;
 25.1158 +  UCHAR type;
 25.1159 +  PVOID setting;
 25.1160 +  PVOID value;
 25.1161 +  PVOID value2;
 25.1162 +
 25.1163 +  FUNCTION_ENTER();
 25.1164 +
 25.1165 +  if (xppdd->backend_state == XenbusStateConnected)
 25.1166 +  {
 25.1167 +    XenPci_ChangeFrontendState(device, XenbusStateClosing, XenbusStateClosing, 30000);
 25.1168 +    if (xppdd->backend_state == XenbusStateClosing)
 25.1169 +      XenPci_ChangeFrontendState(device, XenbusStateClosed, XenbusStateClosed, 30000);
 25.1170 +    if (xppdd->backend_state == XenbusStateClosed)
 25.1171 +      XenPci_ChangeFrontendState(device, XenbusStateInitialising, XenbusStateInitWait, 30000);
 25.1172 +  }
 25.1173 +  else
 25.1174 +  {
 25.1175 +    if (xppdd->backend_state == XenbusStateClosing)
 25.1176 +      XenPci_ChangeFrontendState(device, XenbusStateClosed, XenbusStateClosed, 30000);
 25.1177 +  }
 25.1178 +
 25.1179 +  if (xppdd->assigned_resources_start != NULL)
 25.1180 +  {
 25.1181 +    ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
 25.1182 +    in_ptr = xppdd->assigned_resources_start;
 25.1183 +    while((type = GET_XEN_INIT_RSP(&in_ptr, &setting, &value, &value2)) != XEN_INIT_TYPE_END)
 25.1184 +    {
 25.1185 +      switch (type)
 25.1186 +      {
 25.1187 +      case XEN_INIT_TYPE_RING: /* frontend ring */
 25.1188 +        FreePages(value);
 25.1189 +        break;
 25.1190 +      case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
 25.1191 +      case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
 25.1192 +        EvtChn_Unbind(xpdd, PtrToUlong(value));
 25.1193 +        EvtChn_Close(xpdd, PtrToUlong(value));
 25.1194 +        break;
 25.1195 +      case XEN_INIT_TYPE_GRANT_ENTRIES:
 25.1196 +        for (i = 0; i < PtrToUlong(setting); i++)
 25.1197 +          GntTbl_EndAccess(xpdd, ((grant_ref_t *)value)[i], FALSE);
 25.1198 +        break;
 25.1199 +      }
 25.1200 +    }
 25.1201 +    ExFreePoolWithTag(xppdd->assigned_resources_start, XENPCI_POOL_TAG);
 25.1202 +    xppdd->assigned_resources_start = NULL;
 25.1203 +  }
 25.1204 +
 25.1205 +  FUNCTION_EXIT();
 25.1206 +
 25.1207 +  return STATUS_SUCCESS;
 25.1208 +}
 25.1209 +
 25.1210 +struct dummy_sring {
 25.1211 +    RING_IDX req_prod, req_event;
 25.1212 +    RING_IDX rsp_prod, rsp_event;
 25.1213 +    uint8_t  pad[48];
 25.1214 +};
 25.1215 +
 25.1216 +static NTSTATUS
 25.1217 +XenPci_XenConfigDeviceSpecifyBuffers(WDFDEVICE device, PUCHAR src, PUCHAR dst)
 25.1218 +{
 25.1219 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1220 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1221 +  NTSTATUS status = STATUS_SUCCESS;
 25.1222 +  ULONG i;
 25.1223 +  char path[128];
 25.1224 +  PCHAR setting, value;
 25.1225 +  PCHAR res;
 25.1226 +  PVOID address;
 25.1227 +  UCHAR type;
 25.1228 +  PUCHAR in_ptr; //, in_start;
 25.1229 +  PUCHAR out_ptr; //, out_start;
 25.1230 +  XENPCI_VECTORS vectors;
 25.1231 +  ULONG event_channel;
 25.1232 +  ULONG run_type = 0;
 25.1233 +  PMDL ring;
 25.1234 +  grant_ref_t gref;
 25.1235 +  BOOLEAN done_xenbus_init = FALSE;
 25.1236 +  PVOID value2;
 25.1237 + 
 25.1238 +  FUNCTION_ENTER();
 25.1239 +
 25.1240 +  in_ptr = src;
 25.1241 +  out_ptr = dst;
 25.1242 +  
 25.1243 +  // always add vectors
 25.1244 +  vectors.magic = XEN_DATA_MAGIC;
 25.1245 +  vectors.length = sizeof(XENPCI_VECTORS);
 25.1246 +  vectors.context = device;
 25.1247 +  vectors.EvtChn_Bind = XenPci_EvtChn_Bind;
 25.1248 +  vectors.EvtChn_BindDpc = XenPci_EvtChn_BindDpc;
 25.1249 +  vectors.EvtChn_Unbind = XenPci_EvtChn_Unbind;
 25.1250 +  vectors.EvtChn_Mask = XenPci_EvtChn_Mask;
 25.1251 +  vectors.EvtChn_Unmask = XenPci_EvtChn_Unmask;
 25.1252 +  vectors.EvtChn_Notify = XenPci_EvtChn_Notify;
 25.1253 +  vectors.EvtChn_AckEvent = XenPci_EvtChn_AckEvent;
 25.1254 +  vectors.EvtChn_Sync = XenPci_EvtChn_Sync;
 25.1255 +  vectors.GntTbl_GetRef = XenPci_GntTbl_GetRef;
 25.1256 +  vectors.GntTbl_PutRef = XenPci_GntTbl_PutRef;
 25.1257 +  vectors.GntTbl_GrantAccess = XenPci_GntTbl_GrantAccess;
 25.1258 +  vectors.GntTbl_EndAccess = XenPci_GntTbl_EndAccess;
 25.1259 +  vectors.XenPci_XenConfigDevice = XenPci_XenConfigDevice;
 25.1260 +  vectors.XenPci_XenShutdownDevice = XenPci_XenShutdownDevice;
 25.1261 +  strncpy(vectors.path, xppdd->path, 128);
 25.1262 +  strncpy(vectors.backend_path, xppdd->backend_path, 128);
 25.1263 +  //vectors.pdo_event_channel = xpdd->pdo_event_channel;
 25.1264 +  vectors.XenBus_Read = XenPci_XenBus_Read;
 25.1265 +  vectors.XenBus_Write = XenPci_XenBus_Write;
 25.1266 +  vectors.XenBus_Printf = XenPci_XenBus_Printf;
 25.1267 +  vectors.XenBus_StartTransaction = XenPci_XenBus_StartTransaction;
 25.1268 +  vectors.XenBus_EndTransaction = XenPci_XenBus_EndTransaction;
 25.1269 +  vectors.XenBus_List = XenPci_XenBus_List;
 25.1270 +  vectors.XenBus_AddWatch = XenPci_XenBus_AddWatch;
 25.1271 +  vectors.XenBus_RemWatch = XenPci_XenBus_RemWatch;
 25.1272 +
 25.1273 +  if (qemu_filtered)
 25.1274 +    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_ACTIVE, NULL, NULL, NULL);
 25.1275 +
 25.1276 +  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION, NULL, UlongToPtr(qemu_protocol_version), NULL);
 25.1277 +  
 25.1278 +  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_VECTORS, NULL, &vectors, NULL);
 25.1279 +  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_STATE_PTR, NULL, &xppdd->device_state, NULL);
 25.1280 +
 25.1281 +  // first pass, possibly before state == Connected
 25.1282 +  while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
 25.1283 +  {
 25.1284 +  
 25.1285 +    if (!done_xenbus_init)
 25.1286 +    {
 25.1287 +      if (XenPci_ChangeFrontendState(device, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
 25.1288 +      {
 25.1289 +        status = STATUS_UNSUCCESSFUL;
 25.1290 +        goto error;
 25.1291 +      }
 25.1292 +      done_xenbus_init = TRUE;
 25.1293 +    }
 25.1294 +    
 25.1295 +    ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, type, setting, value, value2);
 25.1296 +
 25.1297 +    switch (type)
 25.1298 +    {
 25.1299 +    case XEN_INIT_TYPE_RUN:
 25.1300 +      run_type++;
 25.1301 +      break;
 25.1302 +    case XEN_INIT_TYPE_WRITE_STRING: /* frontend setting = value */
 25.1303 +      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_WRITE_STRING - %s = %s\n", setting, value));
 25.1304 +      RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
 25.1305 +      XenBus_Printf(xpdd, XBT_NIL, path, "%s", value);
 25.1306 +      break;
 25.1307 +    case XEN_INIT_TYPE_RING: /* frontend ring */
 25.1308 +      /* we only allocate and do the SHARED_RING_INIT here */
 25.1309 +      if ((ring = AllocatePage()) != 0)
 25.1310 +      {
 25.1311 +        address = MmGetMdlVirtualAddress(ring);
 25.1312 +        //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, address));
 25.1313 +        SHARED_RING_INIT((struct dummy_sring *)address);
 25.1314 +        if ((gref = GntTbl_GrantAccess(
 25.1315 +          xpdd, 0, (ULONG)*MmGetMdlPfnArray(ring), FALSE, INVALID_GRANT_REF)) != INVALID_GRANT_REF)
 25.1316 +        {
 25.1317 +          RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
 25.1318 +          XenBus_Printf(xpdd, XBT_NIL, path, "%d", gref);
 25.1319 +          ADD_XEN_INIT_RSP(&out_ptr, type, setting, address, NULL);
 25.1320 +          ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, ring, NULL);
 25.1321 +          // add the grant entry too so it gets freed automatically
 25.1322 +          __ADD_XEN_INIT_UCHAR(&xppdd->assigned_resources_ptr, XEN_INIT_TYPE_GRANT_ENTRIES);
 25.1323 +          __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, 1);
 25.1324 +          __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, gref);
 25.1325 +        }
 25.1326 +        else
 25.1327 +        {
 25.1328 +          FreePages(ring);
 25.1329 +          status = STATUS_UNSUCCESSFUL;
 25.1330 +          goto error;
 25.1331 +        }
 25.1332 +      }
 25.1333 +      else
 25.1334 +      {
 25.1335 +        status = STATUS_UNSUCCESSFUL;
 25.1336 +        goto error;
 25.1337 +      }
 25.1338 +      break;
 25.1339 +    case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
 25.1340 +    case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
 25.1341 +      if ((event_channel = EvtChn_AllocUnbound(xpdd, 0)) != 0)
 25.1342 +      {
 25.1343 +        //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, event_channel));
 25.1344 +        RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
 25.1345 +        XenBus_Printf(xpdd, XBT_NIL, path, "%d", event_channel);
 25.1346 +        ADD_XEN_INIT_RSP(&out_ptr, type, setting, UlongToPtr(event_channel), NULL);
 25.1347 +        ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, UlongToPtr(event_channel), NULL);
 25.1348 +        if (type == XEN_INIT_TYPE_EVENT_CHANNEL_IRQ)
 25.1349 +        {
 25.1350 +          EvtChn_BindIrq(xpdd, event_channel, xppdd->irq_vector, path);
 25.1351 +        }
 25.1352 +        else
 25.1353 +        {
 25.1354 +          EvtChn_Bind(xpdd, event_channel, (PXEN_EVTCHN_SERVICE_ROUTINE)value, value2);
 25.1355 +        }
 25.1356 +      }
 25.1357 +      else
 25.1358 +      {
 25.1359 +        status = STATUS_UNSUCCESSFUL;
 25.1360 +        goto error;
 25.1361 +      }
 25.1362 +      break;
 25.1363 +    }
 25.1364 +  }
 25.1365 +  if (!NT_SUCCESS(status))
 25.1366 +  {
 25.1367 +    goto error;
 25.1368 +  }
 25.1369 +  // If XEN_INIT_TYPE_RUN was specified more than once then we skip XenbusStateInitialised here and go straight to XenbusStateConnected at the end
 25.1370 +  if (run_type == 1)
 25.1371 +  {
 25.1372 +    if (XenPci_ChangeFrontendState(device, XenbusStateInitialised, XenbusStateConnected, 30000) != STATUS_SUCCESS)
 25.1373 +    {
 25.1374 +      status = STATUS_UNSUCCESSFUL;
 25.1375 +      goto error;
 25.1376 +    }
 25.1377 +  }
 25.1378 +
 25.1379 +  // second pass, possibly after state == Connected
 25.1380 +  in_ptr = src;
 25.1381 +  while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
 25.1382 +  {
 25.1383 +    switch(type)
 25.1384 +    {
 25.1385 +    case XEN_INIT_TYPE_READ_STRING_BACK:
 25.1386 +    case XEN_INIT_TYPE_READ_STRING_FRONT:
 25.1387 +      if (type == XEN_INIT_TYPE_READ_STRING_FRONT)
 25.1388 +        RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
 25.1389 +      else
 25.1390 +        RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->backend_path, setting);
 25.1391 +      res = XenBus_Read(xpdd, XBT_NIL, path, &value);
 25.1392 +      if (res)
 25.1393 +      {
 25.1394 +        //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = <failed>\n", setting));
 25.1395 +        XenPci_FreeMem(res);
 25.1396 +        ADD_XEN_INIT_RSP(&out_ptr, type, setting, NULL, NULL);
 25.1397 +      }
 25.1398 +      else
 25.1399 +      {
 25.1400 +        //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
 25.1401 +        ADD_XEN_INIT_RSP(&out_ptr, type, setting, value, value2);
 25.1402 +        XenPci_FreeMem(value);
 25.1403 +      }
 25.1404 +      break;
 25.1405 +    case XEN_INIT_TYPE_VECTORS:
 25.1406 +      // this is always done so ignore the request
 25.1407 +      break;
 25.1408 +    case XEN_INIT_TYPE_GRANT_ENTRIES:
 25.1409 +      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(value)));
 25.1410 +      __ADD_XEN_INIT_UCHAR(&out_ptr, type);
 25.1411 +      __ADD_XEN_INIT_UCHAR(&xppdd->assigned_resources_ptr, type);
 25.1412 +      __ADD_XEN_INIT_ULONG(&out_ptr, PtrToUlong(value));
 25.1413 +      __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, PtrToUlong(value));
 25.1414 +      for (i = 0; i < PtrToUlong(value); i++)
 25.1415 +      {
 25.1416 +        gref = GntTbl_GetRef(xpdd);
 25.1417 +        __ADD_XEN_INIT_ULONG(&out_ptr, gref);
 25.1418 +        __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, gref);
 25.1419 +      }
 25.1420 +      break;
 25.1421 +    }
 25.1422 +  }
 25.1423 +  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
 25.1424 +
 25.1425 +  if (run_type)
 25.1426 +  {
 25.1427 +    if (XenPci_ChangeFrontendState(device, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
 25.1428 +    {
 25.1429 +      status = STATUS_UNSUCCESSFUL;
 25.1430 +      goto error;
 25.1431 +    }
 25.1432 +  }
 25.1433 +  FUNCTION_EXIT();
 25.1434 +  return status;
 25.1435 +  
 25.1436 +error:
 25.1437 +  XenPci_ChangeFrontendState(device, XenbusStateInitialising, XenbusStateInitWait, 30000);
 25.1438 +  FUNCTION_EXIT_STATUS(status);
 25.1439 +
 25.1440 +  return status;
 25.1441 +}
 25.1442 +
 25.1443 +static NTSTATUS
 25.1444 +XenPci_XenConfigDevice(WDFDEVICE device)
 25.1445 +{
 25.1446 +  NTSTATUS status;
 25.1447 +  PUCHAR src, dst;
 25.1448 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1449 +
 25.1450 +  src = ExAllocatePoolWithTag(NonPagedPool, xppdd->config_page_length, XENPCI_POOL_TAG);
 25.1451 +  dst = MmMapIoSpace(xppdd->config_page_phys, xppdd->config_page_length, MmNonCached);
 25.1452 +  memcpy(src, dst, xppdd->config_page_length);
 25.1453 +  
 25.1454 +  status = XenPci_XenConfigDeviceSpecifyBuffers(device, src, dst);
 25.1455 +
 25.1456 +  MmUnmapIoSpace(dst, xppdd->config_page_length);
 25.1457 +  ExFreePoolWithTag(src, XENPCI_POOL_TAG);
 25.1458 +  
 25.1459 +  return status;
 25.1460 +}
 25.1461 +
 25.1462 +static NTSTATUS
 25.1463 +XenPciPdo_EvtDeviceWdmIrpPreprocess_START_DEVICE(WDFDEVICE device, PIRP irp)
 25.1464 +{
 25.1465 +  NTSTATUS status = STATUS_SUCCESS;
 25.1466 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1467 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1468 +  PIO_STACK_LOCATION stack;
 25.1469 +  PCM_PARTIAL_RESOURCE_LIST prl;
 25.1470 +  PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
 25.1471 +  ULONG i;
 25.1472 +  char path[128];
 25.1473 +  PMDL mdl;
 25.1474 + 
 25.1475 +  FUNCTION_ENTER();
 25.1476 +  KdPrint((__DRIVER_NAME "     %s\n", xppdd->path));
 25.1477 +
 25.1478 +  stack = IoGetCurrentIrpStackLocation(irp);
 25.1479 +
 25.1480 +  status = XenPci_GetBackendAndAddWatch(device);
 25.1481 +  if (!NT_SUCCESS(status)) {
 25.1482 +    FUNCTION_ERROR_EXIT();
 25.1483 +    return status;
 25.1484 +  }
 25.1485 +
 25.1486 +  mdl = XenConfig_MakeConfigPage(device);
 25.1487 +  
 25.1488 +  prl = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
 25.1489 +  for (i = 0; i < prl->Count; i++)
 25.1490 +  {
 25.1491 +    prd = & prl->PartialDescriptors[i];
 25.1492 +    switch (prd->Type)
 25.1493 +    {
 25.1494 +    case CmResourceTypeMemory:
 25.1495 +      if (prd->u.Memory.Start.QuadPart == xpdd->platform_mmio_addr.QuadPart && prd->u.Memory.Length == 0)
 25.1496 +      {
 25.1497 +        prd->u.Memory.Start.QuadPart = MmGetMdlPfnArray(mdl)[0] << PAGE_SHIFT;
 25.1498 +        prd->u.Memory.Length = MmGetMdlByteCount(mdl);
 25.1499 +      }
 25.1500 +      else if (prd->u.Memory.Start.QuadPart == xpdd->platform_mmio_addr.QuadPart + 1 && prd->u.Memory.Length == 0)
 25.1501 +      {
 25.1502 +        RtlZeroMemory(prd, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
 25.1503 +        prd->Type = CmResourceTypeInterrupt;
 25.1504 +        prd->ShareDisposition = CmResourceShareShared;
 25.1505 +        prd->Flags = (xpdd->irq_mode == Latched)?CM_RESOURCE_INTERRUPT_LATCHED:CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
 25.1506 +        prd->u.Interrupt.Level = xpdd->irq_number;
 25.1507 +        prd->u.Interrupt.Vector = xpdd->irq_number;
 25.1508 +        prd->u.Interrupt.Affinity = (KAFFINITY)-1;
 25.1509 +        xppdd->irq_number = xpdd->irq_number;
 25.1510 +      }
 25.1511 +      break;
 25.1512 +    }
 25.1513 +  }
 25.1514 +
 25.1515 +  prl = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
 25.1516 +  for (i = 0; i < prl->Count; i++)
 25.1517 +  {
 25.1518 +    prd = & prl->PartialDescriptors[i];
 25.1519 +    switch (prd->Type)
 25.1520 +    {
 25.1521 +    case CmResourceTypeMemory:
 25.1522 +      KdPrint((__DRIVER_NAME "     CmResourceTypeMemory (%d)\n", i));
 25.1523 +      KdPrint((__DRIVER_NAME "     Start = %08x, Length = %d\n", prd->u.Memory.Start.LowPart, prd->u.Memory.Length));
 25.1524 +      if (prd->u.Memory.Start.QuadPart == xpdd->platform_mmio_addr.QuadPart)
 25.1525 +      {
 25.1526 +        if (prd->u.Memory.Length == 0)
 25.1527 +        {
 25.1528 +          KdPrint((__DRIVER_NAME "     pfn[0] = %08x\n", (ULONG)MmGetMdlPfnArray(mdl)[0]));
 25.1529 +          prd->u.Memory.Start.QuadPart = (ULONGLONG)MmGetMdlPfnArray(mdl)[0] << PAGE_SHIFT;
 25.1530 +          prd->u.Memory.Length = MmGetMdlByteCount(mdl);
 25.1531 +          KdPrint((__DRIVER_NAME "     New Start = %08x%08x, Length = %d\n", prd->u.Memory.Start.HighPart, prd->u.Memory.Start.LowPart, prd->u.Memory.Length));
 25.1532 +        }
 25.1533 +        xppdd->config_page_phys = prd->u.Memory.Start;
 25.1534 +        xppdd->config_page_length = prd->u.Memory.Length;
 25.1535 +        xppdd->requested_resources_start = xppdd->requested_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
 25.1536 +        xppdd->assigned_resources_start = xppdd->assigned_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
 25.1537 +        
 25.1538 +        status = XenPci_XenConfigDevice(device);
 25.1539 +        if (!NT_SUCCESS(status))
 25.1540 +        {
 25.1541 +          RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
 25.1542 +          XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
 25.1543 +          FUNCTION_ERROR_EXIT();
 25.1544 +          return status;
 25.1545 +        }
 25.1546 +      }
 25.1547 +      else if (prd->u.Memory.Start.QuadPart == xpdd->platform_mmio_addr.QuadPart + 1 && prd->u.Memory.Length == 0)
 25.1548 +      {
 25.1549 +        RtlZeroMemory(prd, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
 25.1550 +        prd->Type = CmResourceTypeInterrupt;
 25.1551 +        prd->ShareDisposition = CmResourceShareShared;
 25.1552 +        prd->Flags = (xpdd->irq_mode == Latched)?CM_RESOURCE_INTERRUPT_LATCHED:CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
 25.1553 +        prd->u.Interrupt.Level = xpdd->irq_level;
 25.1554 +        prd->u.Interrupt.Vector = xpdd->irq_vector;
 25.1555 +        prd->u.Interrupt.Affinity = (KAFFINITY)-1;
 25.1556 +        xppdd->irq_vector = xpdd->irq_vector;
 25.1557 +        xppdd->irq_level = xpdd->irq_level;
 25.1558 +      }
 25.1559 +      break;
 25.1560 +    }
 25.1561 +  }
 25.1562 +
 25.1563 +  IoSkipCurrentIrpStackLocation(irp);
 25.1564 +  
 25.1565 +  FUNCTION_EXIT();
 25.1566 +
 25.1567 +  return WdfDeviceWdmDispatchPreprocessedIrp(device, irp);
 25.1568 +}
 25.1569 +
 25.1570 +#if 0
 25.1571 +static NTSTATUS
 25.1572 +XenPciPdo_EvtDeviceResourcesQuery(WDFDEVICE device, WDFCMRESLIST resources)
 25.1573 +{
 25.1574 +}
 25.1575 +#endif
 25.1576 +
 25.1577 +static NTSTATUS
 25.1578 +XenPciPdo_EvtDeviceResourceRequirementsQuery(WDFDEVICE device, WDFIORESREQLIST requirements_list)
 25.1579 +{
 25.1580 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1581 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1582 +  WDFIORESLIST res_list;
 25.1583 +  IO_RESOURCE_DESCRIPTOR ird;
 25.1584 +
 25.1585 +  FUNCTION_ENTER();
 25.1586 +  
 25.1587 +  WdfIoResourceRequirementsListSetInterfaceType(requirements_list, PNPBus);
 25.1588 +  
 25.1589 +  WdfIoResourceListCreate(requirements_list, WDF_NO_OBJECT_ATTRIBUTES, &res_list);
 25.1590 +  ird.Option = 0;
 25.1591 +  ird.Type = CmResourceTypeMemory;
 25.1592 +  ird.ShareDisposition = CmResourceShareShared;
 25.1593 +  ird.Flags = CM_RESOURCE_MEMORY_READ_WRITE | CM_RESOURCE_MEMORY_CACHEABLE;
 25.1594 +  ird.u.Memory.MinimumAddress.QuadPart = xpdd->platform_mmio_addr.QuadPart;
 25.1595 +  ird.u.Memory.MaximumAddress.QuadPart = xpdd->platform_mmio_addr.QuadPart;
 25.1596 +  ird.u.Memory.Length = 0;
 25.1597 +  ird.u.Memory.Alignment = 1; //PAGE_SIZE;
 25.1598 +  WdfIoResourceListAppendDescriptor(res_list, &ird);
 25.1599 +  
 25.1600 +  ird.Option = 0;
 25.1601 +  ird.Type = CmResourceTypeMemory;
 25.1602 +  ird.ShareDisposition = CmResourceShareShared;
 25.1603 +  ird.Flags = CM_RESOURCE_MEMORY_READ_WRITE | CM_RESOURCE_MEMORY_CACHEABLE;
 25.1604 +  ird.u.Memory.MinimumAddress.QuadPart = xpdd->platform_mmio_addr.QuadPart + 1;
 25.1605 +  ird.u.Memory.MaximumAddress.QuadPart = xpdd->platform_mmio_addr.QuadPart + 1;
 25.1606 +  ird.u.Memory.Length = 0;
 25.1607 +  ird.u.Memory.Alignment = 1; //PAGE_SIZE;
 25.1608 +  WdfIoResourceListAppendDescriptor(res_list, &ird);
 25.1609 +  
 25.1610 +  WdfIoResourceRequirementsListAppendIoResList(requirements_list, res_list);
 25.1611 +
 25.1612 +  FUNCTION_EXIT();
 25.1613 +  
 25.1614 +  return STATUS_SUCCESS;
 25.1615 +}
 25.1616 +
 25.1617 +NTSTATUS
 25.1618 +XenPci_EvtChildListCreateDevice(WDFCHILDLIST child_list,
 25.1619 +  PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER identification_header,
 25.1620 +  PWDFDEVICE_INIT child_init)
 25.1621 +{
 25.1622 +  NTSTATUS status = STATUS_SUCCESS;
 25.1623 +  WDF_OBJECT_ATTRIBUTES child_attributes;
 25.1624 +  WDFDEVICE child_device;
 25.1625 +  PXENPCI_PDO_IDENTIFICATION_DESCRIPTION identification = (PXENPCI_PDO_IDENTIFICATION_DESCRIPTION)identification_header;
 25.1626 +  WDF_DEVICE_PNP_CAPABILITIES child_pnp_capabilities;
 25.1627 +  DECLARE_UNICODE_STRING_SIZE(buffer, 512);
 25.1628 +  DECLARE_CONST_UNICODE_STRING(location, L"Xen Bus");
 25.1629 +  PXENPCI_PDO_DEVICE_DATA xppdd;
 25.1630 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(WdfChildListGetDevice(child_list));
 25.1631 +  WDF_QUERY_INTERFACE_CONFIG interface_config;
 25.1632 +  BUS_INTERFACE_STANDARD bus_interface;
 25.1633 +  WDF_PDO_EVENT_CALLBACKS pdo_callbacks;
 25.1634 +  UCHAR pnp_minor_functions[] = { IRP_MN_START_DEVICE };
 25.1635 +  
 25.1636 +  FUNCTION_ENTER();
 25.1637 +
 25.1638 +  WdfDeviceInitSetDeviceType(child_init, FILE_DEVICE_UNKNOWN);
 25.1639 +  
 25.1640 +/*
 25.1641 +  WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&child_pnp_power_callbacks);
 25.1642 +  child_pnp_power_callbacks.EvtDeviceD0Entry = XenPciPdo_EvtDeviceD0Entry;
 25.1643 +  child_pnp_power_callbacks.EvtDeviceD0EntryPostInterruptsEnabled = XenPciPdo_EvtDeviceD0EntryPostInterruptsEnabled;
 25.1644 +  child_pnp_power_callbacks.EvtDeviceD0Exit = XenPciPdo_EvtDeviceD0Exit;
 25.1645 +  child_pnp_power_callbacks.EvtDeviceD0ExitPreInterruptsDisabled = XenPciPdo_EvtDeviceD0ExitPreInterruptsDisabled;
 25.1646 +  child_pnp_power_callbacks.EvtDevicePrepareHardware = XenPciPdo_EvtDevicePrepareHardware;
 25.1647 +  child_pnp_power_callbacks.EvtDeviceReleaseHardware = XenPciPdo_EvtDeviceReleaseHardware;
 25.1648 +  WdfDeviceInitSetPnpPowerEventCallbacks(child_init, &child_pnp_power_callbacks);
 25.1649 +*/
 25.1650 +  KdPrint((__DRIVER_NAME "     device = '%s', index = '%d', path = '%s'\n",
 25.1651 +    identification->device, identification->index, identification->path));
 25.1652 +  
 25.1653 +  status = WdfDeviceInitAssignWdmIrpPreprocessCallback(child_init, XenPciPdo_EvtDeviceWdmIrpPreprocess_START_DEVICE,
 25.1654 +    IRP_MJ_PNP, pnp_minor_functions, ARRAY_SIZE(pnp_minor_functions));
 25.1655 +  if (!NT_SUCCESS(status))
 25.1656 +  {
 25.1657 +    return status;
 25.1658 +  }
 25.1659 +  
 25.1660 +  WDF_PDO_EVENT_CALLBACKS_INIT(&pdo_callbacks);
 25.1661 +  //pdo_callbacks.EvtDeviceResourcesQuery = XenPciPdo_EvtDeviceResourcesQuery;
 25.1662 +  pdo_callbacks.EvtDeviceResourceRequirementsQuery = XenPciPdo_EvtDeviceResourceRequirementsQuery;
 25.1663 +  //pdo_callbacks.EvtDeviceEject = XenPciPdo_EvtDeviceEject;
 25.1664 +  //pdo_callbacks.EvtDeviceSetLock  = XenPciPdo_EvtDeviceSetLock;
 25.1665 +  WdfPdoInitSetEventCallbacks(child_init, &pdo_callbacks);
 25.1666 +
 25.1667 +  RtlUnicodeStringPrintf(&buffer, L"xen\\%S", identification->device);
 25.1668 +  status = WdfPdoInitAssignDeviceID(child_init, &buffer);
 25.1669 +  if (!NT_SUCCESS(status))
 25.1670 +  {
 25.1671 +    return status;
 25.1672 +  }
 25.1673 +  status = WdfPdoInitAddHardwareID(child_init, &buffer);
 25.1674 +  if (!NT_SUCCESS(status))
 25.1675 +  {
 25.1676 +    return status;
 25.1677 +  }
 25.1678 +  status = WdfPdoInitAddCompatibleID(child_init, &buffer);
 25.1679 +  if (!NT_SUCCESS(status))
 25.1680 +  {
 25.1681 +    return status;
 25.1682 +  }
 25.1683 +  
 25.1684 +  RtlUnicodeStringPrintf(&buffer, L"%02d", identification->index);
 25.1685 +  status = WdfPdoInitAssignInstanceID(child_init, &buffer);
 25.1686 +  if (!NT_SUCCESS(status))
 25.1687 +  {
 25.1688 +    return status;
 25.1689 +  }
 25.1690 +  
 25.1691 +  RtlUnicodeStringPrintf(&buffer, L"Xen %S device #%d", identification->device, identification->index);
 25.1692 +  status = WdfPdoInitAddDeviceText(child_init, &buffer, &location, 0x0409);
 25.1693 +  if (!NT_SUCCESS(status))
 25.1694 +  {
 25.1695 +    return status;
 25.1696 +  }
 25.1697 +  WdfPdoInitSetDefaultLocale(child_init, 0x0409);
 25.1698 +  
 25.1699 +  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&child_attributes, XENPCI_PDO_DEVICE_DATA);
 25.1700 +  status = WdfDeviceCreate(&child_init, &child_attributes, &child_device);
 25.1701 +  if (!NT_SUCCESS(status))
 25.1702 +  {
 25.1703 +    return status;
 25.1704 +  }
 25.1705 +
 25.1706 +  xppdd = GetXppdd(child_device);
 25.1707 +  
 25.1708 +  xppdd->wdf_device = child_device;
 25.1709 +  xppdd->wdf_device_bus_fdo = WdfChildListGetDevice(child_list);
 25.1710 +
 25.1711 +  xppdd->device_state.magic = XEN_DEVICE_STATE_MAGIC;
 25.1712 +  xppdd->device_state.length = sizeof(XENPCI_DEVICE_STATE);
 25.1713 +  xppdd->device_state.suspend_resume_state_pdo = SR_STATE_RUNNING;
 25.1714 +  xppdd->device_state.suspend_resume_state_fdo = SR_STATE_RUNNING;
 25.1715 +  xppdd->device_state.pdo_event_channel = xpdd->pdo_event_channel;
 25.1716 +  WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFilePaging, TRUE);
 25.1717 +  WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileHibernation, TRUE);
 25.1718 +  WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileDump, TRUE);
 25.1719 +
 25.1720 +  WDF_DEVICE_PNP_CAPABILITIES_INIT(&child_pnp_capabilities);
 25.1721 +  child_pnp_capabilities.LockSupported = WdfFalse;
 25.1722 +  child_pnp_capabilities.EjectSupported  = WdfTrue;
 25.1723 +  child_pnp_capabilities.Removable  = WdfTrue;
 25.1724 +  child_pnp_capabilities.DockDevice  = WdfFalse;
 25.1725 +  child_pnp_capabilities.UniqueID  = WdfFalse;
 25.1726 +  child_pnp_capabilities.SilentInstall  = WdfTrue;
 25.1727 +  child_pnp_capabilities.SurpriseRemovalOK  = WdfTrue;
 25.1728 +  child_pnp_capabilities.HardwareDisabled = WdfFalse;
 25.1729 +  WdfDeviceSetPnpCapabilities(child_device, &child_pnp_capabilities);
 25.1730 +
 25.1731 +  //WDF_DEVICE_POWER_CAPABILITIES_INIT(&child_power_capabilities);
 25.1732 +  //WdfDeviceSetPowerCapabilities(child_device, &child_power_capabilities);  
 25.1733 +
 25.1734 +  bus_interface.Size = sizeof(BUS_INTERFACE_STANDARD);
 25.1735 +  bus_interface.Version = 1; //BUS_INTERFACE_STANDARD_VERSION;
 25.1736 +  bus_interface.Context = xppdd;
 25.1737 +  bus_interface.InterfaceReference = XenPci_IS_InterfaceReference;
 25.1738 +  bus_interface.InterfaceDereference = XenPci_IS_InterfaceReference;
 25.1739 +  bus_interface.TranslateBusAddress = XenPci_BIS_TranslateBusAddress;
 25.1740 +  bus_interface.GetDmaAdapter = XenPci_BIS_GetDmaAdapter;
 25.1741 +  bus_interface.SetBusData = XenPci_BIS_SetBusData;
 25.1742 +  bus_interface.GetBusData = XenPci_BIS_GetBusData;
 25.1743 +  WDF_QUERY_INTERFACE_CONFIG_INIT(&interface_config, (PINTERFACE)&bus_interface, &GUID_BUS_INTERFACE_STANDARD, NULL);
 25.1744 +  status = WdfDeviceAddQueryInterface(child_device, &interface_config);
 25.1745 +  if (!NT_SUCCESS(status))
 25.1746 +  {
 25.1747 +    return status;
 25.1748 +  }
 25.1749 +  
 25.1750 +  RtlStringCbCopyA(xppdd->path, ARRAY_SIZE(xppdd->path), identification->path);
 25.1751 +  RtlStringCbCopyA(xppdd->device, ARRAY_SIZE(xppdd->device), identification->device);
 25.1752 +  xppdd->index = identification->index;
 25.1753 +  KeInitializeEvent(&xppdd->backend_state_event, SynchronizationEvent, FALSE);
 25.1754 +  xppdd->backend_state = XenbusStateUnknown;
 25.1755 +  xppdd->backend_path[0] = '\0';
 25.1756 +    
 25.1757 +  FUNCTION_EXIT();
 25.1758 +  
 25.1759 +  return status;
 25.1760 +}
 25.1761 +
 25.1762 +static __forceinline VOID
 25.1763 +XenPci_Pdo_ChangeSuspendState(WDFDEVICE device, ULONG new_state)
 25.1764 +{
 25.1765 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1766 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1767 +
 25.1768 +  FUNCTION_ENTER();
 25.1769 +  KdPrint((__DRIVER_NAME "     setting pdo state to %d\n", new_state));
 25.1770 +  xppdd->device_state.suspend_resume_state_pdo = new_state;
 25.1771 +  KeMemoryBarrier();
 25.1772 +  KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xpdd->pdo_event_channel));
 25.1773 +  EvtChn_Notify(xpdd, xpdd->pdo_event_channel);    
 25.1774 +  while(xppdd->device_state.suspend_resume_state_fdo != xppdd->device_state.suspend_resume_state_pdo)
 25.1775 +  {
 25.1776 +    KdPrint((__DRIVER_NAME "     waiting...\n"));
 25.1777 +    KeWaitForSingleObject(&xpdd->pdo_suspend_event, Executive, KernelMode, FALSE, NULL);
 25.1778 +  }
 25.1779 +  KdPrint((__DRIVER_NAME "     fdo state set to %d\n", new_state));
 25.1780 +  FUNCTION_EXIT();
 25.1781 +}
 25.1782 +
 25.1783 +/* called at PASSIVE_LEVEL */
 25.1784 +NTSTATUS
 25.1785 +XenPci_Pdo_Suspend(WDFDEVICE device)
 25.1786 +{
 25.1787 +  NTSTATUS status = STATUS_SUCCESS;
 25.1788 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1789 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1790 +  //LARGE_INTEGER wait_time;
 25.1791 +  char path[128];
 25.1792 +  PUCHAR in_ptr;
 25.1793 +  UCHAR type;
 25.1794 +  PVOID setting;
 25.1795 +  PVOID value;
 25.1796 +  PVOID value2;
 25.1797 +
 25.1798 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (%s)\n", xppdd->path));
 25.1799 +
 25.1800 +  if (xppdd->backend_state == XenbusStateConnected)
 25.1801 +  {
 25.1802 +    xppdd->restart_on_resume = TRUE;
 25.1803 +    XenPci_Pdo_ChangeSuspendState(device, SR_STATE_SUSPENDING);
 25.1804 +
 25.1805 +    XenPci_ChangeFrontendState(device, XenbusStateClosing, XenbusStateClosing, 30000);
 25.1806 +    XenPci_ChangeFrontendState(device, XenbusStateClosed, XenbusStateClosed, 30000);
 25.1807 +    XenPci_ChangeFrontendState(device, XenbusStateInitialising, XenbusStateInitWait, 30000);
 25.1808 +
 25.1809 +    if (xppdd->assigned_resources_start != NULL)
 25.1810 +    {
 25.1811 +      in_ptr = xppdd->assigned_resources_ptr;
 25.1812 +      ADD_XEN_INIT_RSP(&in_ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
 25.1813 +      in_ptr = xppdd->assigned_resources_start;
 25.1814 +      while((type = GET_XEN_INIT_RSP(&in_ptr, &setting, &value, &value2)) != XEN_INIT_TYPE_END)
 25.1815 +      {
 25.1816 +        switch (type)
 25.1817 +        {
 25.1818 +        case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
 25.1819 +        case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
 25.1820 +          EvtChn_Unbind(xpdd, PtrToUlong(value));
 25.1821 +          EvtChn_Close(xpdd, PtrToUlong(value));
 25.1822 +          break;
 25.1823 +        }
 25.1824 +      }
 25.1825 +    }
 25.1826 +
 25.1827 +    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
 25.1828 +    XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);  
 25.1829 +  }
 25.1830 +  else
 25.1831 +  {
 25.1832 +    xppdd->restart_on_resume = FALSE;
 25.1833 +  }
 25.1834 +
 25.1835 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
 25.1836 +  
 25.1837 +  return status;
 25.1838 +}
 25.1839 +
 25.1840 +NTSTATUS
 25.1841 +XenPci_Pdo_Resume(WDFDEVICE device)
 25.1842 +{
 25.1843 +  NTSTATUS status = STATUS_SUCCESS;
 25.1844 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
 25.1845 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
 25.1846 +  ULONG old_backend_state;
 25.1847 +  PUCHAR src, dst;
 25.1848 +
 25.1849 +  FUNCTION_ENTER();
 25.1850 +  KdPrint((__DRIVER_NAME "     path = %s\n", xppdd->path));
 25.1851 +
 25.1852 +  xppdd->device_state.pdo_event_channel = xpdd->pdo_event_channel;
 25.1853 +  old_backend_state = xppdd->backend_state;
 25.1854 +
 25.1855 +  if (xppdd->restart_on_resume)
 25.1856 +  {  
 25.1857 +    status = XenPci_GetBackendAndAddWatch(device);
 25.1858 +  
 25.1859 +    if (XenPci_ChangeFrontendState(device, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
 25.1860 +    {
 25.1861 +      KdPrint((__DRIVER_NAME "     Failed to change frontend state to Initialising\n"));
 25.1862 +      // this is probably an unrecoverable situation...
 25.1863 +      FUNCTION_ERROR_EXIT();
 25.1864 +      return STATUS_UNSUCCESSFUL;
 25.1865 +    }
 25.1866 +    if (xppdd->assigned_resources_ptr)
 25.1867 +    {
 25.1868 +      // reset things - feed the 'requested resources' back in
 25.1869 +      ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
 25.1870 +      src = xppdd->requested_resources_start;
 25.1871 +      xppdd->requested_resources_ptr = xppdd->requested_resources_start = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);;
 25.1872 +      xppdd->assigned_resources_ptr = xppdd->assigned_resources_start;
 25.1873 +      
 25.1874 +      dst = MmMapIoSpace(xppdd->config_page_phys, xppdd->config_page_length, MmNonCached);
 25.1875 +      
 25.1876 +      status = XenPci_XenConfigDeviceSpecifyBuffers(device, src, dst);
 25.1877 +
 25.1878 +      MmUnmapIoSpace(dst, xppdd->config_page_length);
 25.1879 +      ExFreePoolWithTag(src, XENPCI_POOL_TAG);
 25.1880 +    }
 25.1881 +    if (XenPci_ChangeFrontendState(device, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
 25.1882 +    {
 25.1883 +      // this is definitely an unrecoverable situation...
 25.1884 +      KdPrint((__DRIVER_NAME "     Failed to change frontend state to connected\n"));
 25.1885 +      FUNCTION_ERROR_EXIT();
 25.1886 +      return STATUS_UNSUCCESSFUL;
 25.1887 +    }
 25.1888 +    XenPci_Pdo_ChangeSuspendState(device, SR_STATE_RESUMING);
 25.1889 +    XenPci_Pdo_ChangeSuspendState(device, SR_STATE_RUNNING);
 25.1890 +  }
 25.1891 +
 25.1892 +  FUNCTION_EXIT();
 25.1893 +
 25.1894 +  return STATUS_SUCCESS;
 25.1895 +} 
 25.1896 +
 25.1897 +#if 0
 25.1898  NTSTATUS
 25.1899  XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
 25.1900  {
 25.1901 @@ -516,9 +2407,9 @@ XenPci_XenShutdownDevice(PVOID Context)
 25.1902  
 25.1903    if (xppdd->assigned_resources_start != NULL)
 25.1904    {
 25.1905 -    ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL);
 25.1906 +    ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
 25.1907      in_ptr = xppdd->assigned_resources_start;
 25.1908 -    while((type = GET_XEN_INIT_RSP(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
 25.1909 +    while((type = GET_XEN_INIT_RSP(&in_ptr, &setting, &value, &value2)) != XEN_INIT_TYPE_END)
 25.1910      {
 25.1911        switch (type)
 25.1912        {
 25.1913 @@ -556,7 +2447,7 @@ XenPci_XenConfigDeviceSpecifyBuffers(PVO
 25.1914    NTSTATUS status = STATUS_SUCCESS;
 25.1915    ULONG i;
 25.1916    char path[128];
 25.1917 -  PCHAR setting, value;
 25.1918 +  PCHAR setting, value, value2;
 25.1919    PCHAR res;
 25.1920    PVOID address;
 25.1921    UCHAR type;
 25.1922 @@ -605,15 +2496,15 @@ XenPci_XenConfigDeviceSpecifyBuffers(PVO
 25.1923    vectors.XenBus_RemWatch = XenPci_XenBus_RemWatch;
 25.1924  
 25.1925    if (qemu_filtered)
 25.1926 -    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_ACTIVE, NULL, NULL);
 25.1927 -
 25.1928 -  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION, NULL, UlongToPtr(qemu_protocol_version));
 25.1929 +    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_ACTIVE, NULL, NULL, NULL);
 25.1930 +
 25.1931 +  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION, NULL, UlongToPtr(qemu_protocol_version), NULL);
 25.1932    
 25.1933 -  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_VECTORS, NULL, &vectors);
 25.1934 -  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_STATE_PTR, NULL, &xppdd->device_state);
 25.1935 +  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_VECTORS, NULL, &vectors, NULL);
 25.1936 +  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_STATE_PTR, NULL, &xppdd->device_state, NULL);
 25.1937  
 25.1938    // first pass, possibly before state == Connected
 25.1939 -  while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value)) != XEN_INIT_TYPE_END)
 25.1940 +  while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
 25.1941    {
 25.1942    
 25.1943      if (!done_xenbus_init)
 25.1944 @@ -626,7 +2517,7 @@ XenPci_XenConfigDeviceSpecifyBuffers(PVO
 25.1945        done_xenbus_init = TRUE;
 25.1946      }
 25.1947      
 25.1948 -    ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, type, setting, value);
 25.1949 +    ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, type, setting, value, value2);
 25.1950  
 25.1951      switch (type)
 25.1952      {
 25.1953 @@ -650,8 +2541,8 @@ XenPci_XenConfigDeviceSpecifyBuffers(PVO
 25.1954          {
 25.1955            RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
 25.1956            XenBus_Printf(xpdd, XBT_NIL, path, "%d", gref);
 25.1957 -          ADD_XEN_INIT_RSP(&out_ptr, type, setting, address);
 25.1958 -          ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, ring);
 25.1959 +          ADD_XEN_INIT_RSP(&out_ptr, type, setting, address, NULL);
 25.1960 +          ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, ring, NULL);
 25.1961            // add the grant entry too so it gets freed automatically
 25.1962            __ADD_XEN_INIT_UCHAR(&xppdd->assigned_resources_ptr, XEN_INIT_TYPE_GRANT_ENTRIES);
 25.1963            __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, 1);
 25.1964 @@ -677,8 +2568,8 @@ XenPci_XenConfigDeviceSpecifyBuffers(PVO
 25.1965          //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, event_channel));
 25.1966          RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
 25.1967          XenBus_Printf(xpdd, XBT_NIL, path, "%d", event_channel);
 25.1968 -        ADD_XEN_INIT_RSP(&out_ptr, type, setting, UlongToPtr(event_channel));
 25.1969 -        ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, UlongToPtr(event_channel));
 25.1970 +        ADD_XEN_INIT_RSP(&out_ptr, type, setting, UlongToPtr(event_channel), NULL);
 25.1971 +        ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, UlongToPtr(event_channel), NULL);
 25.1972          if (type == XEN_INIT_TYPE_EVENT_CHANNEL_IRQ)
 25.1973            EvtChn_BindIrq(xpdd, event_channel, xppdd->irq_vector, path);
 25.1974        }
 25.1975 @@ -706,7 +2597,7 @@ XenPci_XenConfigDeviceSpecifyBuffers(PVO
 25.1976  
 25.1977    // second pass, possibly after state == Connected
 25.1978    in_ptr = src;
 25.1979 -  while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value)) != XEN_INIT_TYPE_END)
 25.1980 +  while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
 25.1981    {
 25.1982      switch(type)
 25.1983      {
 25.1984 @@ -721,12 +2612,12 @@ XenPci_XenConfigDeviceSpecifyBuffers(PVO
 25.1985        {
 25.1986          //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = <failed>\n", setting));
 25.1987          XenPci_FreeMem(res);
 25.1988 -        ADD_XEN_INIT_RSP(&out_ptr, type, setting, NULL);
 25.1989 +        ADD_XEN_INIT_RSP(&out_ptr, type, setting, NULL, NULL);
 25.1990        }
 25.1991        else
 25.1992        {
 25.1993          //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
 25.1994 -        ADD_XEN_INIT_RSP(&out_ptr, type, setting, value);
 25.1995 +        ADD_XEN_INIT_RSP(&out_ptr, type, setting, value, NULL);
 25.1996          XenPci_FreeMem(value);
 25.1997        }
 25.1998        break;
 25.1999 @@ -1276,12 +3167,16 @@ static VOID
 25.2000  XenPci_IS_InterfaceReference(PVOID context)
 25.2001  {
 25.2002    UNREFERENCED_PARAMETER(context);
 25.2003 +  FUNCTION_ENTER();
 25.2004 +  FUNCTION_EXIT();
 25.2005  }
 25.2006  
 25.2007  static VOID
 25.2008  XenPci_IS_InterfaceDereference(PVOID context)
 25.2009  {
 25.2010    UNREFERENCED_PARAMETER(context);
 25.2011 +  FUNCTION_ENTER();
 25.2012 +  FUNCTION_EXIT();
 25.2013  }
 25.2014  
 25.2015  static BOOLEAN
 25.2016 @@ -1322,18 +3217,21 @@ XenPci_DOP_AllocateCommonBuffer(
 25.2017    BOOLEAN CacheEnabled
 25.2018  )
 25.2019  {
 25.2020 -  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
 25.2021 -  PXENPCI_DEVICE_DATA xpdd = xen_dma_adapter->xppdd->bus_fdo->DeviceExtension;
 25.2022 +  xen_dma_adapter_t *xen_dma_adapter;
 25.2023 +  PXENPCI_DEVICE_DATA xpdd;
 25.2024    PVOID buffer;
 25.2025    PFN_NUMBER pfn;
 25.2026    grant_ref_t gref;
 25.2027 -  /* should LogicalAddress be the gref? */
 25.2028    
 25.2029    UNREFERENCED_PARAMETER(DmaAdapter);
 25.2030    UNREFERENCED_PARAMETER(CacheEnabled);
 25.2031    
 25.2032 -  FUNCTION_ENTER();
 25.2033 -  KdPrint((__DRIVER_NAME "     Length = %d\n", Length));
 25.2034 +  //FUNCTION_ENTER();
 25.2035 +
 25.2036 +  xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
 25.2037 +  xpdd = xen_dma_adapter->xppdd->bus_fdo->DeviceExtension;
 25.2038 +
 25.2039 +  //KdPrint((__DRIVER_NAME "     Length = %d\n", Length));
 25.2040    
 25.2041    buffer = ExAllocatePoolWithTag(NonPagedPool, Length, XENPCI_POOL_TAG);
 25.2042  
 25.2043 @@ -1343,7 +3241,7 @@ XenPci_DOP_AllocateCommonBuffer(
 25.2044    ASSERT(gref);
 25.2045    LogicalAddress->QuadPart = (gref << PAGE_SHIFT) | (PtrToUlong(buffer) & (PAGE_SIZE - 1));
 25.2046    
 25.2047 -  FUNCTION_EXIT();
 25.2048 +  //FUNCTION_EXIT();
 25.2049    return buffer;
 25.2050  }
 25.2051  
 25.2052 @@ -1357,9 +3255,13 @@ XenPci_DOP_FreeCommonBuffer(
 25.2053  )
 25.2054  {
 25.2055    UNREFERENCED_PARAMETER(DmaAdapter);
 25.2056 +  UNREFERENCED_PARAMETER(Length);
 25.2057 +  UNREFERENCED_PARAMETER(LogicalAddress);
 25.2058 +  UNREFERENCED_PARAMETER(CacheEnabled);
 25.2059  
 25.2060    FUNCTION_ENTER();
 25.2061    ExFreePoolWithTag(VirtualAddress, XENPCI_POOL_TAG);
 25.2062 +  // TODO: free the grant ref here
 25.2063    FUNCTION_EXIT();
 25.2064  }
 25.2065  
 25.2066 @@ -1401,18 +3303,23 @@ XenPci_DOP_AllocateAdapterChannel(
 25.2067  
 25.2068  static BOOLEAN
 25.2069  XenPci_DOP_FlushAdapterBuffers(
 25.2070 -    IN PDMA_ADAPTER  DmaAdapter,
 25.2071 -    IN PMDL  Mdl,
 25.2072 -    IN PVOID  MapRegisterBase,
 25.2073 -    IN PVOID  CurrentVa,
 25.2074 -    IN ULONG  Length,
 25.2075 -    IN BOOLEAN  WriteToDevice
 25.2076 -    )
 25.2077 +  PDMA_ADAPTER DmaAdapter,
 25.2078 +  PMDL Mdl,
 25.2079 +  PVOID MapRegisterBase,
 25.2080 +  PVOID CurrentVa,
 25.2081 +  ULONG Length,
 25.2082 +  BOOLEAN WriteToDevice)
 25.2083  {
 25.2084    UNREFERENCED_PARAMETER(DmaAdapter);
 25.2085 +  UNREFERENCED_PARAMETER( Mdl);
 25.2086 +  UNREFERENCED_PARAMETER(MapRegisterBase);
 25.2087 +  UNREFERENCED_PARAMETER(CurrentVa);
 25.2088 +  UNREFERENCED_PARAMETER(Length);
 25.2089 +  UNREFERENCED_PARAMETER(WriteToDevice);
 25.2090  
 25.2091    FUNCTION_ENTER();
 25.2092    FUNCTION_EXIT();
 25.2093 +  return TRUE;
 25.2094  }
 25.2095  
 25.2096  static VOID
 25.2097 @@ -1433,6 +3340,8 @@ XenPci_DOP_FreeMapRegisters(
 25.2098    ULONG NumberOfMapRegisters)
 25.2099  {
 25.2100    UNREFERENCED_PARAMETER(DmaAdapter);
 25.2101 +  UNREFERENCED_PARAMETER(MapRegisterBase);
 25.2102 +  UNREFERENCED_PARAMETER(NumberOfMapRegisters);
 25.2103  
 25.2104    FUNCTION_ENTER();
 25.2105    FUNCTION_EXIT();
 25.2106 @@ -1447,10 +3356,21 @@ XenPci_DOP_MapTransfer(
 25.2107      PULONG Length,
 25.2108      BOOLEAN WriteToDevice)
 25.2109  {
 25.2110 +  PHYSICAL_ADDRESS physical;
 25.2111 +  
 25.2112    UNREFERENCED_PARAMETER(DmaAdapter);
 25.2113 +  UNREFERENCED_PARAMETER(Mdl);
 25.2114 +  UNREFERENCED_PARAMETER(MapRegisterBase);
 25.2115 +  UNREFERENCED_PARAMETER(CurrentVa);
 25.2116 +  UNREFERENCED_PARAMETER(Length);
 25.2117 +  UNREFERENCED_PARAMETER(WriteToDevice);
 25.2118  
 25.2119    FUNCTION_ENTER();
 25.2120 +  
 25.2121 +  physical.QuadPart = 0;
 25.2122 +  
 25.2123    FUNCTION_EXIT();
 25.2124 +  return physical;
 25.2125  }
 25.2126  
 25.2127  static ULONG
 25.2128 @@ -1461,6 +3381,7 @@ XenPci_DOP_GetDmaAlignment(
 25.2129  
 25.2130    FUNCTION_ENTER();
 25.2131    FUNCTION_EXIT();
 25.2132 +  return 0;
 25.2133  }
 25.2134  
 25.2135  static ULONG
 25.2136 @@ -1471,6 +3392,7 @@ XenPci_DOP_ReadDmaCounter(
 25.2137  
 25.2138    FUNCTION_ENTER();
 25.2139    FUNCTION_EXIT();
 25.2140 +  return 0;
 25.2141  }
 25.2142  
 25.2143  static NTSTATUS
 25.2144 @@ -1485,9 +3407,17 @@ XenPci_DOP_GetScatterGatherList(
 25.2145    BOOLEAN WriteToDevice)
 25.2146  {
 25.2147    UNREFERENCED_PARAMETER(DmaAdapter);
 25.2148 +  UNREFERENCED_PARAMETER(DeviceObject);
 25.2149 +  UNREFERENCED_PARAMETER(Mdl);
 25.2150 +  UNREFERENCED_PARAMETER(CurrentVa);
 25.2151 +  UNREFERENCED_PARAMETER(Length);
 25.2152 +  UNREFERENCED_PARAMETER(ExecutionRoutine);
 25.2153 +  UNREFERENCED_PARAMETER(Context);
 25.2154 +  UNREFERENCED_PARAMETER(WriteToDevice);
 25.2155  
 25.2156    FUNCTION_ENTER();
 25.2157    FUNCTION_EXIT();
 25.2158 +  return STATUS_SUCCESS;
 25.2159  }
 25.2160  
 25.2161  #define MAP_TYPE_VIRTUAL  1
 25.2162 @@ -1508,14 +3438,17 @@ XenPci_DOP_PutScatterGatherList(
 25.2163      IN BOOLEAN WriteToDevice
 25.2164      )
 25.2165  {
 25.2166 -  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
 25.2167 -  PXENPCI_DEVICE_DATA xpdd = xen_dma_adapter->xppdd->bus_fdo->DeviceExtension;
 25.2168 +  xen_dma_adapter_t *xen_dma_adapter;
 25.2169 +  PXENPCI_DEVICE_DATA xpdd;
 25.2170    ULONG i;
 25.2171    sg_extra_t *sg_extra;
 25.2172  
 25.2173    UNREFERENCED_PARAMETER(WriteToDevice);
 25.2174    
 25.2175    //FUNCTION_ENTER();
 25.2176 +
 25.2177 +  xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
 25.2178 +  xpdd = xen_dma_adapter->xppdd->bus_fdo->DeviceExtension;
 25.2179    
 25.2180    sg_extra = (sg_extra_t *)((PUCHAR)ScatterGather + FIELD_OFFSET(SCATTER_GATHER_LIST, Elements) +
 25.2181      (sizeof(SCATTER_GATHER_ELEMENT)) * ScatterGather->NumberOfElements);
 25.2182 @@ -1587,6 +3520,7 @@ XenPci_DOP_CalculateScatterGatherList(
 25.2183      *NumberOfMapRegisters = 1;
 25.2184  
 25.2185    KdPrint((__DRIVER_NAME "     ScatterGatherListSize = %d\n", *ScatterGatherListSize));
 25.2186 +
 25.2187    FUNCTION_EXIT();
 25.2188    return STATUS_SUCCESS;
 25.2189  }
 25.2190 @@ -1609,8 +3543,8 @@ XenPci_DOP_BuildScatterGatherList(
 25.2191    PUCHAR ptr;
 25.2192    ULONG remaining = Length;
 25.2193    ULONG total_remaining;
 25.2194 -  xen_dma_adapter_t *xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
 25.2195 -  PXENPCI_DEVICE_DATA xpdd = xen_dma_adapter->xppdd->bus_fdo->DeviceExtension;
 25.2196 +  xen_dma_adapter_t *xen_dma_adapter;
 25.2197 +  PXENPCI_DEVICE_DATA xpdd;
 25.2198    sg_extra_t *sg_extra;
 25.2199    PMDL curr_mdl;
 25.2200    ULONG map_type;
 25.2201 @@ -1623,6 +3557,9 @@ XenPci_DOP_BuildScatterGatherList(
 25.2202  
 25.2203    //FUNCTION_ENTER();
 25.2204  
 25.2205 +  xen_dma_adapter = (xen_dma_adapter_t *)DmaAdapter;
 25.2206 +  xpdd = xen_dma_adapter->xppdd->bus_fdo->DeviceExtension;
 25.2207 +
 25.2208    ASSERT(Mdl);
 25.2209    if (xen_dma_adapter->dma_extension)
 25.2210    {
 25.2211 @@ -1675,7 +3612,10 @@ XenPci_DOP_BuildScatterGatherList(
 25.2212      for (sg_element = 0, curr_mdl = Mdl; curr_mdl; curr_mdl = curr_mdl->Next)
 25.2213      {
 25.2214        remaining = MmGetMdlByteCount(curr_mdl);
 25.2215 -      offset = MmGetMdlByteOffset(curr_mdl);
 25.2216 +      if (!MmGetMdlByteOffset(Mdl) && (PtrToUlong(CurrentVa) & (PAGE_SIZE - 1)))
 25.2217 +        offset = (PtrToUlong(CurrentVa) & (PAGE_SIZE - 1));
 25.2218 +      else
 25.2219 +        offset = MmGetMdlByteOffset(curr_mdl);
 25.2220        for (i = 0; i < ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(curr_mdl), MmGetMdlByteCount(curr_mdl)); i++)
 25.2221        {
 25.2222  //KdPrint((__DRIVER_NAME "     element = %d\n", sg_element));
 25.2223 @@ -1699,6 +3639,8 @@ XenPci_DOP_BuildScatterGatherList(
 25.2224      ASSERT(sg_extra->aligned_buffer); /* lazy */
 25.2225      sg_extra->unaligned_buffer = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
 25.2226      ASSERT(sg_extra->unaligned_buffer); /* lazy */
 25.2227 +    if (!MmGetMdlByteOffset(Mdl) && (PtrToUlong(CurrentVa) & (PAGE_SIZE - 1)))
 25.2228 +      sg_extra->unaligned_buffer = (PUCHAR)sg_extra->unaligned_buffer + (PtrToUlong(CurrentVa) & (PAGE_SIZE - 1));
 25.2229      sg_extra->copy_length = Length;
 25.2230      if (WriteToDevice)
 25.2231        memcpy(sg_extra->aligned_buffer, sg_extra->unaligned_buffer, sg_extra->copy_length);
 25.2232 @@ -1718,17 +3660,21 @@ XenPci_DOP_BuildScatterGatherList(
 25.2233      //KdPrint((__DRIVER_NAME "     MAP_TYPE_VIRTUAL\n"));
 25.2234      ptr = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
 25.2235      ASSERT(ptr); /* lazy */
 25.2236 +    if (!MmGetMdlByteOffset(Mdl) && (PtrToUlong(CurrentVa) & (PAGE_SIZE - 1)))
 25.2237 +      ptr += (PtrToUlong(CurrentVa) & (PAGE_SIZE - 1));
 25.2238      sglist->Elements[0].Address.QuadPart = (ULONGLONG)ptr;
 25.2239      sglist->Elements[0].Length = Length;
 25.2240      break;
 25.2241    }
 25.2242 -  //KdPrint((__DRIVER_NAME "     CurrentVa = %p, Length = %d\n", CurrentVa, Length));
 25.2243 -  //for (i = 0; i < sglist->NumberOfElements; i++)
 25.2244 -  //{
 25.2245 -    //KdPrint((__DRIVER_NAME "     sge[%d]->Address = %08x%08x, Length = %d\n", i, sglist->Elements[i].Address.HighPart,
 25.2246 -    //  sglist->Elements[i].Address.LowPart, sglist->Elements[i].Length));
 25.2247 -  //}
 25.2248 -  
 25.2249 +#if 0
 25.2250 +  KdPrint((__DRIVER_NAME "     Mdl = %p, CurrentVa = %p, Mdl->Va = %p, Offset = %d, Length = %d\n", 
 25.2251 +    Mdl, CurrentVa, MmGetMdlVirtualAddress(Mdl), MmGetMdlByteOffset(Mdl), Length));
 25.2252 +  for (i = 0; i < sglist->NumberOfElements; i++)
 25.2253 +  {
 25.2254 +    KdPrint((__DRIVER_NAME "     sge[%d]->Address = %08x%08x, Length = %d\n", i, sglist->Elements[i].Address.HighPart,
 25.2255 +      sglist->Elements[i].Address.LowPart, sglist->Elements[i].Length));
 25.2256 +  }
 25.2257 +#endif
 25.2258    ExecutionRoutine(DeviceObject, DeviceObject->CurrentIrp, ScatterGatherBuffer, Context);
 25.2259  
 25.2260    //FUNCTION_EXIT();
 25.2261 @@ -1738,52 +3684,84 @@ XenPci_DOP_BuildScatterGatherList(
 25.2262  
 25.2263  static NTSTATUS
 25.2264  XenPci_DOP_BuildMdlFromScatterGatherList(
 25.2265 -    IN PDMA_ADAPTER  DmaAdapter,
 25.2266 -    IN PSCATTER_GATHER_LIST  ScatterGather,
 25.2267 -    IN PMDL  OriginalMdl,
 25.2268 -    OUT PMDL  *TargetMdl
 25.2269 -    )
 25.2270 +  PDMA_ADAPTER DmaAdapter,
 25.2271 +  PSCATTER_GATHER_LIST ScatterGather,
 25.2272 +  PMDL OriginalMdl,
 25.2273 +  PMDL *TargetMdl)
 25.2274  {
 25.2275 +  UNREFERENCED_PARAMETER(DmaAdapter);
 25.2276 +  UNREFERENCED_PARAMETER(ScatterGather);
 25.2277 +  UNREFERENCED_PARAMETER(OriginalMdl);
 25.2278 +  UNREFERENCED_PARAMETER(TargetMdl);
 25.2279 +
 25.2280    FUNCTION_ENTER();
 25.2281    FUNCTION_EXIT();
 25.2282    return STATUS_UNSUCCESSFUL;
 25.2283  }
 25.2284  
 25.2285  static PDMA_ADAPTER
 25.2286 -XenPci_BIS_GetDmaAdapter(PVOID context, PDEVICE_DESCRIPTION device_descriptor, PULONG number_of_map_registers)
 25.2287 +XenPci_BIS_GetDmaAdapter(PVOID context, PDEVICE_DESCRIPTION device_description, PULONG number_of_map_registers)
 25.2288  {
 25.2289    xen_dma_adapter_t *xen_dma_adapter;
 25.2290    PDEVICE_OBJECT curr, prev;
 25.2291    PDRIVER_OBJECT fdo_driver_object;
 25.2292    PVOID fdo_driver_extension;
 25.2293    
 25.2294 -  UNREFERENCED_PARAMETER(device_descriptor);
 25.2295 +  UNREFERENCED_PARAMETER(device_description);
 25.2296    
 25.2297    FUNCTION_ENTER();
 25.2298 -  xen_dma_adapter = ExAllocatePoolWithTag(NonPagedPool, sizeof(xen_dma_adapter_t), XENPCI_POOL_TAG);
 25.2299 +
 25.2300 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 25.2301 +  KdPrint((__DRIVER_NAME "     Device Description = %p:\n", device_description));
 25.2302 +  KdPrint((__DRIVER_NAME "      Version  = %d\n", device_description->Version));
 25.2303 +  KdPrint((__DRIVER_NAME "      Master = %d\n", device_description->Master));
 25.2304 +  KdPrint((__DRIVER_NAME "      ScatterGather = %d\n", device_description->ScatterGather));
 25.2305 +  KdPrint((__DRIVER_NAME "      DemandMode = %d\n", device_description->DemandMode));
 25.2306 +  KdPrint((__DRIVER_NAME "      AutoInitialize = %d\n", device_description->AutoInitialize));
 25.2307 +  KdPrint((__DRIVER_NAME "      Dma32BitAddresses = %d\n", device_description->Dma32BitAddresses));
 25.2308 +  KdPrint((__DRIVER_NAME "      IgnoreCount = %d\n", device_description->IgnoreCount));
 25.2309 +  KdPrint((__DRIVER_NAME "      Dma64BitAddresses = %d\n", device_description->Dma64BitAddresses));
 25.2310 +  KdPrint((__DRIVER_NAME "      BusNumber = %d\n", device_description->BusNumber));
 25.2311 +  KdPrint((__DRIVER_NAME "      DmaChannel = %d\n", device_description->DmaChannel));
 25.2312 +  KdPrint((__DRIVER_NAME "      InterfaceType = %d\n", device_description->InterfaceType));
 25.2313 +  KdPrint((__DRIVER_NAME "      DmaWidth = %d\n", device_description->DmaWidth));
 25.2314 +  KdPrint((__DRIVER_NAME "      DmaSpeed = %d\n", device_description->DmaSpeed));
 25.2315 +  KdPrint((__DRIVER_NAME "      MaximumLength = %d\n", device_description->MaximumLength));
 25.2316 +  KdPrint((__DRIVER_NAME "      DmaPort = %d\n", device_description->DmaPort));
 25.2317 +  
 25.2318 +/*
 25.2319 +we have to allocate PAGE_SIZE bytes here because Windows thinks this is
 25.2320 +actually an ADAPTER_OBJECT, and then the verifier crashes because
 25.2321 +Windows accessed beyond the end of the structure :(
 25.2322 +*/
 25.2323 +  xen_dma_adapter = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
 25.2324 +  RtlZeroMemory(xen_dma_adapter, PAGE_SIZE);
 25.2325    xen_dma_adapter->dma_adapter.Version = 2;
 25.2326 -  xen_dma_adapter->dma_adapter.Size = sizeof(xen_dma_adapter_t);
 25.2327 -  xen_dma_adapter->dma_adapter.DmaOperations = &xen_dma_adapter->dma_operations;
 25.2328 -  xen_dma_adapter->dma_operations.Size = sizeof(DMA_OPERATIONS);
 25.2329 -  xen_dma_adapter->dma_operations.PutDmaAdapter = XenPci_DOP_PutDmaAdapter;
 25.2330 -  xen_dma_adapter->dma_operations.AllocateCommonBuffer = XenPci_DOP_AllocateCommonBuffer;
 25.2331 -  xen_dma_adapter->dma_operations.FreeCommonBuffer = XenPci_DOP_FreeCommonBuffer;
 25.2332 -  xen_dma_adapter->dma_operations.AllocateAdapterChannel = XenPci_DOP_AllocateAdapterChannel;
 25.2333 -  xen_dma_adapter->dma_operations.FlushAdapterBuffers = XenPci_DOP_FlushAdapterBuffers;
 25.2334 -  xen_dma_adapter->dma_operations.FreeAdapterChannel = XenPci_DOP_FreeAdapterChannel;
 25.2335 -  xen_dma_adapter->dma_operations.FreeMapRegisters = XenPci_DOP_FreeMapRegisters;
 25.2336 -  xen_dma_adapter->dma_operations.MapTransfer = XenPci_DOP_MapTransfer;
 25.2337 -  xen_dma_adapter->dma_operations.GetDmaAlignment = XenPci_DOP_GetDmaAlignment;
 25.2338 -  xen_dma_adapter->dma_operations.ReadDmaCounter = XenPci_DOP_ReadDmaCounter;
 25.2339 -  xen_dma_adapter->dma_operations.GetScatterGatherList = XenPci_DOP_GetScatterGatherList;
 25.2340 -  xen_dma_adapter->dma_operations.PutScatterGatherList = XenPci_DOP_PutScatterGatherList;
 25.2341 -  xen_dma_adapter->dma_operations.CalculateScatterGatherList = XenPci_DOP_CalculateScatterGatherList;
 25.2342 -  xen_dma_adapter->dma_operations.BuildScatterGatherList = XenPci_DOP_BuildScatterGatherList;
 25.2343 -  xen_dma_adapter->dma_operations.BuildMdlFromScatterGatherList = XenPci_DOP_BuildMdlFromScatterGatherList;
 25.2344 +  xen_dma_adapter->dma_adapter.Size = sizeof(DMA_ADAPTER); //xen_dma_adapter_t);
 25.2345 +  xen_dma_adapter->dma_adapter.DmaOperations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DMA_OPERATIONS), XENPCI_POOL_TAG);
 25.2346 +  //xen_dma_adapter->dma_adapter.DmaOperations = &xen_dma_adapter->dma_operations;
 25.2347 +  xen_dma_adapter->dma_adapter.DmaOperations->Size = sizeof(DMA_OPERATIONS);
 25.2348 +  xen_dma_adapter->dma_adapter.DmaOperations->PutDmaAdapter = XenPci_DOP_PutDmaAdapter;
 25.2349 +  xen_dma_adapter->dma_adapter.DmaOperations->AllocateCommonBuffer = XenPci_DOP_AllocateCommonBuffer;
 25.2350 +  xen_dma_adapter->dma_adapter.DmaOperations->FreeCommonBuffer = XenPci_DOP_FreeCommonBuffer;
 25.2351 +  xen_dma_adapter->dma_adapter.DmaOperations->AllocateAdapterChannel = XenPci_DOP_AllocateAdapterChannel;
 25.2352 +  xen_dma_adapter->dma_adapter.DmaOperations->FlushAdapterBuffers = XenPci_DOP_FlushAdapterBuffers;
 25.2353 +  xen_dma_adapter->dma_adapter.DmaOperations->FreeAdapterChannel = XenPci_DOP_FreeAdapterChannel;
 25.2354 +  xen_dma_adapter->dma_adapter.DmaOperations->FreeMapRegisters = XenPci_DOP_FreeMapRegisters;
 25.2355 +  xen_dma_adapter->dma_adapter.DmaOperations->MapTransfer = XenPci_DOP_MapTransfer;
 25.2356 +  xen_dma_adapter->dma_adapter.DmaOperations->GetDmaAlignment = XenPci_DOP_GetDmaAlignment;
 25.2357 +  xen_dma_adapter->dma_adapter.DmaOperations->ReadDmaCounter = XenPci_DOP_ReadDmaCounter;
 25.2358 +  xen_dma_adapter->dma_adapter.DmaOperations->GetScatterGatherList = XenPci_DOP_GetScatterGatherList;
 25.2359 +  xen_dma_adapter->dma_adapter.DmaOperations->PutScatterGatherList = XenPci_DOP_PutScatterGatherList;
 25.2360 +  xen_dma_adapter->dma_adapter.DmaOperations->CalculateScatterGatherList = XenPci_DOP_CalculateScatterGatherList;
 25.2361 +  xen_dma_adapter->dma_adapter.DmaOperations->BuildScatterGatherList = XenPci_DOP_BuildScatterGatherList;
 25.2362 +  xen_dma_adapter->dma_adapter.DmaOperations->BuildMdlFromScatterGatherList = XenPci_DOP_BuildMdlFromScatterGatherList;
 25.2363    xen_dma_adapter->xppdd = context;
 25.2364    xen_dma_adapter->dma_extension = NULL;
 25.2365  
 25.2366 +  KdPrint((__DRIVER_NAME "     About to call IoGetAttachedDeviceReference\n"));
 25.2367    curr = IoGetAttachedDeviceReference(xen_dma_adapter->xppdd->common.pdo);
 25.2368 +  KdPrint((__DRIVER_NAME "     Before start of loop - curr = %p\n", curr));
 25.2369    while (curr != NULL)
 25.2370    {
 25.2371      fdo_driver_object = curr->DriverObject;
 25.2372 @@ -1802,8 +3780,9 @@ XenPci_BIS_GetDmaAdapter(PVOID context, 
 25.2373      curr = IoGetLowerDeviceObject(curr);
 25.2374      ObDereferenceObject(prev);
 25.2375    }
 25.2376 -
 25.2377 -  *number_of_map_registers = 1024; /* why not... */
 25.2378 +  KdPrint((__DRIVER_NAME "     End of loop\n"));
 25.2379 +
 25.2380 +  *number_of_map_registers = 1024; //1024; /* why not... */
 25.2381  
 25.2382    FUNCTION_EXIT();
 25.2383  
 25.2384 @@ -2280,3 +4259,4 @@ XenPci_SystemControl_Pdo(PDEVICE_OBJECT 
 25.2385  
 25.2386    return status;
 25.2387  }
 25.2388 +#endif
 25.2389 \ No newline at end of file
    26.1 --- a/xenscsi/xenscsi.c	Tue Jan 27 00:47:02 2009 +1100
    26.2 +++ b/xenscsi/xenscsi.c	Sat Feb 14 13:35:48 2009 +1100
    26.3 @@ -232,14 +232,16 @@ XenScsi_WaitPause(PVOID DeviceExtension)
    26.4    LARGE_INTEGER wait_time;
    26.5  
    26.6    FUNCTION_ENTER();
    26.7 -  xsdd->vectors.EvtChn_Notify(xsdd->vectors.context, xsdd->vectors.pdo_event_channel);
    26.8 +#if 0
    26.9 +  xsdd->vectors.EvtChn_Notify(xsdd->vectors.context, xsdd->device_state->pdo_event_channel);
   26.10    while (xsdd->pause_ack != xsdd->pause_req)
   26.11    {
   26.12      KdPrint((__DRIVER_NAME "     Waiting...\n"));
   26.13      wait_time.QuadPart = -1 * 1000 * 10; /* 1ms */
   26.14      KeDelayExecutionThread(KernelMode, FALSE, &wait_time);
   26.15 -    xsdd->vectors.EvtChn_Notify(xsdd->vectors.context, xsdd->vectors.pdo_event_channel);
   26.16 +    xsdd->vectors.EvtChn_Notify(xsdd->vectors.context, xsdd->device_state->pdo_event_channel);
   26.17    }  
   26.18 +#endif
   26.19    FUNCTION_EXIT();
   26.20  }
   26.21  
   26.22 @@ -382,7 +384,7 @@ XenScsi_HwScsiFindAdapter(PVOID DeviceEx
   26.23    PACCESS_RANGE access_range;
   26.24    PUCHAR ptr;
   26.25    USHORT type;
   26.26 -  PCHAR setting, value;
   26.27 +  PCHAR setting, value, value2;
   26.28    vscsiif_sring_t *sring;
   26.29    CHAR path[128];
   26.30  
   26.31 @@ -431,7 +433,7 @@ XenScsi_HwScsiFindAdapter(PVOID DeviceEx
   26.32    }
   26.33    sring = NULL;
   26.34    xsdd->event_channel = 0;
   26.35 -  while((type = GET_XEN_INIT_RSP(&ptr, &setting, &value)) != XEN_INIT_TYPE_END)
   26.36 +  while((type = GET_XEN_INIT_RSP(&ptr, &setting, &value, &value2)) != XEN_INIT_TYPE_END)
   26.37    {
   26.38      switch(type)
   26.39      {
   26.40 @@ -806,11 +808,11 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   26.41  
   26.42    IoAllocateDriverObjectExtension(DriverObject, UlongToPtr(XEN_INIT_DRIVER_EXTENSION_MAGIC), PAGE_SIZE, &driver_extension);
   26.43    ptr = driver_extension;
   26.44 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL);
   26.45 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "ring-ref", NULL);
   26.46 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_IRQ, "event-channel", NULL);
   26.47 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_GRANT_ENTRIES, NULL, UlongToPtr(144));
   26.48 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL);       
   26.49 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL, NULL);
   26.50 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "ring-ref", NULL, NULL);
   26.51 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_IRQ, "event-channel", NULL, NULL);
   26.52 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_GRANT_ENTRIES, NULL, UlongToPtr(144), NULL);
   26.53 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
   26.54    /* RegistryPath == NULL when we are invoked as a crash dump driver */
   26.55    if (!RegistryPath)
   26.56    {
    27.1 --- a/xenstub/makefile.inc	Tue Jan 27 00:47:02 2009 +1100
    27.2 +++ b/xenstub/makefile.inc	Sat Feb 14 13:35:48 2009 +1100
    27.3 @@ -1,6 +1,6 @@
    27.4  _LNG=$(LANGUAGE)
    27.5  STAMP=stampinf -f $@ -a $(_BUILDARCH) -d * -v $(VERSION)
    27.6  
    27.7 -..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf: $(INF_NAME).inx sources ..\common.inc
    27.8 +$(INF_NAME).inf: $(INF_NAME).inx sources ..\common.inc
    27.9      copy $(@B).inx $@
   27.10      $(STAMP)
    28.1 --- a/xenstub/sources	Tue Jan 27 00:47:02 2009 +1100
    28.2 +++ b/xenstub/sources	Sat Feb 14 13:35:48 2009 +1100
    28.3 @@ -2,5 +2,5 @@
    28.4  TARGETNAME=xenstub
    28.5  TARGETTYPE=DRIVER
    28.6  INF_NAME=$(TARGETNAME)
    28.7 -MISCFILES=..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf
    28.8 +MISCFILES=$(INF_NAME).inf
    28.9  SOURCES=xenstub.c
    29.1 --- a/xenvbd/makefile.inc	Tue Jan 27 00:47:02 2009 +1100
    29.2 +++ b/xenvbd/makefile.inc	Sat Feb 14 13:35:48 2009 +1100
    29.3 @@ -1,6 +1,6 @@
    29.4  _LNG=$(LANGUAGE)
    29.5  STAMP=stampinf -f $@ -a $(_BUILDARCH) -d * -v $(VERSION)
    29.6  
    29.7 -..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf: $(INF_NAME).inx sources ..\common.inc
    29.8 +$(INF_NAME).inf: $(INF_NAME).inx sources ..\common.inc
    29.9      copy $(@B).inx $@
   29.10      $(STAMP)
    30.1 --- a/xenvbd/sources	Tue Jan 27 00:47:02 2009 +1100
    30.2 +++ b/xenvbd/sources	Sat Feb 14 13:35:48 2009 +1100
    30.3 @@ -4,6 +4,6 @@
    30.4  TARGETNAME=xenvbd
    30.5  TARGETTYPE=DRIVER
    30.6  INF_NAME=$(TARGETNAME)
    30.7 -MISCFILES=..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf
    30.8 +MISCFILES=$(INF_NAME).inf
    30.9  TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\scsiport.lib
   30.10  SOURCES=xenvbd.c
    31.1 --- a/xenvbd/xenvbd.c	Tue Jan 27 00:47:02 2009 +1100
    31.2 +++ b/xenvbd/xenvbd.c	Sat Feb 14 13:35:48 2009 +1100
    31.3 @@ -96,10 +96,13 @@ XenVbd_PutRequest(PXENVBD_DEVICE_DATA xv
    31.4  {
    31.5    blkif_other_request_t *other_req;
    31.6  
    31.7 -  //KdPrint((__DRIVER_NAME "     ring.sring->rsp_prod = %d\n", xvdd->ring.sring->rsp_prod));
    31.8 -  //KdPrint((__DRIVER_NAME "     ring.sring->rsp_event = %d\n", xvdd->ring.sring->rsp_event));
    31.9 -  //KdPrint((__DRIVER_NAME "     ring.rsp_cons = %d\n", xvdd->ring.rsp_cons));
   31.10 -  //KdPrint((__DRIVER_NAME "     ring.req_prod_pvt = %d\n", xvdd->ring.req_prod_pvt));
   31.11 +  if (dump_mode)
   31.12 +  {
   31.13 +    KdPrint((__DRIVER_NAME "     ring.sring->rsp_prod = %d\n", xvdd->ring.sring->rsp_prod));
   31.14 +    KdPrint((__DRIVER_NAME "     ring.sring->rsp_event = %d\n", xvdd->ring.sring->rsp_event));
   31.15 +    KdPrint((__DRIVER_NAME "     ring.rsp_cons = %d\n", xvdd->ring.rsp_cons));
   31.16 +    KdPrint((__DRIVER_NAME "     ring.req_prod_pvt = %d\n", xvdd->ring.req_prod_pvt));
   31.17 +  }
   31.18    if (!xvdd->use_other)
   31.19    {
   31.20      *RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt) = *req;
   31.21 @@ -127,7 +130,7 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
   31.22    ULONG i;
   31.23    PUCHAR ptr;
   31.24    USHORT type;
   31.25 -  PCHAR setting, value;
   31.26 +  PCHAR setting, value, value2;
   31.27    ULONG qemu_protocol_version = 0;
   31.28  
   31.29    xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
   31.30 @@ -136,7 +139,7 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
   31.31  
   31.32    xvdd->inactive = TRUE;  
   31.33    ptr = xvdd->device_base;
   31.34 -  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID) &setting, (PVOID) &value)) != XEN_INIT_TYPE_END)
   31.35 +  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
   31.36    {
   31.37      switch(type)
   31.38      {
   31.39 @@ -153,7 +156,7 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
   31.40        break;
   31.41      case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
   31.42      case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel */
   31.43 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value)));
   31.44 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value) & 0x3FFFFFFF));
   31.45        if (strcmp(setting, "event-channel") == 0)
   31.46        {
   31.47          /* cheat here - save the state of the ring in the topmost bits of the event-channel */
   31.48 @@ -232,6 +235,10 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
   31.49        break;
   31.50      case XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION:
   31.51        qemu_protocol_version = PtrToUlong(value);
   31.52 +      break;
   31.53 +    case XEN_INIT_TYPE_GRANT_ENTRIES:
   31.54 +      xvdd->dump_grant_ref = *(grant_ref_t *)value;
   31.55 +      break;
   31.56      default:
   31.57        KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
   31.58        break;
   31.59 @@ -345,6 +352,22 @@ decode_cdb_is_read(PSCSI_REQUEST_BLOCK s
   31.60    }
   31.61  }
   31.62  
   31.63 +static __forceinline PVOID
   31.64 +get_databuffer_virtual(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
   31.65 +{
   31.66 +  ULONG data_buffer_length;
   31.67 +  
   31.68 +  if (!dump_mode)
   31.69 +  {
   31.70 +    return LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
   31.71 +  }
   31.72 +  else
   31.73 +  {
   31.74 +    /* in dump mode, we can count on srb->DataBuffer being the virtual address we want */
   31.75 +    return srb->DataBuffer;
   31.76 +  }
   31.77 +}
   31.78 +
   31.79  static VOID
   31.80  XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
   31.81  {
   31.82 @@ -378,24 +401,45 @@ XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA 
   31.83    //KdPrint((__DRIVER_NAME "     sector_number = %d\n", (ULONG)shadow->req.sector_number));
   31.84    //KdPrint((__DRIVER_NAME "     handle = %d\n", shadow->req.handle));
   31.85    //KdPrint((__DRIVER_NAME "     operation = %d\n", shadow->req.operation));
   31.86 -    
   31.87 -  while (remaining > 0)
   31.88 +  if (!dump_mode)
   31.89 +  {
   31.90 +    while (remaining > 0)
   31.91 +    {
   31.92 +      PHYSICAL_ADDRESS physical_address;
   31.93 +      physical_address = ScsiPortGetPhysicalAddress(xvdd, srb, ptr, &length);
   31.94 +      offset = physical_address.LowPart & (PAGE_SIZE - 1);
   31.95 +      ASSERT((offset & 511) == 0);
   31.96 +      //length = min(PAGE_SIZE - offset, remaining);
   31.97 +      //KdPrint((__DRIVER_NAME "     length(a) = %d\n", length));
   31.98 +      shadow->req.seg[shadow->req.nr_segments].gref = (grant_ref_t)(physical_address.QuadPart >> PAGE_SHIFT);
   31.99 +      //KdPrint((__DRIVER_NAME "     length(b) = %d\n", length));
  31.100 +      shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset >> 9);
  31.101 +      shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) >> 9) - 1);
  31.102 +      remaining -= length;
  31.103 +      ptr += length;
  31.104 +      //KdPrint((__DRIVER_NAME "     seg[%d].gref = %d\n", shadow->req.nr_segments, shadow->req.seg[shadow->req.nr_segments].gref));
  31.105 +      //KdPrint((__DRIVER_NAME "     seg[%d].first_sect = %d\n", shadow->req.nr_segments, shadow->req.seg[shadow->req.nr_segments].first_sect));
  31.106 +      //KdPrint((__DRIVER_NAME "     seg[%d].last_sect = %d\n", shadow->req.nr_segments, shadow->req.seg[shadow->req.nr_segments].last_sect));
  31.107 +      shadow->req.nr_segments++;
  31.108 +    }
  31.109 +  }
  31.110 +  else
  31.111    {
  31.112      PHYSICAL_ADDRESS physical_address;
  31.113 +    //KdPrint((__DRIVER_NAME "     remaining = %d\n", remaining));
  31.114 +    ASSERT(remaining <= PAGE_SIZE); /* one page at a time in dump mode */
  31.115      physical_address = ScsiPortGetPhysicalAddress(xvdd, srb, ptr, &length);
  31.116      offset = physical_address.LowPart & (PAGE_SIZE - 1);
  31.117 -    ASSERT((offset & 511) == 0);
  31.118 -    //length = min(PAGE_SIZE - offset, remaining);
  31.119 -    //KdPrint((__DRIVER_NAME "     length(a) = %d\n", length));
  31.120 -    shadow->req.seg[shadow->req.nr_segments].gref = (grant_ref_t)(physical_address.QuadPart >> PAGE_SHIFT);
  31.121 -    //KdPrint((__DRIVER_NAME "     length(b) = %d\n", length));
  31.122 +    ASSERT(offset == 0);
  31.123 +    //ASSERT((offset & 511) == 0);
  31.124 +    shadow->req.seg[shadow->req.nr_segments].gref = 
  31.125 +      (grant_ref_t)xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0,
  31.126 +      (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, xvdd->dump_grant_ref);
  31.127 +    //KdPrint((__DRIVER_NAME "     gref = %d, dump_grant_ref = %d\n",
  31.128 +    //  shadow->req.seg[shadow->req.nr_segments].gref, xvdd->dump_grant_ref));
  31.129      shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset >> 9);
  31.130 -    shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) >> 9) - 1);
  31.131 +    shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + remaining) >> 9) - 1);
  31.132      remaining -= length;
  31.133 -    ptr += length;
  31.134 -    //KdPrint((__DRIVER_NAME "     seg[%d].gref = %d\n", shadow->req.nr_segments, shadow->req.seg[shadow->req.nr_segments].gref));
  31.135 -    //KdPrint((__DRIVER_NAME "     seg[%d].first_sect = %d\n", shadow->req.nr_segments, shadow->req.seg[shadow->req.nr_segments].first_sect));
  31.136 -    //KdPrint((__DRIVER_NAME "     seg[%d].last_sect = %d\n", shadow->req.nr_segments, shadow->req.seg[shadow->req.nr_segments].last_sect));
  31.137      shadow->req.nr_segments++;
  31.138    }
  31.139    //KdPrint((__DRIVER_NAME "     nr_segments = %d\n", shadow->req.nr_segments));
  31.140 @@ -415,44 +459,22 @@ XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA 
  31.141    //FUNCTION_EXIT();
  31.142  }
  31.143  
  31.144 -typedef struct {
  31.145 -  PSCSI_REQUEST_BLOCK srb;
  31.146 -  ULONG offset;
  31.147 -} mini_shadow_t;
  31.148 -
  31.149 +#if 0
  31.150  static VOID
  31.151  XenVbd_Resume(PVOID DeviceExtension)
  31.152  {
  31.153    PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
  31.154    ULONG i;
  31.155 -  mini_shadow_t shadows[MAX_SHADOW_ENTRIES];
  31.156 -  ULONG shadow_count;
  31.157  
  31.158    FUNCTION_ENTER();
  31.159    KdPrint((__DRIVER_NAME "     found device in resume state\n"));
  31.160    //FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE); what was this for???
  31.161    // re-submit srb's
  31.162    
  31.163 -  shadow_count = 0;
  31.164 -  for (i = 0; i < SHADOW_ENTRIES; i++)
  31.165 -  {
  31.166 -    if (xvdd->shadows[i].srb)
  31.167 -    {
  31.168 -      shadows[shadow_count].srb = xvdd->shadows[i].srb;
  31.169 -      shadow_count++;
  31.170 -      xvdd->shadows[i].srb = NULL;
  31.171 -    }      
  31.172 -  }
  31.173  KdPrint((__DRIVER_NAME "     About to call InitFromConfig\n"));
  31.174    XenVbd_InitFromConfig(xvdd);
  31.175  KdPrint((__DRIVER_NAME "     Back from InitFromConfig\n"));
  31.176    
  31.177 -  for (i = 0; i < shadow_count; i++)
  31.178 -  {
  31.179 -KdPrint((__DRIVER_NAME "     Putting on Shadow entry\n"));
  31.180 -    XenVbd_PutSrbOnRing(xvdd, shadows[i].srb);
  31.181 -  }
  31.182 -KdPrint((__DRIVER_NAME "     Shadows are back on the ring\n"));
  31.183    
  31.184    xvdd->device_state->resume_state = RESUME_STATE_RUNNING;
  31.185  
  31.186 @@ -466,6 +488,7 @@ KdPrint((__DRIVER_NAME "     No shadows 
  31.187    }
  31.188    FUNCTION_EXIT();
  31.189  }
  31.190 +#endif
  31.191  
  31.192  static ULONG DDKAPI
  31.193  XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
  31.194 @@ -480,7 +503,7 @@ XenVbd_HwScsiFindAdapter(PVOID DeviceExt
  31.195    UNREFERENCED_PARAMETER(BusInformation);
  31.196    UNREFERENCED_PARAMETER(ArgumentString);
  31.197  
  31.198 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));  
  31.199 +  FUNCTION_ENTER(); 
  31.200    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  31.201  
  31.202    *Again = FALSE;
  31.203 @@ -507,17 +530,29 @@ XenVbd_HwScsiFindAdapter(PVOID DeviceExt
  31.204    if (!xvdd->device_base)
  31.205    {
  31.206      KdPrint((__DRIVER_NAME "     Invalid config\n"));
  31.207 -    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
  31.208 +    FUNCTION_EXIT(); 
  31.209      return SP_RETURN_BAD_CONFIG;
  31.210    }
  31.211    
  31.212    status = XenVbd_InitFromConfig(xvdd);
  31.213    if (status != SP_RETURN_FOUND)
  31.214 +  {
  31.215 +    FUNCTION_EXIT();
  31.216      return status;
  31.217 -  
  31.218 -  ConfigInfo->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
  31.219 -  ConfigInfo->NumberOfPhysicalBreaks = BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
  31.220 -  ConfigInfo->ScatterGather = TRUE;
  31.221 +  }
  31.222 +
  31.223 +  if (dump_mode)
  31.224 +  {
  31.225 +    ConfigInfo->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
  31.226 +    ConfigInfo->NumberOfPhysicalBreaks = BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
  31.227 +    ConfigInfo->ScatterGather = TRUE;
  31.228 +  }
  31.229 +  else
  31.230 +  {
  31.231 +    ConfigInfo->MaximumTransferLength = 4096;
  31.232 +    ConfigInfo->NumberOfPhysicalBreaks = 0;
  31.233 +    ConfigInfo->ScatterGather = FALSE;
  31.234 +  }
  31.235    ConfigInfo->AlignmentMask = 0;
  31.236    ConfigInfo->NumberOfBuses = 1;
  31.237    ConfigInfo->InitiatorBusId[0] = 1;
  31.238 @@ -538,7 +573,7 @@ XenVbd_HwScsiFindAdapter(PVOID DeviceExt
  31.239      KdPrint((__DRIVER_NAME "     Dma64BitAddresses not supported\n"));
  31.240    }
  31.241  
  31.242 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
  31.243 +  FUNCTION_EXIT();
  31.244  
  31.245    return SP_RETURN_FOUND;
  31.246  }
  31.247 @@ -612,13 +647,14 @@ XenVbd_FillModePage(PXENVBD_DEVICE_DATA 
  31.248    UCHAR cdb_page_code;
  31.249    USHORT cdb_allocation_length;
  31.250    PVOID data_buffer;
  31.251 -  ULONG data_buffer_length;
  31.252 +  //ULONG data_buffer_length;
  31.253  
  31.254    UNREFERENCED_PARAMETER(xvdd);
  31.255  
  31.256    //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  31.257    
  31.258 -  data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
  31.259 +  //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
  31.260 +  data_buffer = get_databuffer_virtual(xvdd, srb);
  31.261    //cdb = (PCDB)srb->Cdb;
  31.262    switch (srb->Cdb[0])
  31.263    {
  31.264 @@ -756,35 +792,44 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
  31.265    int block_count;
  31.266    int more_to_do = TRUE;
  31.267    blkif_shadow_t *shadow;
  31.268 +  ULONG suspend_resume_state_pdo;
  31.269  
  31.270    /* in dump mode I think we get called on a timer, not by an actual IRQ */
  31.271    if (!dump_mode && !xvdd->vectors.EvtChn_AckEvent(xvdd->vectors.context, xvdd->event_channel))
  31.272      return FALSE; /* interrupt was not for us */
  31.273 +    
  31.274 +  suspend_resume_state_pdo = xvdd->device_state->suspend_resume_state_pdo;
  31.275 +  KeMemoryBarrier();
  31.276  
  31.277 -  //FUNCTION_ENTER();
  31.278 -
  31.279 -  if (xvdd->device_state->resume_state != xvdd->device_state->resume_state_ack)
  31.280 +  if (suspend_resume_state_pdo != xvdd->device_state->suspend_resume_state_fdo)
  31.281    {
  31.282      FUNCTION_ENTER();
  31.283 -    switch (xvdd->device_state->resume_state)
  31.284 +    switch (suspend_resume_state_pdo)
  31.285      {
  31.286 -      case RESUME_STATE_SUSPENDING:
  31.287 -        KdPrint((__DRIVER_NAME "     New state SUSPENDING\n"));
  31.288 +      case SR_STATE_SUSPENDING:
  31.289 +        KdPrint((__DRIVER_NAME "     New pdo state SR_STATE_SUSPENDING\n"));
  31.290          break;
  31.291 -      case RESUME_STATE_FRONTEND_RESUME:
  31.292 -        KdPrint((__DRIVER_NAME "     New state RESUME_STATE_FRONTEND_RESUME\n"));
  31.293 -        XenVbd_Resume(xvdd);
  31.294 +      case SR_STATE_RESUMING:
  31.295 +        KdPrint((__DRIVER_NAME "     New pdo state SR_STATE_RESUMING\n"));
  31.296 +        XenVbd_InitFromConfig(xvdd);
  31.297 +        xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
  31.298 +        xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
  31.299          break;
  31.300 +      case SR_STATE_RUNNING:
  31.301 +        KdPrint((__DRIVER_NAME "     New pdo state %d\n", suspend_resume_state_pdo));
  31.302 +        xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
  31.303 +        xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
  31.304 +        ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  31.305        default:
  31.306 -        KdPrint((__DRIVER_NAME "     New state %d\n", xvdd->device_state->resume_state));
  31.307 +        KdPrint((__DRIVER_NAME "     New pdo state %d\n", suspend_resume_state_pdo));
  31.308 +        xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
  31.309 +        xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
  31.310          break;
  31.311      }
  31.312 -    xvdd->device_state->resume_state_ack = xvdd->device_state->resume_state;
  31.313      KeMemoryBarrier();
  31.314 -    FUNCTION_EXIT();
  31.315    }
  31.316  
  31.317 -  if (xvdd->device_state->resume_state != RESUME_STATE_RUNNING)
  31.318 +  if (xvdd->device_state->suspend_resume_state_fdo != SR_STATE_RUNNING)
  31.319    {
  31.320      return FALSE;
  31.321    }
  31.322 @@ -828,7 +873,8 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
  31.323          ScsiPortNotification(NextRequest, DeviceExtension);
  31.324          break;
  31.325        case 2:
  31.326 -        //KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, rep->operation, rep->id, rep->status));
  31.327 +        if (dump_mode)
  31.328 +          KdPrint((__DRIVER_NAME "     rep->id = %d\n", rep->id));
  31.329          shadow = &xvdd->shadows[rep->id];
  31.330          srb = shadow->srb;
  31.331          ASSERT(srb != NULL);
  31.332 @@ -850,10 +896,19 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
  31.333            xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
  31.334            XenVbd_MakeAutoSense(xvdd, srb);
  31.335          }
  31.336 -
  31.337          put_shadow_on_freelist(xvdd, shadow);
  31.338 +        if (dump_mode)
  31.339 +        {
  31.340 +          ASSERT(shadow->req.nr_segments == 1);
  31.341 +          //KdPrint((__DRIVER_NAME "     gref = %d, dump_grant_ref = %d\n",
  31.342 +          //  shadow->req.seg[0].gref, xvdd->dump_grant_ref));
  31.343 +          ASSERT(shadow->req.seg[0].gref == xvdd->dump_grant_ref);
  31.344 +          xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
  31.345 +            shadow->req.seg[0].gref, TRUE);
  31.346 +        }
  31.347          ScsiPortNotification(RequestComplete, xvdd, srb);
  31.348 -        ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  31.349 +        if (suspend_resume_state_pdo == SR_STATE_RUNNING)
  31.350 +          ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  31.351          break;
  31.352        }
  31.353      }
  31.354 @@ -870,13 +925,24 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
  31.355      }
  31.356    }
  31.357  
  31.358 +  if (suspend_resume_state_pdo == SR_STATE_SUSPENDING)
  31.359 +  {
  31.360 +    if (xvdd->shadow_free == SHADOW_ENTRIES)
  31.361 +    {
  31.362 +      /* all entries are purged from the list. ready to suspend */
  31.363 +      xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
  31.364 +      KeMemoryBarrier();
  31.365 +      KdPrint((__DRIVER_NAME "     Set fdo state SR_STATE_SUSPENDING\n"));
  31.366 +      KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xvdd->device_state->pdo_event_channel));
  31.367 +      xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
  31.368 +    }
  31.369 +    FUNCTION_EXIT();
  31.370 +  }
  31.371    //KdPrint((__DRIVER_NAME "     ring.sring->rsp_prod = %d\n", xvdd->ring.sring->rsp_prod));
  31.372    //KdPrint((__DRIVER_NAME "     ring.sring->rsp_event = %d\n", xvdd->ring.sring->rsp_event));
  31.373    //KdPrint((__DRIVER_NAME "     ring.rsp_cons = %d\n", xvdd->ring.rsp_cons));
  31.374    //KdPrint((__DRIVER_NAME "     ring.req_prod_pvt = %d\n", xvdd->ring.req_prod_pvt));
  31.375  
  31.376 -  //FUNCTION_EXIT();
  31.377 -
  31.378    return FALSE; /* always fall through to the next ISR... */
  31.379  }
  31.380  
  31.381 @@ -884,7 +950,7 @@ static BOOLEAN DDKAPI
  31.382  XenVbd_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
  31.383  {
  31.384    PUCHAR data_buffer;
  31.385 -  ULONG data_buffer_length;
  31.386 +  //ULONG data_buffer_length;
  31.387    PCDB cdb;
  31.388    PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
  31.389  
  31.390 @@ -907,7 +973,7 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  31.391      return TRUE;
  31.392    }
  31.393  
  31.394 -  if (xvdd->device_state->resume_state != RESUME_STATE_RUNNING)
  31.395 +  if (xvdd->device_state->suspend_resume_state_pdo != SR_STATE_RUNNING)
  31.396    {
  31.397      KdPrint((__DRIVER_NAME " --> HwScsiStartIo (Resuming)\n"));
  31.398      Srb->SrbStatus = SRB_STATUS_BUSY;
  31.399 @@ -929,21 +995,29 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  31.400    {
  31.401    case SRB_FUNCTION_EXECUTE_SCSI:
  31.402      cdb = (PCDB)Srb->Cdb;
  31.403 -//    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_EXECUTE_SCSI\n"));
  31.404  
  31.405      switch(cdb->CDB6GENERIC.OperationCode)
  31.406      {
  31.407      case SCSIOP_TEST_UNIT_READY:
  31.408 -      //KdPrint((__DRIVER_NAME "     Command = TEST_UNIT_READY\n"));
  31.409 +      if (dump_mode)
  31.410 +        KdPrint((__DRIVER_NAME "     Command = TEST_UNIT_READY\n"));
  31.411        Srb->SrbStatus = SRB_STATUS_SUCCESS;
  31.412        Srb->ScsiStatus = 0;
  31.413        break;
  31.414      case SCSIOP_INQUIRY:
  31.415 -//      KdPrint((__DRIVER_NAME "     Command = INQUIRY\n"));
  31.416 +      if (dump_mode)
  31.417 +      {
  31.418 +        //PHYSICAL_ADDRESS physical;
  31.419 +        KdPrint((__DRIVER_NAME "     Command = INQUIRY\n"));
  31.420 +        //KdPrint((__DRIVER_NAME "     Srb->Databuffer = %p\n", Srb->DataBuffer));
  31.421 +        //physical = ScsiPortGetPhysicalAddress(xvdd, Srb, Srb->DataBuffer, &data_buffer_length);
  31.422 +        //KdPrint((__DRIVER_NAME "     ScsiPortGetPhysicalAddress = %08x:%08x\n", physical.LowPart, physical.HighPart));
  31.423 +      }
  31.424  //      KdPrint((__DRIVER_NAME "     (LUN = %d, EVPD = %d, Page Code = %02X)\n", Srb->Cdb[1] >> 5, Srb->Cdb[1] & 1, Srb->Cdb[2]));
  31.425  //      KdPrint((__DRIVER_NAME "     (Length = %d)\n", Srb->DataTransferLength));
  31.426 -//      KdPrint((__DRIVER_NAME "     (Srb->Databuffer = %08x)\n", Srb->DataBuffer));
  31.427 -      data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, Srb, Srb->DataBuffer, &data_buffer_length).QuadPart);
  31.428 +      
  31.429 +      //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, Srb, Srb->DataBuffer, &data_buffer_length).QuadPart);
  31.430 +      data_buffer = get_databuffer_virtual(xvdd, Srb);
  31.431        RtlZeroMemory(data_buffer, Srb->DataTransferLength);
  31.432        Srb->SrbStatus = SRB_STATUS_SUCCESS;
  31.433        switch (xvdd->device_type)
  31.434 @@ -1041,11 +1115,13 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  31.435        }
  31.436        break;
  31.437      case SCSIOP_READ_CAPACITY:
  31.438 -      //KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
  31.439 +      if (dump_mode)
  31.440 +        KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
  31.441        //KdPrint((__DRIVER_NAME "       LUN = %d, RelAdr = %d\n", Srb->Cdb[1] >> 4, Srb->Cdb[1] & 1));
  31.442        //KdPrint((__DRIVER_NAME "       LBA = %02x%02x%02x%02x\n", Srb->Cdb[2], Srb->Cdb[3], Srb->Cdb[4], Srb->Cdb[5]));
  31.443        //KdPrint((__DRIVER_NAME "       PMI = %d\n", Srb->Cdb[8] & 1));
  31.444 -      data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, Srb, Srb->DataBuffer, &data_buffer_length).QuadPart);
  31.445 +      //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, Srb, Srb->DataBuffer, &data_buffer_length).QuadPart);
  31.446 +      data_buffer = get_databuffer_virtual(xvdd, Srb);
  31.447        RtlZeroMemory(data_buffer, Srb->DataTransferLength);
  31.448        if ((xvdd->total_sectors - 1) >> 32)
  31.449        {
  31.450 @@ -1069,11 +1145,13 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  31.451        Srb->SrbStatus = SRB_STATUS_SUCCESS;
  31.452        break;
  31.453      case SCSIOP_READ_CAPACITY16:
  31.454 -      //KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
  31.455 +      if (dump_mode)
  31.456 +        KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
  31.457        //KdPrint((__DRIVER_NAME "       LUN = %d, RelAdr = %d\n", Srb->Cdb[1] >> 4, Srb->Cdb[1] & 1));
  31.458        //KdPrint((__DRIVER_NAME "       LBA = %02x%02x%02x%02x\n", Srb->Cdb[2], Srb->Cdb[3], Srb->Cdb[4], Srb->Cdb[5]));
  31.459        //KdPrint((__DRIVER_NAME "       PMI = %d\n", Srb->Cdb[8] & 1));
  31.460 -      data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, Srb, Srb->DataBuffer, &data_buffer_length).QuadPart);
  31.461 +      //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, Srb, Srb->DataBuffer, &data_buffer_length).QuadPart);
  31.462 +      data_buffer = get_databuffer_virtual(xvdd, Srb);
  31.463        RtlZeroMemory(data_buffer, Srb->DataTransferLength);
  31.464        data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 56) & 0xff;
  31.465        data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 48) & 0xff;
  31.466 @@ -1092,32 +1170,40 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  31.467        break;
  31.468      case SCSIOP_MODE_SENSE:
  31.469      case SCSIOP_MODE_SENSE10:
  31.470 -//      KdPrint((__DRIVER_NAME "     Command = MODE_SENSE (DBD = %d, PC = %d, Page Code = %02x)\n", Srb->Cdb[1] & 0x08, Srb->Cdb[2] & 0xC0, Srb->Cdb[2] & 0x3F));
  31.471 +      if (dump_mode)
  31.472 +        KdPrint((__DRIVER_NAME "     Command = MODE_SENSE (DBD = %d, PC = %d, Page Code = %02x)\n", Srb->Cdb[1] & 0x08, Srb->Cdb[2] & 0xC0, Srb->Cdb[2] & 0x3F));
  31.473        XenVbd_FillModePage(xvdd, Srb);
  31.474        break;
  31.475      case SCSIOP_READ:
  31.476      case SCSIOP_READ16:
  31.477      case SCSIOP_WRITE:
  31.478      case SCSIOP_WRITE16:
  31.479 -//      KdPrint((__DRIVER_NAME "     Command = READ/WRITE\n"));
  31.480 +      //if (dump_mode)
  31.481 +      //  KdPrint((__DRIVER_NAME "     Command = READ/WRITE\n"));
  31.482        XenVbd_PutSrbOnRing(xvdd, Srb);
  31.483        break;
  31.484      case SCSIOP_VERIFY:
  31.485        // Should we do more here?
  31.486 -//      KdPrint((__DRIVER_NAME "     Command = VERIFY\n"));
  31.487 +      if (dump_mode)
  31.488 +        KdPrint((__DRIVER_NAME "     Command = VERIFY\n"));
  31.489        Srb->SrbStatus = SRB_STATUS_SUCCESS;
  31.490        break;
  31.491      case SCSIOP_REPORT_LUNS:
  31.492 -//      KdPrint((__DRIVER_NAME "     Command = REPORT_LUNS\n"));
  31.493 +      if (dump_mode)
  31.494 +        KdPrint((__DRIVER_NAME "     Command = REPORT_LUNS\n"));
  31.495        Srb->SrbStatus = SRB_STATUS_SUCCESS;;
  31.496        break;
  31.497      case SCSIOP_REQUEST_SENSE:
  31.498 -//      KdPrint((__DRIVER_NAME "     Command = REQUEST_SENSE\n"));
  31.499 +      if (dump_mode)
  31.500 +        KdPrint((__DRIVER_NAME "     Command = REQUEST_SENSE\n"));
  31.501        XenVbd_MakeSense(xvdd, Srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
  31.502        Srb->SrbStatus = SRB_STATUS_SUCCESS;
  31.503        break;      
  31.504      case SCSIOP_READ_TOC:
  31.505 -      data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, Srb, Srb->DataBuffer, &data_buffer_length).QuadPart);
  31.506 +      if (dump_mode)
  31.507 +        KdPrint((__DRIVER_NAME "     Command = READ_TOC\n"));
  31.508 +      //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, Srb, Srb->DataBuffer, &data_buffer_length).QuadPart);
  31.509 +      data_buffer = get_databuffer_virtual(xvdd, Srb);
  31.510  //      DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
  31.511  /*
  31.512  #define READ_TOC_FORMAT_TOC         0x00
  31.513 @@ -1126,7 +1212,6 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  31.514  #define READ_TOC_FORMAT_PMA         0x03
  31.515  #define READ_TOC_FORMAT_ATIP        0x04
  31.516  */
  31.517 -//      KdPrint((__DRIVER_NAME "     Command = READ_TOC\n"));
  31.518  //      KdPrint((__DRIVER_NAME "     Msf = %d\n", cdb->READ_TOC.Msf));
  31.519  //      KdPrint((__DRIVER_NAME "     LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
  31.520  //      KdPrint((__DRIVER_NAME "     Format2 = %d\n", cdb->READ_TOC.Format2));
  31.521 @@ -1160,15 +1245,18 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  31.522        }
  31.523        break;
  31.524      case SCSIOP_START_STOP_UNIT:
  31.525 -//      KdPrint((__DRIVER_NAME "     Command = SCSIOP_START_STOP_UNIT\n"));
  31.526 +      if (dump_mode)
  31.527 +        KdPrint((__DRIVER_NAME "     Command = SCSIOP_START_STOP_UNIT\n"));
  31.528        Srb->SrbStatus = SRB_STATUS_SUCCESS;
  31.529        break;
  31.530      case SCSIOP_RESERVE_UNIT:
  31.531 -//      KdPrint((__DRIVER_NAME "     Command = SCSIOP_RESERVE_UNIT\n"));
  31.532 +      if (dump_mode)
  31.533 +        KdPrint((__DRIVER_NAME "     Command = SCSIOP_RESERVE_UNIT\n"));
  31.534        Srb->SrbStatus = SRB_STATUS_SUCCESS;
  31.535        break;
  31.536      case SCSIOP_RELEASE_UNIT:
  31.537 -//      KdPrint((__DRIVER_NAME "     Command = SCSIOP_RELEASE_UNIT\n"));
  31.538 +      if (dump_mode)
  31.539 +        KdPrint((__DRIVER_NAME "     Command = SCSIOP_RELEASE_UNIT\n"));
  31.540        Srb->SrbStatus = SRB_STATUS_SUCCESS;
  31.541        break;
  31.542      default:
  31.543 @@ -1178,7 +1266,7 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  31.544      }
  31.545      if (Srb->SrbStatus == SRB_STATUS_ERROR)
  31.546      {
  31.547 -      //KdPrint((__DRIVER_NAME "     EXECUTE_SCSI Command = %02X returned error %02x\n", Srb->Cdb[0], xvdd->last_sense_key));
  31.548 +      KdPrint((__DRIVER_NAME "     EXECUTE_SCSI Command = %02X returned error %02x\n", Srb->Cdb[0], xvdd->last_sense_key));
  31.549        if (xvdd->last_sense_key == SCSI_SENSE_NO_SENSE)
  31.550        {
  31.551          xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
  31.552 @@ -1187,37 +1275,50 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  31.553        Srb->ScsiStatus = 0x02;
  31.554        XenVbd_MakeAutoSense(xvdd, Srb);
  31.555        ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  31.556 -      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  31.557 +      if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
  31.558 +        ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  31.559      }
  31.560      else if (Srb->SrbStatus != SRB_STATUS_PENDING)
  31.561      {
  31.562        xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
  31.563        xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
  31.564        ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  31.565 -      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  31.566 +      if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
  31.567 +        ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  31.568      }
  31.569      break;
  31.570    case SRB_FUNCTION_IO_CONTROL:
  31.571      //KdPrint((__DRIVER_NAME "     SRB_FUNCTION_IO_CONTROL\n"));
  31.572      Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  31.573      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  31.574 -    ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  31.575 +    if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
  31.576 +      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  31.577      break;
  31.578    case SRB_FUNCTION_FLUSH:
  31.579 -    //KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH\n"));
  31.580 -    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  31.581 +    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH\n"));
  31.582 +    Srb->SrbStatus = SRB_STATUS_SUCCESS;
  31.583      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  31.584 -    ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  31.585 +    if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
  31.586 +      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  31.587 +    break;
  31.588 +  case SRB_FUNCTION_SHUTDOWN:
  31.589 +    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_SHUTDOWN %p\n", Srb));
  31.590 +    Srb->SrbStatus = SRB_STATUS_SUCCESS;
  31.591 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  31.592 +    if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
  31.593 +      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  31.594      break;
  31.595    default:
  31.596      KdPrint((__DRIVER_NAME "     Unhandled Srb->Function = %08X\n", Srb->Function));
  31.597      Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  31.598      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  31.599 -    ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  31.600 +    if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
  31.601 +      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  31.602      break;
  31.603    }
  31.604  
  31.605 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  31.606 +  if (dump_mode)
  31.607 +    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  31.608    return TRUE;
  31.609  }
  31.610  
  31.611 @@ -1232,7 +1333,7 @@ XenVbd_HwScsiResetBus(PVOID DeviceExtens
  31.612    KdPrint((__DRIVER_NAME " --> HwScsiResetBus\n"));
  31.613  
  31.614    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  31.615 -  if (xvdd->ring_detect_state == 2 && xvdd->device_state->resume_state == RESUME_STATE_RUNNING)
  31.616 +  if (xvdd->ring_detect_state == 2 && xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
  31.617    {
  31.618      ScsiPortNotification(NextRequest, DeviceExtension);
  31.619    }
  31.620 @@ -1267,7 +1368,7 @@ XenVbd_HwScsiAdapterControl(PVOID Device
  31.621  
  31.622    UNREFERENCED_PARAMETER(DeviceExtension);
  31.623  
  31.624 -  KdPrint((__DRIVER_NAME " --> HwScsiAdapterControl\n"));
  31.625 +  FUNCTION_ENTER();
  31.626    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  31.627  
  31.628    switch (ControlType)
  31.629 @@ -1297,8 +1398,8 @@ XenVbd_HwScsiAdapterControl(PVOID Device
  31.630      break;
  31.631    }
  31.632  
  31.633 -  KdPrint((__DRIVER_NAME " <-- HwScsiAdapterControl\n"));
  31.634 -
  31.635 +  FUNCTION_EXIT();
  31.636 +  
  31.637    return Status;
  31.638  }
  31.639  
  31.640 @@ -1314,7 +1415,7 @@ XenVbd_DmaNeedVirtualAddress(PIRP irp)
  31.641    stack = IoGetCurrentIrpStackLocation(irp);
  31.642    if (stack->MajorFunction != IRP_MJ_SCSI)
  31.643    {
  31.644 -    //KdPrint((__DRIVER_NAME "     Not IRP_MJ_SCSI\n"));
  31.645 +    KdPrint((__DRIVER_NAME "     Not IRP_MJ_SCSI\n"));
  31.646      //FUNCTION_EXIT();
  31.647      return FALSE; /* this actually shouldn't happen */
  31.648    }
  31.649 @@ -1340,6 +1441,8 @@ XenVbd_DmaGetAlignment(PIRP irp)
  31.650  {
  31.651    UNREFERENCED_PARAMETER(irp);
  31.652    
  31.653 +  //FUNCTION_ENTER();
  31.654 +  //FUNCTION_EXIT();
  31.655    return 512;
  31.656  }
  31.657  
  31.658 @@ -1367,14 +1470,15 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
  31.659    {
  31.660      IoAllocateDriverObjectExtension(DriverObject, UlongToPtr(XEN_INIT_DRIVER_EXTENSION_MAGIC), PAGE_SIZE, &driver_extension);
  31.661      ptr = driver_extension;
  31.662 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL);
  31.663 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "ring-ref", NULL);
  31.664 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_IRQ, "event-channel", NULL);
  31.665 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_FRONT, "device-type", NULL);
  31.666 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "mode", NULL);
  31.667 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sectors", NULL);
  31.668 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sector-size", NULL);
  31.669 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL);       
  31.670 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL, NULL);
  31.671 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "ring-ref", NULL, NULL);
  31.672 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_IRQ, "event-channel", NULL, NULL);
  31.673 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_FRONT, "device-type", NULL, NULL);
  31.674 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "mode", NULL, NULL);
  31.675 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sectors", NULL, NULL);
  31.676 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sector-size", NULL, NULL);
  31.677 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_GRANT_ENTRIES, NULL, ULongToPtr(1), NULL); /* 1 ref for use in crash dump */
  31.678 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
  31.679  
  31.680      IoAllocateDriverObjectExtension(DriverObject, UlongToPtr(XEN_DMA_DRIVER_EXTENSION_MAGIC), sizeof(dma_driver_extension), &dma_driver_extension);  
  31.681      dma_driver_extension->need_virtual_address = XenVbd_DmaNeedVirtualAddress;
  31.682 @@ -1387,8 +1491,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
  31.683    HwInitializationData.AdapterInterfaceType = PNPBus;
  31.684    HwInitializationData.DeviceExtensionSize = sizeof(XENVBD_DEVICE_DATA);
  31.685    HwInitializationData.SpecificLuExtensionSize = 0;
  31.686 -  /* SrbExtension is not always aligned to a page boundary, so we add PAGE_SIZE-1 to it to make sure we have at least UNALIGNED_DOUBLE_BUFFER_SIZE bytes of page aligned memory */
  31.687 -  HwInitializationData.SrbExtensionSize = 0; //UNALIGNED_DOUBLE_BUFFER_SIZE + PAGE_SIZE - 1;
  31.688 +  HwInitializationData.SrbExtensionSize = 0;
  31.689    HwInitializationData.NumberOfAccessRanges = 1;
  31.690  #if 0
  31.691    HwInitializationData.MapBuffers = TRUE;
  31.692 @@ -1415,6 +1518,11 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
  31.693    HwInitializationData.HwAdapterState = XenVbd_HwScsiAdapterState;
  31.694    HwInitializationData.HwAdapterControl = XenVbd_HwScsiAdapterControl;
  31.695  
  31.696 +#if 0
  31.697 +  if (dump_mode)
  31.698 +    KdBreakPoint();
  31.699 +#endif
  31.700 +
  31.701    status = ScsiPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
  31.702    
  31.703    if(!NT_SUCCESS(status))
    32.1 --- a/xenvbd/xenvbd.h	Tue Jan 27 00:47:02 2009 +1100
    32.2 +++ b/xenvbd/xenvbd.h	Sat Feb 14 13:35:48 2009 +1100
    32.3 @@ -133,6 +133,7 @@ struct
    32.4    XENPCI_VECTORS vectors;
    32.5    PXENPCI_DEVICE_STATE device_state;
    32.6    PSCSI_REQUEST_BLOCK pending_srb;
    32.7 +  grant_ref_t dump_grant_ref;
    32.8  /*  
    32.9    ULONGLONG interrupts;
   32.10    ULONGLONG aligned_requests;