win-pvdrivers

changeset 1005:4f7d5a8636bd

xenvbd rewrite. combined scsiport and storport code where possible.
author James Harper <james.harper@bendigoit.com.au>
date Sat Feb 02 18:51:07 2013 +1100 (2013-02-02)
parents a5d1d333e0e2
children 9fb8690938b3
files common.inc common/include/xen_windows.h dirs quicksign.bat xennet/makefile.mingw xennet/xennet6.c xennet/xennet6.h xennet/xennet6_oid.c xennet/xennet6_rx.c xennet/xennet6_tx.c xenpci/evtchn.c xenpci/sources xenpci/xenbus.c xenpci/xenpci.c xenpci/xenpci.def xenpci/xenpci.h xenpci/xenpci_dbgprint.c xenpci/xenpci_export.c xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c xenvbd/makefile xenvbd/makefile.inc xenvbd/makefile.mingw xenvbd/sources xenvbd/xenvbd.c xenvbd/xenvbd.inx xenvbd/xenvbd.rc xenvbd/xenvbd_scsiport.c xenvbd/xenvbd_scsiport.h xenvbd/xenvbd_storport.c xenvbd/xenvbd_storport.h xenvbd_common/common.h xenvbd_common/common_miniport.h xenvbd_common/common_xen.h xenvbd_filter/makefile xenvbd_filter/makefile.inc xenvbd_filter/sources xenvbd_filter/xenvbd_filter.c xenvbd_filter/xenvbd_filter.h xenvbd_filter/xenvbd_filter.rc xenvbd_scsiport/common.h xenvbd_scsiport/makefile xenvbd_scsiport/makefile.inc xenvbd_scsiport/sources xenvbd_scsiport/xenvbd.c xenvbd_scsiport/xenvbd.h xenvbd_scsiport/xenvbd.inx xenvbd_scsiport/xenvbd.rc xenvbd_storport/makefile xenvbd_storport/makefile.inc xenvbd_storport/sources xenvbd_storport/xenvbd.c xenvbd_storport/xenvbd.h xenvbd_storport/xenvbd.inx xenvbd_storport/xenvbd.rc
line diff
     1.1 --- a/common.inc	Sun Jan 06 14:08:22 2013 +1100
     1.2 +++ b/common.inc	Sat Feb 02 18:51:07 2013 +1100
     1.3 @@ -6,4 +6,4 @@ C_DEFINES=$(C_DEFINES) -DWIN_KERNEL_BUIL
     1.4  LIBLFDS_DIR = ..\liblfds.6
     1.5  INCLUDES = ..\common\include;..\common\include\public;$(LIBLFDS_DIR)\inc
     1.6  TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\ntstrsafe.lib
     1.7 -NTTARGETFILES=
     1.8 +#NTTARGETFILES=
     2.1 --- a/common/include/xen_windows.h	Sun Jan 06 14:08:22 2013 +1100
     2.2 +++ b/common/include/xen_windows.h	Sat Feb 02 18:51:07 2013 +1100
     2.3 @@ -13,23 +13,12 @@
     2.4    #define __x86_64__
     2.5  #elif defined(_IA64_)
     2.6    #define __ia64__
     2.7 -#elif defined(__MINGW32__)
     2.8 -  /* __i386__ already defined */
     2.9  #elif defined(_X86_)
    2.10    #define __i386__
    2.11  #else
    2.12    #error Unknown architecture
    2.13  #endif
    2.14  
    2.15 -#ifdef __MINGW32__
    2.16 -typedef signed char int8_t;
    2.17 -typedef unsigned char uint8_t;
    2.18 -typedef signed short int16_t;
    2.19 -typedef unsigned short uint16_t;
    2.20 -typedef signed int int32_t;
    2.21 -typedef unsigned int uint32_t;
    2.22 -typedef unsigned long long uint64_t;
    2.23 -#else
    2.24  typedef INT8 int8_t;
    2.25  typedef UINT8 uint8_t;
    2.26  typedef INT16 int16_t;
    2.27 @@ -37,7 +26,6 @@ typedef UINT16 uint16_t;
    2.28  typedef INT32 int32_t;
    2.29  typedef UINT32 uint32_t;
    2.30  typedef UINT64 uint64_t;
    2.31 -#endif
    2.32  
    2.33  #include <xen.h>
    2.34  #include <grant_table.h>
    2.35 @@ -68,7 +56,9 @@ typedef unsigned long xenbus_transaction
    2.36  #define wmb() KeMemoryBarrier()
    2.37  #define mb() KeMemoryBarrier()
    2.38  
    2.39 -#define IOCTL_XEN_RECONFIGURE CTL_CODE(0x8000, 0x800, METHOD_NEITHER, 0)
    2.40 +//#define IOCTL_XEN_RECONFIGURE CTL_CODE(0x8000, 0x800, METHOD_NEITHER, 0)
    2.41 +//#define IOCTL_XEN_SUSPEND CTL_CODE(0x8000, 0x801, METHOD_NEITHER, 0)
    2.42 +//#define IOCTL_XEN_RESUME  CTL_CODE(0x8000, 0x802, METHOD_NEITHER, 0)
    2.43  
    2.44  static __inline char **
    2.45  SplitString(char *String, char Split, int MaxParts, int *Count)
    2.46 @@ -217,13 +207,13 @@ the wrong width is used with the wrong d
    2.47  #define XN_BASE_BACKEND  2 /* path is relative to backend device */
    2.48  #define XN_BASE_GLOBAL   3 /* path is relative to root of xenstore */
    2.49  
    2.50 +#define XN_DEVICE_CALLBACK_BACKEND_STATE 1 /* backend state change callback */
    2.51 +#define XN_DEVICE_CALLBACK_SUSPEND       2
    2.52 +#define XN_DEVICE_CALLBACK_RESUME        3
    2.53 +
    2.54  
    2.55  typedef PVOID XN_HANDLE;
    2.56  
    2.57 -/* get a handle given a PDO */
    2.58 -typedef XN_HANDLE
    2.59 -(*PXN_GET_HANDLE)(PDEVICE_OBJECT pdo);
    2.60 -
    2.61  typedef VOID
    2.62  (*PXN_WATCH_CALLBACK)(PVOID context, char *path);
    2.63  
    2.64 @@ -231,13 +221,13 @@ typedef VOID
    2.65  (*PXN_EVENT_CALLBACK)(PVOID context);
    2.66  
    2.67  typedef VOID
    2.68 -(*PXN_BACKEND_STATE_CALLBACK)(PVOID context, ULONG state);
    2.69 +(*PXN_DEVICE_CALLBACK)(PVOID context, ULONG callback_type, PVOID value);
    2.70  
    2.71  ULONG
    2.72  XnGetVersion();
    2.73  
    2.74  XN_HANDLE
    2.75 -XnOpenDevice(PDEVICE_OBJECT pdo, PXN_BACKEND_STATE_CALLBACK callback, PVOID context);
    2.76 +XnOpenDevice(PDEVICE_OBJECT pdo, PXN_DEVICE_CALLBACK callback, PVOID context);
    2.77  
    2.78  VOID
    2.79  XnCloseDevice(XN_HANDLE handle);
    2.80 @@ -296,14 +286,11 @@ XnAllocateGrant(XN_HANDLE handle, ULONG 
    2.81  VOID
    2.82  XnFreeGrant(XN_HANDLE handle, grant_ref_t ref, ULONG tag);
    2.83  
    2.84 -evtchn_port_t
    2.85 -XnAllocateEvent(XN_HANDLE handle);
    2.86 +NTSTATUS
    2.87 +XnBindEvent(XN_HANDLE handle, evtchn_port_t *port, PXN_EVENT_CALLBACK callback, PVOID context);
    2.88  
    2.89  NTSTATUS
    2.90 -XnBindEvent(XN_HANDLE handle, evtchn_port_t port, PXN_EVENT_CALLBACK callback, PVOID context);
    2.91 -
    2.92 -NTSTATUS
    2.93 -XnUnBindEvent(XN_HANDLE handle, evtchn_port_t port);
    2.94 +XnUnbindEvent(XN_HANDLE handle, evtchn_port_t port);
    2.95  
    2.96  #ifndef XENPCI_POOL_TAG
    2.97  #define XENPCI_POOL_TAG (ULONG) 'XenP'
    2.98 @@ -316,7 +303,8 @@ XnFreeMem(XN_HANDLE handle, PVOID Ptr) {
    2.99  }
   2.100  
   2.101  
   2.102 -
   2.103 +VOID
   2.104 +XnDumpModeHookDebugPrint();
   2.105  
   2.106  
   2.107  
     3.1 --- a/dirs	Sun Jan 06 14:08:22 2013 +1100
     3.2 +++ b/dirs	Sat Feb 02 18:51:07 2013 +1100
     3.3 @@ -1,4 +1,4 @@
     3.4  
     3.5  #DIRS=liblfds.6 xenpci xenvbd xennet xenscsi xenusb copyconfig shutdownmon waitnopendinginstallevents
     3.6  
     3.7 -DIRS=liblfds.6 xenpci xenvbd xennet copyconfig shutdownmon waitnopendinginstallevents
     3.8 +DIRS=liblfds.6 xenpci xenvbd_scsiport xenvbd_storport xenvbd_filter copyconfig shutdownmon waitnopendinginstallevents
     4.1 --- a/quicksign.bat	Sun Jan 06 14:08:22 2013 +1100
     4.2 +++ b/quicksign.bat	Sat Feb 02 18:51:07 2013 +1100
     4.3 @@ -1,6 +1,6 @@
     4.4  @ECHO OFF
     4.5  
     4.6 -CALL set_ddk_path.bat
     4.7 +REM CALL set_ddk_path.bat
     4.8  
     4.9  IF %_BUILDARCH%==x86 (SET BUILDDIR=obj%BUILD_ALT_DIR%\i386) ELSE (SET BUILDDIR=obj%BUILD_ALT_DIR%\amd64)
    4.10  IF %DDK_TARGET_OS%==Win2K SET SIGN_OS=2000
    4.11 @@ -28,8 +28,9 @@ SET CERT_CROSS_CERT_FLAG=
    4.12  IF DEFINED CERT_CROSS_CERT_FILENAME SET CERT_CROSS_CERT_FLAG=/ac %CERT_CROSS_CERT_FILENAME%
    4.13  SET CERT_PASSWORD_FLAG=
    4.14  IF DEFINED CERT_PASSWORD SET CERT_PASSWORD_FLAG=/p %CERT_PASSWORD%
    4.15 -%SIGNTOOL% sign /v %CERT_CROSS_CERT_FLAG% /f %CERT_FILENAME% %CERT_PASSWORD_FLAG% /t http://timestamp.verisign.com/scripts/timestamp.dll xenpci\%BUILDDIR%\xenpci.sys
    4.16 -%SIGNTOOL% sign /v %CERT_CROSS_CERT_FLAG% /f %CERT_FILENAME% %CERT_PASSWORD_FLAG% /t http://timestamp.verisign.com/scripts/timestamp.dll xenvbd\%BUILDDIR%\xenvbd.sys
    4.17 -%SIGNTOOL% sign /v %CERT_CROSS_CERT_FLAG% /f %CERT_FILENAME% %CERT_PASSWORD_FLAG% /t http://timestamp.verisign.com/scripts/timestamp.dll xennet\%BUILDDIR%\xennet.sys
    4.18 -%SIGNTOOL% sign /v %CERT_CROSS_CERT_FLAG% /f %CERT_FILENAME% %CERT_PASSWORD_FLAG% /t http://timestamp.verisign.com/scripts/timestamp.dll xenscsi\%BUILDDIR%\xenscsi.sys
    4.19 -%SIGNTOOL% sign /v %CERT_CROSS_CERT_FLAG% /f %CERT_FILENAME% %CERT_PASSWORD_FLAG% /t http://timestamp.verisign.com/scripts/timestamp.dll xenusb\%BUILDDIR%\xenusb.sys
    4.20 +%SIGNTOOL% sign /v %CERT_CROSS_CERT_FLAG% /f %CERT_FILENAME% %CERT_PASSWORD_FLAG% /t http://timestamp.verisign.com/scripts/timstamp.dll xenpci\%BUILDDIR%\xenpci.sys
    4.21 +%SIGNTOOL% sign /v %CERT_CROSS_CERT_FLAG% /f %CERT_FILENAME% %CERT_PASSWORD_FLAG% /t http://timestamp.verisign.com/scripts/timstamp.dll xenvbd\%BUILDDIR%\xenvbd.sys
    4.22 +%SIGNTOOL% sign /v %CERT_CROSS_CERT_FLAG% /f %CERT_FILENAME% %CERT_PASSWORD_FLAG% /t http://timestamp.verisign.com/scripts/timstamp.dll xenvbd_filter\%BUILDDIR%\xenvbd_filter.sys
    4.23 +%SIGNTOOL% sign /v %CERT_CROSS_CERT_FLAG% /f %CERT_FILENAME% %CERT_PASSWORD_FLAG% /t http://timestamp.verisign.com/scripts/timstamp.dll xennet\%BUILDDIR%\xennet.sys
    4.24 +%SIGNTOOL% sign /v %CERT_CROSS_CERT_FLAG% /f %CERT_FILENAME% %CERT_PASSWORD_FLAG% /t http://timestamp.verisign.com/scripts/timstamp.dll xenscsi\%BUILDDIR%\xenscsi.sys
    4.25 +%SIGNTOOL% sign /v %CERT_CROSS_CERT_FLAG% /f %CERT_FILENAME% %CERT_PASSWORD_FLAG% /t http://timestamp.verisign.com/scripts/timstamp.dll xenusb\%BUILDDIR%\xenusb.sys
     5.1 --- a/xennet/makefile.mingw	Sun Jan 06 14:08:22 2013 +1100
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,7 +0,0 @@
     5.4 -W32API_PATH=/home/agrover/temp/w32api-3.11
     5.5 -
     5.6 -CFLAGS = -O2 -Wall -L$(W32API_PATH)/lib/ddk -I$(W32API_PATH)/include/ddk -I../common/include -I../common/include/public -Wno-multichar -Wno-unknown-pragmas -DDBG
     5.7 -
     5.8 -xennet.sys: xennet.c xennet_oid.c xennet_tx.c xennet_rx.c xennet_common.c ../mingw/mingw_extras.c
     5.9 -	i586-mingw32msvc-gcc $(CFLAGS) -o $@ -shared -Wl,--entry,_DriverEntry@8 -nostartfiles -nostdlib $^ -lntoskrnl -lhal -lndis
    5.10 -
     6.1 --- a/xennet/xennet6.c	Sun Jan 06 14:08:22 2013 +1100
     6.2 +++ b/xennet/xennet6.c	Sat Feb 02 18:51:07 2013 +1100
     6.3 @@ -29,6 +29,7 @@ static IO_WORKITEM_ROUTINE XenNet_Resume
     6.4  //static KDEFERRED_ROUTINE XenNet_SuspendResume;
     6.5  static KDEFERRED_ROUTINE XenNet_RxTxDpc;
     6.6  #endif
     6.7 +static VOID XenNet_DeviceCallback(PVOID context, ULONG callback_type, PVOID value);
     6.8  
     6.9  #pragma NDIS_INIT_FUNCTION(DriverEntry)
    6.10  
    6.11 @@ -37,322 +38,6 @@ NDIS_HANDLE driver_handle = NULL;
    6.12  USHORT ndis_os_major_version = 0;
    6.13  USHORT ndis_os_minor_version = 0;
    6.14  
    6.15 -#if 0
    6.16 -/* ----- BEGIN Other people's code --------- */
    6.17 -/* from linux/include/linux/ctype.h, used under GPLv2 */
    6.18 -#define _U      0x01    /* upper */
    6.19 -#define _L      0x02    /* lower */
    6.20 -#define _D      0x04    /* digit */
    6.21 -#define _C      0x08    /* cntrl */
    6.22 -#define _P      0x10    /* punct */
    6.23 -#define _S      0x20    /* white space (space/lf/tab) */
    6.24 -#define _X      0x40    /* hex digit */
    6.25 -#define _SP     0x80    /* hard space (0x20) */
    6.26 -
    6.27 -/* from linux/include/lib/ctype.c, used under GPLv2 */
    6.28 -unsigned char _ctype[] = {
    6.29 -_C,_C,_C,_C,_C,_C,_C,_C,                        /* 0-7 */
    6.30 -_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,         /* 8-15 */
    6.31 -_C,_C,_C,_C,_C,_C,_C,_C,                        /* 16-23 */
    6.32 -_C,_C,_C,_C,_C,_C,_C,_C,                        /* 24-31 */
    6.33 -_S|_SP,_P,_P,_P,_P,_P,_P,_P,                    /* 32-39 */
    6.34 -_P,_P,_P,_P,_P,_P,_P,_P,                        /* 40-47 */
    6.35 -_D,_D,_D,_D,_D,_D,_D,_D,                        /* 48-55 */
    6.36 -_D,_D,_P,_P,_P,_P,_P,_P,                        /* 56-63 */
    6.37 -_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,      /* 64-71 */
    6.38 -_U,_U,_U,_U,_U,_U,_U,_U,                        /* 72-79 */
    6.39 -_U,_U,_U,_U,_U,_U,_U,_U,                        /* 80-87 */
    6.40 -_U,_U,_U,_P,_P,_P,_P,_P,                        /* 88-95 */
    6.41 -_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,      /* 96-103 */
    6.42 -_L,_L,_L,_L,_L,_L,_L,_L,                        /* 104-111 */
    6.43 -_L,_L,_L,_L,_L,_L,_L,_L,                        /* 112-119 */
    6.44 -_L,_L,_L,_P,_P,_P,_P,_C,                        /* 120-127 */
    6.45 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 128-143 */
    6.46 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 144-159 */
    6.47 -_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
    6.48 -_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
    6.49 -_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
    6.50 -_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
    6.51 -_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
    6.52 -_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
    6.53 -
    6.54 -/* from linux/include/linux/ctype.h, used under GPLv2 */
    6.55 -#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
    6.56 -
    6.57 -#define isalnum(c)      ((__ismask(c)&(_U|_L|_D)) != 0)
    6.58 -#define isalpha(c)      ((__ismask(c)&(_U|_L)) != 0)
    6.59 -#define iscntrl(c)      ((__ismask(c)&(_C)) != 0)
    6.60 -#define isdigit(c)      ((__ismask(c)&(_D)) != 0)
    6.61 -#define isgraph(c)      ((__ismask(c)&(_P|_U|_L|_D)) != 0)
    6.62 -#define islower(c)      ((__ismask(c)&(_L)) != 0)
    6.63 -#define isprint(c)      ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
    6.64 -#define ispunct(c)      ((__ismask(c)&(_P)) != 0)
    6.65 -#define isspace(c)      ((__ismask(c)&(_S)) != 0)
    6.66 -#define isupper(c)      ((__ismask(c)&(_U)) != 0)
    6.67 -#define isxdigit(c)     ((__ismask(c)&(_D|_X)) != 0)
    6.68 -
    6.69 -#define TOLOWER(x) ((x) | 0x20)
    6.70 -
    6.71 -/* from linux/lib/vsprintf.c, used under GPLv2 */
    6.72 -/* Copyright (C) 1991, 1992  Linus Torvalds
    6.73 - * Wirzenius wrote this portably, Torvalds fucked it up :-)
    6.74 - */
    6.75 -/**
    6.76 - * simple_strtoul - convert a string to an unsigned long
    6.77 - * @cp: The start of the string
    6.78 - * @endp: A pointer to the end of the parsed string will be placed here
    6.79 - * @base: The number base to use
    6.80 - */
    6.81 -unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
    6.82 -{
    6.83 -  unsigned long result = 0,value;
    6.84 -
    6.85 -  if (!base) {
    6.86 -    base = 10;
    6.87 -    if (*cp == '0') {
    6.88 -      base = 8;
    6.89 -      cp++;
    6.90 -      if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) {
    6.91 -        cp++;
    6.92 -        base = 16;
    6.93 -      }
    6.94 -    }
    6.95 -  } else if (base == 16) {
    6.96 -    if (cp[0] == '0' && TOLOWER(cp[1]) == 'x')
    6.97 -      cp += 2;
    6.98 -  }
    6.99 -  while (isxdigit(*cp) &&
   6.100 -    (value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {
   6.101 -    result = result*base + value;
   6.102 -    cp++;
   6.103 -  }
   6.104 -  if (endp)
   6.105 -    *endp = (char *)cp;
   6.106 -  return result;
   6.107 -}
   6.108 -/* end vsprintf.c code */
   6.109 -/* ----- END Other people's code --------- */
   6.110 -#endif
   6.111 -
   6.112 -#if 0
   6.113 -static NDIS_STATUS
   6.114 -XenNet_ConnectBackend(struct xennet_info *xi)
   6.115 -{
   6.116 -  PUCHAR ptr;
   6.117 -  UCHAR type;
   6.118 -  PCHAR setting, value, value2;
   6.119 -  UINT i;
   6.120 -
   6.121 -  FUNCTION_ENTER();
   6.122 -  
   6.123 -  NT_ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   6.124 -
   6.125 -  xi->backend_csum_supported = TRUE; /* just assume this */
   6.126 -  xi->backend_gso_value = 0;
   6.127 -  xi->backend_sg_supported = FALSE;
   6.128 -  
   6.129 -  ptr = xi->config_page;
   6.130 -  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
   6.131 -  {
   6.132 -    switch(type)
   6.133 -    {
   6.134 -    case XEN_INIT_TYPE_RING: /* frontend ring */
   6.135 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
   6.136 -      if (strcmp(setting, "tx-ring-ref") == 0)
   6.137 -      {
   6.138 -        FRONT_RING_INIT(&xi->tx, (netif_tx_sring_t *)value, PAGE_SIZE);
   6.139 -      } else if (strcmp(setting, "rx-ring-ref") == 0)
   6.140 -      {
   6.141 -        FRONT_RING_INIT(&xi->rx, (netif_rx_sring_t *)value, PAGE_SIZE);
   6.142 -      }
   6.143 -      break;
   6.144 -    case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
   6.145 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value)));
   6.146 -      if (strcmp(setting, "event-channel") == 0)
   6.147 -      {
   6.148 -        xi->event_channel = PtrToUlong(value);
   6.149 -      }
   6.150 -      break;
   6.151 -    case XEN_INIT_TYPE_READ_STRING_FRONT:
   6.152 -      break;
   6.153 -    case XEN_INIT_TYPE_READ_STRING_BACK:
   6.154 -      state = 0;
   6.155 -      octet = 0;
   6.156 -      for (i = 0; i < strlen(value); i++) {
   6.157 -        if (octet >= 6)
   6.158 -          state = 4;
   6.159 -        switch(state) {
   6.160 -        case 0:
   6.161 -        case 1:
   6.162 -          if (value[i] >= 0 && value[i] <= 9) {
   6.163 -            xi->perm_mac_addr[octet] = (value[i] - '0') << ((1 - state) * 4);
   6.164 -            state++;
   6.165 -          } else if (value[i] >= 'A' && value[i] <= 'F') {
   6.166 -            xi->perm_mac_addr[octet] = (value[i] - 'A' + 10) << ((1 - state) * 4);
   6.167 -            state++;
   6.168 -          } else if (value[i] >= 'a' && value[i] <= 'f') {
   6.169 -            xi->perm_mac_addr[octet] = (value[i] - 'a' + 10) << ((1 - state) * 4);
   6.170 -            state++;
   6.171 -          } else {
   6.172 -            state = 4;
   6.173 -          }
   6.174 -          break;
   6.175 -            
   6.176 -      if (strcmp(setting, "mac") == 0)
   6.177 -      {
   6.178 -        char *s, *e;
   6.179 -        s = value;
   6.180 -        for (i = 0; i < ETH_ALEN; i++) {
   6.181 -          xi->perm_mac_addr[i] = (uint8_t)simple_strtoul(s, &e, 16);
   6.182 -          if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) {
   6.183 -            KdPrint((__DRIVER_NAME "Error parsing MAC address\n"));
   6.184 -          }
   6.185 -          s = e + 1;
   6.186 -        }
   6.187 -        if ((xi->curr_mac_addr[0] & 0x03) != 0x02)
   6.188 -        {
   6.189 -          /* only copy if curr_mac_addr is not a LUA */
   6.190 -          memcpy(xi->curr_mac_addr, xi->perm_mac_addr, ETH_ALEN);
   6.191 -        }
   6.192 -      }
   6.193 -      else if (strcmp(setting, "feature-sg") == 0)
   6.194 -      {
   6.195 -        if (atoi(value))
   6.196 -        {
   6.197 -          xi->backend_sg_supported = TRUE;
   6.198 -        }
   6.199 -      }
   6.200 -      else if (strcmp(setting, "feature-gso-tcpv4") == 0)
   6.201 -      {
   6.202 -        if (atoi(value))
   6.203 -        {
   6.204 -          xi->backend_gso_value = xi->frontend_gso_value;
   6.205 -        }
   6.206 -      }
   6.207 -      break;
   6.208 -    case XEN_INIT_TYPE_VECTORS:
   6.209 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
   6.210 -      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
   6.211 -        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
   6.212 -      {
   6.213 -        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
   6.214 -          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
   6.215 -        FUNCTION_EXIT();
   6.216 -        return NDIS_STATUS_ADAPTER_NOT_FOUND;
   6.217 -      }
   6.218 -      else
   6.219 -        memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS));
   6.220 -      break;
   6.221 -    case XEN_INIT_TYPE_STATE_PTR:
   6.222 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
   6.223 -      xi->device_state = (PXENPCI_DEVICE_STATE)value;
   6.224 -      break;
   6.225 -    default:
   6.226 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
   6.227 -      break;
   6.228 -    }
   6.229 -  }
   6.230 -  if (!xi->backend_sg_supported)
   6.231 -    xi->backend_gso_value = min(xi->backend_gso_value, PAGE_SIZE - MAX_PKT_HEADER_LENGTH);
   6.232 -
   6.233 -  xi->current_sg_supported = xi->frontend_sg_supported && xi->backend_sg_supported;
   6.234 -  xi->current_csum_supported = xi->frontend_csum_supported && xi->backend_csum_supported;
   6.235 -  xi->current_gso_value = min(xi->backend_gso_value, xi->backend_gso_value);
   6.236 -  xi->current_mtu_value = xi->frontend_mtu_value;
   6.237 -  xi->current_gso_rx_split_type = xi->frontend_gso_rx_split_type;
   6.238 -    
   6.239 -  FUNCTION_EXIT();
   6.240 -  
   6.241 -  return NDIS_STATUS_SUCCESS;
   6.242 -} /* XenNet_ConnectBackend */
   6.243 -#endif
   6.244 -
   6.245 -#if 0
   6.246 -static VOID
   6.247 -XenNet_ResumeWorkItem(PDEVICE_OBJECT device_object, PVOID context)
   6.248 -{
   6.249 -  struct xennet_info *xi = context;
   6.250 -  KIRQL old_irql;
   6.251 -  
   6.252 -  UNREFERENCED_PARAMETER(device_object);
   6.253 -  
   6.254 -  FUNCTION_ENTER();
   6.255 -
   6.256 -  NT_ASSERT(xi->resume_work_item);
   6.257 -
   6.258 -  IoFreeWorkItem(xi->resume_work_item);
   6.259 -  
   6.260 -  XenNet_TxResumeStart(xi);
   6.261 -  XenNet_RxResumeStart(xi);
   6.262 -  XenNet_ConnectBackend(xi);
   6.263 -  XenNet_RxResumeEnd(xi);
   6.264 -  XenNet_TxResumeEnd(xi);
   6.265 -
   6.266 -  KeAcquireSpinLock(&xi->resume_lock, &old_irql);
   6.267 -  xi->resume_work_item = NULL;
   6.268 -  KdPrint((__DRIVER_NAME "     *Setting suspend_resume_state_fdo = %d\n", xi->device_state->suspend_resume_state_pdo));
   6.269 -  xi->device_state->suspend_resume_state_fdo = xi->device_state->suspend_resume_state_pdo;
   6.270 -  KdPrint((__DRIVER_NAME "     *Notifying event channel %d\n", xi->device_state->pdo_event_channel));
   6.271 -  xi->vectors.EvtChn_Notify(xi->vectors.context, xi->device_state->pdo_event_channel);
   6.272 -  KeReleaseSpinLock(&xi->resume_lock, old_irql);
   6.273 -
   6.274 -  FUNCTION_EXIT();
   6.275 -}
   6.276 -
   6.277 -static VOID
   6.278 -XenNet_SuspendResume(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2)
   6.279 -{
   6.280 -  struct xennet_info *xi = context;
   6.281 -  KIRQL old_irql;
   6.282 -  PIO_WORKITEM resume_work_item;
   6.283 -
   6.284 -  UNREFERENCED_PARAMETER(dpc);
   6.285 -  UNREFERENCED_PARAMETER(arg1);
   6.286 -  UNREFERENCED_PARAMETER(arg2);
   6.287 -
   6.288 -  FUNCTION_ENTER();
   6.289 -  
   6.290 -  switch (xi->device_state->suspend_resume_state_pdo)
   6.291 -  {
   6.292 -  case SR_STATE_SUSPENDING:
   6.293 -    KdPrint((__DRIVER_NAME "     New state SUSPENDING\n"));
   6.294 -    KeAcquireSpinLock(&xi->rx_lock, &old_irql);
   6.295 -    if (xi->rx_id_free == NET_RX_RING_SIZE)
   6.296 -    {  
   6.297 -      xi->device_state->suspend_resume_state_fdo = SR_STATE_SUSPENDING;
   6.298 -      KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xi->device_state->pdo_event_channel));
   6.299 -      xi->vectors.EvtChn_Notify(xi->vectors.context, xi->device_state->pdo_event_channel);
   6.300 -    }
   6.301 -    KeReleaseSpinLock(&xi->rx_lock, old_irql);
   6.302 -    break;
   6.303 -  case SR_STATE_RESUMING:
   6.304 -    KdPrint((__DRIVER_NAME "     New state SR_STATE_RESUMING\n"));
   6.305 -    /* do it like this so we don't race and double-free the work item */
   6.306 -    resume_work_item = IoAllocateWorkItem(xi->fdo);
   6.307 -    KeAcquireSpinLock(&xi->resume_lock, &old_irql);
   6.308 -    if (xi->resume_work_item || xi->device_state->suspend_resume_state_fdo == SR_STATE_RESUMING)
   6.309 -    {
   6.310 -      KeReleaseSpinLock(&xi->resume_lock, old_irql);
   6.311 -      IoFreeWorkItem(resume_work_item);
   6.312 -      return;
   6.313 -    }
   6.314 -    xi->resume_work_item = resume_work_item;
   6.315 -    KeReleaseSpinLock(&xi->resume_lock, old_irql);
   6.316 -    IoQueueWorkItem(xi->resume_work_item, XenNet_ResumeWorkItem, DelayedWorkQueue, xi);
   6.317 -    break;
   6.318 -  default:
   6.319 -    KdPrint((__DRIVER_NAME "     New state %d\n", xi->device_state->suspend_resume_state_fdo));
   6.320 -    xi->device_state->suspend_resume_state_fdo = xi->device_state->suspend_resume_state_pdo;
   6.321 -    KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xi->device_state->pdo_event_channel));
   6.322 -    xi->vectors.EvtChn_Notify(xi->vectors.context, xi->device_state->pdo_event_channel);
   6.323 -    break;
   6.324 -  }
   6.325 -  KeMemoryBarrier();
   6.326 -  
   6.327 -  FUNCTION_EXIT();
   6.328 -}
   6.329 -#endif
   6.330 -
   6.331  static VOID
   6.332  XenNet_RxTxDpc(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2)
   6.333  {
   6.334 @@ -377,33 +62,228 @@ XenNet_HandleEvent_DIRQL(PVOID context)
   6.335    //ULONG suspend_resume_state_pdo;
   6.336    
   6.337    //FUNCTION_ENTER();
   6.338 -#if 0
   6.339 -  suspend_resume_state_pdo = xi->device_state->suspend_resume_state_pdo;
   6.340 -  KeMemoryBarrier();
   6.341 -
   6.342 -  if (!xi->shutting_down && suspend_resume_state_pdo != xi->device_state->suspend_resume_state_fdo) {
   6.343 -    KeInsertQueueDpc(&xi->suspend_dpc, NULL, NULL);
   6.344 -  }
   6.345 -  if (xi->connected && !xi->inactive && suspend_resume_state_pdo != SR_STATE_RESUMING) {
   6.346 -#endif
   6.347 -  if (xi->connected && !xi->inactive) {
   6.348 +  if (xi->device_state == DEVICE_STATE_ACTIVE || xi->device_state == DEVICE_STATE_DISCONNECTING) {
   6.349      KeInsertQueueDpc(&xi->rxtx_dpc, NULL, NULL);
   6.350    }
   6.351    //FUNCTION_EXIT();
   6.352    return TRUE;
   6.353  }
   6.354  
   6.355 -XenNet_BackendStateCallback(PVOID context, ULONG state) {
   6.356 +static NTSTATUS
   6.357 +XenNet_Connect(PVOID context, BOOLEAN suspend) {
   6.358 +  NTSTATUS status;
   6.359 +  struct xennet_info *xi = context;
   6.360 +  PFN_NUMBER pfn;
   6.361 +  ULONG qemu_hide_filter;
   6.362 +  ULONG qemu_hide_flags_value;
   6.363 +  int i;
   6.364 +  ULONG state;
   6.365 +  ULONG octet;
   6.366 +  PCHAR tmp_string;
   6.367 +  ULONG tmp_ulong;
   6.368 +
   6.369 +  if (!suspend) {
   6.370 +    xi->handle = XnOpenDevice(xi->pdo, XenNet_DeviceCallback, xi);
   6.371 +  }
   6.372 +  if (!xi->handle) {
   6.373 +    FUNCTION_MSG("Cannot open Xen device\n");
   6.374 +    return STATUS_UNSUCCESSFUL;
   6.375 +  }
   6.376 +  XnGetValue(xi->handle, XN_VALUE_TYPE_QEMU_HIDE_FLAGS, &qemu_hide_flags_value);
   6.377 +  XnGetValue(xi->handle, XN_VALUE_TYPE_QEMU_FILTER, &qemu_hide_filter);
   6.378 +  if (!(qemu_hide_flags_value & QEMU_UNPLUG_ALL_NICS) || qemu_hide_filter) {
   6.379 +    FUNCTION_MSG("inactive\n");
   6.380 +    xi->device_state = DEVICE_STATE_INACTIVE;
   6.381 +    XnCloseDevice(xi->handle);
   6.382 +    return STATUS_SUCCESS;
   6.383 +  }
   6.384 +
   6.385 +  for (i = 0; i <= 5 && xi->backend_state != XenbusStateInitialising && xi->backend_state != XenbusStateInitWait && xi->backend_state != XenbusStateInitialised; i++) {
   6.386 +    FUNCTION_MSG("Waiting for XenbusStateInitXxx\n");
   6.387 +    KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL);
   6.388 +  }
   6.389 +  if (xi->backend_state != XenbusStateInitialising && xi->backend_state != XenbusStateInitWait && xi->backend_state != XenbusStateInitialised) {
   6.390 +    FUNCTION_MSG("Backend state timeout\n");
   6.391 +    return STATUS_UNSUCCESSFUL;
   6.392 +  }
   6.393 +  if (!NT_SUCCESS(status = XnBindEvent(xi->handle, &xi->event_channel, XenNet_HandleEvent_DIRQL, xi))) {
   6.394 +    FUNCTION_MSG("Cannot allocate event channel\n");
   6.395 +    return STATUS_UNSUCCESSFUL;
   6.396 +  }
   6.397 +  FUNCTION_MSG("event_channel = %d\n", xi->event_channel);
   6.398 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "event-channel", xi->event_channel);
   6.399 +  xi->tx_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENNET_POOL_TAG);
   6.400 +  if (!xi->tx_sring) {
   6.401 +    FUNCTION_MSG("Cannot allocate tx_sring\n");
   6.402 +    return STATUS_UNSUCCESSFUL;
   6.403 +  }
   6.404 +  SHARED_RING_INIT(xi->tx_sring);
   6.405 +  FRONT_RING_INIT(&xi->tx_ring, xi->tx_sring, PAGE_SIZE);
   6.406 +  pfn = MmGetPhysicalAddress(xi->tx_sring).QuadPart >> PAGE_SHIFT;
   6.407 +  FUNCTION_MSG("tx sring pfn = %d\n", (ULONG)pfn);
   6.408 +  xi->tx_sring_gref = XnGrantAccess(xi->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENNET_POOL_TAG);
   6.409 +  FUNCTION_MSG("tx sring_gref = %d\n", xi->tx_sring_gref);
   6.410 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "tx-ring-ref", xi->tx_sring_gref);  
   6.411 +  xi->rx_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENNET_POOL_TAG);
   6.412 +  if (!xi->rx_sring) {
   6.413 +    FUNCTION_MSG("Cannot allocate rx_sring\n");
   6.414 +    return STATUS_UNSUCCESSFUL;
   6.415 +  }
   6.416 +  SHARED_RING_INIT(xi->rx_sring);
   6.417 +  FRONT_RING_INIT(&xi->rx_ring, xi->rx_sring, PAGE_SIZE);
   6.418 +  pfn = MmGetPhysicalAddress(xi->rx_sring).QuadPart >> PAGE_SHIFT;
   6.419 +  FUNCTION_MSG("rx sring pfn = %d\n", (ULONG)pfn);
   6.420 +  xi->rx_sring_gref = XnGrantAccess(xi->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENNET_POOL_TAG);
   6.421 +  FUNCTION_MSG("rx sring_gref = %d\n", xi->rx_sring_gref);
   6.422 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "rx-ring-ref", xi->rx_sring_gref);  
   6.423 +
   6.424 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "request-rx-copy", 1);
   6.425 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "request-rx-notify", 1);
   6.426 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-no-csum-offload", !xi->frontend_csum_supported);
   6.427 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-sg", (int)xi->frontend_sg_supported);
   6.428 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-gso-tcpv4", !!xi->frontend_gso_value);
   6.429 +
   6.430 +  status = XnReadInt32(xi->handle, XN_BASE_BACKEND, "feature-sg", &tmp_ulong);
   6.431 +  if (tmp_ulong) {
   6.432 +    xi->backend_sg_supported = TRUE;
   6.433 +  }
   6.434 +  status = XnReadInt32(xi->handle, XN_BASE_BACKEND, "feature-gso-tcpv4", &tmp_ulong);
   6.435 +  if (tmp_ulong) {
   6.436 +    xi->backend_gso_value = xi->frontend_gso_value;
   6.437 +  }
   6.438 +
   6.439 +  status = XnReadString(xi->handle, XN_BASE_BACKEND, "mac", &tmp_string);
   6.440 +  state = 0;
   6.441 +  octet = 0;
   6.442 +  for (i = 0; state != 3 && i < strlen(tmp_string); i++) {
   6.443 +    if (octet == 6) {
   6.444 +      state = 3;
   6.445 +      break;
   6.446 +    }
   6.447 +    switch(state) {
   6.448 +    case 0:
   6.449 +    case 1:
   6.450 +      if (tmp_string[i] >= '0' && tmp_string[i] <= '9') {
   6.451 +        xi->perm_mac_addr[octet] |= (tmp_string[i] - '0') << ((1 - state) * 4);
   6.452 +        state++;
   6.453 +      } else if (tmp_string[i] >= 'A' && tmp_string[i] <= 'F') {
   6.454 +        xi->perm_mac_addr[octet] |= (tmp_string[i] - 'A' + 10) << ((1 - state) * 4);
   6.455 +        state++;
   6.456 +      } else if (tmp_string[i] >= 'a' && tmp_string[i] <= 'f') {
   6.457 +        xi->perm_mac_addr[octet] |= (tmp_string[i] - 'a' + 10) << ((1 - state) * 4);
   6.458 +        state++;
   6.459 +      } else {
   6.460 +        state = 3;
   6.461 +      }
   6.462 +      break;
   6.463 +    case 2:
   6.464 +      if (tmp_string[i] == ':') {
   6.465 +        octet++;
   6.466 +        state = 0;
   6.467 +      } else {
   6.468 +        state = 3;
   6.469 +      }
   6.470 +      break;
   6.471 +    }
   6.472 +  }
   6.473 +  if (octet != 5 || state != 2) {
   6.474 +    FUNCTION_MSG("Failed to parse backend MAC address %s\n", tmp_string);
   6.475 +    XnFreeMem(xi->handle, tmp_string);
   6.476 +    return STATUS_UNSUCCESSFUL;
   6.477 +  } else if ((xi->curr_mac_addr[0] & 0x03) != 0x02) {
   6.478 +    /* only copy if curr_mac_addr is not a LUA */
   6.479 +    memcpy(xi->curr_mac_addr, xi->perm_mac_addr, ETH_ALEN);
   6.480 +  }
   6.481 +  XnFreeMem(xi->handle, tmp_string);
   6.482 +  FUNCTION_MSG("MAC address is %02X:%02X:%02X:%02X:%02X:%02X\n",
   6.483 +    xi->curr_mac_addr[0], xi->curr_mac_addr[1], xi->curr_mac_addr[2], 
   6.484 +    xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5]);
   6.485 +
   6.486 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "state", XenbusStateConnected);
   6.487 +
   6.488 +  for (i = 0; i <= 5 && xi->backend_state != XenbusStateConnected; i++) {
   6.489 +    FUNCTION_MSG("Waiting for XenbusStateConnected\n");
   6.490 +    KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL);
   6.491 +  }
   6.492 +  if (xi->backend_state != XenbusStateConnected) {
   6.493 +    FUNCTION_MSG("Backend state timeout\n");
   6.494 +    return STATUS_UNSUCCESSFUL;
   6.495 +  }
   6.496 +  XenNet_TxInit(xi);
   6.497 +  XenNet_RxInit(xi);
   6.498 +
   6.499 +  /* we don't set device_state = DEVICE_STATE_ACTIVE here - has to be done during init once ndis is ready */
   6.500 +  
   6.501 +  return STATUS_SUCCESS;
   6.502 +}
   6.503 +
   6.504 +static NTSTATUS
   6.505 +XenNet_Disconnect(PVOID context, BOOLEAN suspend) {
   6.506    struct xennet_info *xi = (struct xennet_info *)context;
   6.507 +  PFN_NUMBER pfn;
   6.508 +  NTSTATUS status;
   6.509 +
   6.510 +  if (xi->device_state != DEVICE_STATE_ACTIVE) {
   6.511 +    FUNCTION_MSG("state not DEVICE_STATE_ACTIVE, is %d instead\n", xi->device_state);
   6.512 +    FUNCTION_EXIT();
   6.513 +    return STATUS_SUCCESS;
   6.514 +  }
   6.515 +  xi->device_state = DEVICE_STATE_DISCONNECTING;
   6.516 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "state", XenbusStateClosing);
   6.517 +  while (xi->backend_state != XenbusStateClosing && xi->backend_state != XenbusStateClosed) {
   6.518 +    FUNCTION_MSG("Waiting for XenbusStateClosing/Closed\n");
   6.519 +    KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL);
   6.520 +  }
   6.521 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "state", XenbusStateClosed);
   6.522 +  while (xi->backend_state != XenbusStateClosed) {
   6.523 +    FUNCTION_MSG("Waiting for XenbusStateClosed\n");
   6.524 +    KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL);
   6.525 +  }
   6.526 +  XnUnbindEvent(xi->handle, xi->event_channel);
   6.527 +  KeFlushQueuedDpcs();
   6.528 +  XenNet_TxShutdown(xi);
   6.529 +  XenNet_RxShutdown(xi);
   6.530 +  pfn = MmGetPhysicalAddress(xi->rx_sring).QuadPart >> PAGE_SHIFT;
   6.531 +  XnEndAccess(xi->handle, xi->rx_sring_gref, FALSE, XENNET_POOL_TAG);
   6.532 +  ExFreePoolWithTag(xi->rx_sring, XENNET_POOL_TAG);
   6.533 +  pfn = MmGetPhysicalAddress(xi->tx_sring).QuadPart >> PAGE_SHIFT;
   6.534 +  XnEndAccess(xi->handle, xi->tx_sring_gref, FALSE, XENNET_POOL_TAG);
   6.535 +  ExFreePoolWithTag(xi->tx_sring, XENNET_POOL_TAG);
   6.536 +  if (!suspend) {
   6.537 +    XnCloseDevice(xi->handle);
   6.538 +  }
   6.539 +  xi->device_state = DEVICE_STATE_DISCONNECTED;
   6.540 +  return STATUS_SUCCESS;
   6.541 +};
   6.542 +
   6.543 +static VOID
   6.544 +XenNet_DeviceCallback(PVOID context, ULONG callback_type, PVOID value) {
   6.545 +  struct xennet_info *xi = (struct xennet_info *)context;
   6.546 +  ULONG state;
   6.547    
   6.548    FUNCTION_ENTER();
   6.549 -  if (state == xi->backend_state) {
   6.550 -    FUNCTION_MSG("same state %d\n", state);
   6.551 -    FUNCTION_EXIT();
   6.552 +  switch (callback_type) {
   6.553 +  case XN_DEVICE_CALLBACK_BACKEND_STATE:
   6.554 +    state = (ULONG)(ULONG_PTR)value;
   6.555 +    if (state == xi->backend_state) {
   6.556 +      FUNCTION_MSG("same state %d\n", state);
   6.557 +      FUNCTION_EXIT();
   6.558 +    }
   6.559 +    FUNCTION_MSG("XenBusState = %d -> %d\n", xi->backend_state, state);
   6.560 +    xi->backend_state = state;
   6.561 +    KeSetEvent(&xi->backend_event, 0, FALSE);
   6.562 +    break;
   6.563 +  case XN_DEVICE_CALLBACK_SUSPEND:
   6.564 +    FUNCTION_MSG("XN_DEVICE_CALLBACK_SUSPEND");
   6.565 +    XenNet_Disconnect(xi, TRUE);
   6.566 +    break;
   6.567 +  case XN_DEVICE_CALLBACK_RESUME:
   6.568 +    FUNCTION_MSG("XN_DEVICE_CALLBACK_RESUME");
   6.569 +    XenNet_Connect(xi, TRUE);
   6.570 +    xi->device_state = DEVICE_STATE_ACTIVE;
   6.571 +    KeInsertQueueDpc(&xi->rxtx_dpc, NULL, NULL);
   6.572 +    break;
   6.573    }
   6.574 -  FUNCTION_MSG("XenbusState = %d -> %d\n", xi->backend_state, state);
   6.575 -  xi->backend_state = state;
   6.576 -  NdisSetEvent(&xi->backend_event);
   6.577    FUNCTION_EXIT();
   6.578  }
   6.579  
   6.580 @@ -419,22 +299,15 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   6.581    PNDIS_CONFIGURATION_PARAMETER config_param;
   6.582    //PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapter_attributes;
   6.583    ULONG i;
   6.584 -  PFN_NUMBER pfn;
   6.585    ULONG length;
   6.586    PVOID network_address;
   6.587    UINT network_address_length;
   6.588 -  ULONG qemu_hide_filter;
   6.589 -  ULONG qemu_hide_flags_value;
   6.590    NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES registration_attributes;
   6.591    NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES general_attributes;
   6.592    NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES offload_attributes;
   6.593    NDIS_OFFLOAD df_offload, hw_offload;
   6.594    NDIS_TCP_CONNECTION_OFFLOAD df_conn_offload, hw_conn_offload;
   6.595    static NDIS_OID *supported_oids;
   6.596 -  ULONG state;
   6.597 -  ULONG octet;
   6.598 -  PCHAR tmp_string;
   6.599 -  ULONG tmp_ulong;
   6.600  
   6.601    UNREFERENCED_PARAMETER(driver_context);
   6.602    UNREFERENCED_PARAMETER(init_parameters);
   6.603 @@ -450,60 +323,10 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   6.604    }
   6.605    RtlZeroMemory(xi, sizeof(*xi));
   6.606    xi->adapter_handle = adapter_handle;
   6.607 -  xi->inactive = TRUE;
   6.608 +  xi->device_state = DEVICE_STATE_INITIALISING;
   6.609    NdisMGetDeviceProperty(xi->adapter_handle, &xi->pdo, &xi->fdo,
   6.610      &xi->lower_do, NULL, NULL);
   6.611 -  NdisInitializeEvent(&xi->backend_event);
   6.612 -  xi->handle = XnOpenDevice(xi->pdo, XenNet_BackendStateCallback, xi);
   6.613 -  if (!xi->handle) {
   6.614 -    FUNCTION_MSG("Cannot open Xen device\n");
   6.615 -    status = NDIS_STATUS_RESOURCES;
   6.616 -    goto err;
   6.617 -  }
   6.618 -  for (i = 0; i <= 5 && xi->backend_state != XenbusStateInitialising && xi->backend_state != XenbusStateInitWait && xi->backend_state != XenbusStateInitialised; i++) {
   6.619 -    NdisWaitEvent(&xi->backend_event, 1000);
   6.620 -  }
   6.621 -  NdisResetEvent(&xi->backend_event);
   6.622 -  if (xi->backend_state != XenbusStateInitialising && xi->backend_state != XenbusStateInitWait && xi->backend_state != XenbusStateInitialised) {
   6.623 -    FUNCTION_MSG("Backend state timeout\n");
   6.624 -    status = NDIS_STATUS_RESOURCES;
   6.625 -    goto err;
   6.626 -  }
   6.627 -  xi->event_channel = XnAllocateEvent(xi->handle);
   6.628 -  if (!xi->event_channel) {
   6.629 -    FUNCTION_MSG("Cannot allocate event channel\n");
   6.630 -    status = NDIS_STATUS_RESOURCES;
   6.631 -    goto err;
   6.632 -  }
   6.633 -  FUNCTION_MSG("event_channel = %d\n", xi->event_channel);
   6.634 -  status = XnBindEvent(xi->handle, xi->event_channel, XenNet_HandleEvent_DIRQL, xi);
   6.635 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "event-channel", xi->event_channel);
   6.636 -  xi->tx_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENNET_POOL_TAG);
   6.637 -  if (!xi->tx_sring) {
   6.638 -    FUNCTION_MSG("Cannot allocate tx_sring\n");
   6.639 -    status = NDIS_STATUS_RESOURCES;
   6.640 -    goto err;
   6.641 -  }
   6.642 -  SHARED_RING_INIT(xi->tx_sring);
   6.643 -  FRONT_RING_INIT(&xi->tx_ring, xi->tx_sring, PAGE_SIZE);
   6.644 -  pfn = MmGetPhysicalAddress(xi->tx_sring).QuadPart >> PAGE_SHIFT;
   6.645 -  FUNCTION_MSG("tx sring pfn = %d\n", (ULONG)pfn);
   6.646 -  xi->tx_sring_gref = XnGrantAccess(xi->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENNET_POOL_TAG);
   6.647 -  FUNCTION_MSG("tx sring_gref = %d\n", xi->tx_sring_gref);
   6.648 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "tx-ring-ref", xi->tx_sring_gref);  
   6.649 -  xi->rx_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENNET_POOL_TAG);
   6.650 -  if (!xi->rx_sring) {
   6.651 -    FUNCTION_MSG("Cannot allocate rx_sring\n");
   6.652 -    status = NDIS_STATUS_RESOURCES;
   6.653 -    goto err;
   6.654 -  }
   6.655 -  SHARED_RING_INIT(xi->rx_sring);
   6.656 -  FRONT_RING_INIT(&xi->rx_ring, xi->rx_sring, PAGE_SIZE);
   6.657 -  pfn = MmGetPhysicalAddress(xi->rx_sring).QuadPart >> PAGE_SHIFT;
   6.658 -  FUNCTION_MSG("rx sring pfn = %d\n", (ULONG)pfn);
   6.659 -  xi->rx_sring_gref = XnGrantAccess(xi->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENNET_POOL_TAG);
   6.660 -  FUNCTION_MSG("rx sring_gref = %d\n", xi->rx_sring_gref);
   6.661 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "rx-ring-ref", xi->rx_sring_gref);  
   6.662 +  KeInitializeEvent(&xi->backend_event, SynchronizationEvent, FALSE);
   6.663  
   6.664    xi->rx_target     = RX_DFL_MIN_TARGET;
   6.665    xi->rx_min_target = RX_DFL_MIN_TARGET;
   6.666 @@ -540,14 +363,7 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   6.667      | NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED
   6.668      | NDIS_STATISTICS_XMIT_DISCARDS_SUPPORTED;
   6.669  
   6.670 -#if 0    
   6.671 -  KeInitializeDpc(&xi->suspend_dpc, XenNet_SuspendResume, xi);
   6.672 -  KeInitializeSpinLock(&xi->resume_lock);
   6.673 -#endif
   6.674 -
   6.675    KeInitializeDpc(&xi->rxtx_dpc, XenNet_RxTxDpc, xi);
   6.676 -  KeSetTargetProcessorDpc(&xi->rxtx_dpc, 0);
   6.677 -  KeSetImportanceDpc(&xi->rxtx_dpc, HighImportance);
   6.678  
   6.679    xi->packet_filter = 0;
   6.680  
   6.681 @@ -559,13 +375,8 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   6.682      goto err;
   6.683    }
   6.684  
   6.685 -  XnGetValue(xi->handle, XN_VALUE_TYPE_QEMU_HIDE_FLAGS, &qemu_hide_flags_value);
   6.686 -  XnGetValue(xi->handle, XN_VALUE_TYPE_QEMU_FILTER, &qemu_hide_filter);
   6.687 -  if ((qemu_hide_flags_value & QEMU_UNPLUG_ALL_NICS) || qemu_hide_filter)
   6.688 -    xi->inactive = FALSE;
   6.689 -
   6.690 -  xi->power_state = NdisDeviceStateD0;
   6.691 -  xi->power_workitem = IoAllocateWorkItem(xi->fdo);
   6.692 +  //xi->power_state = NdisDeviceStateD0;
   6.693 +  //xi->power_workitem = IoAllocateWorkItem(xi->fdo);
   6.694  
   6.695    config_object.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);
   6.696    config_object.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
   6.697 @@ -670,81 +481,7 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   6.698  
   6.699    NdisCloseConfiguration(config_handle);
   6.700  
   6.701 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "request-rx-copy", 1);
   6.702 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "request-rx-notify", 1);
   6.703 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-no-csum-offload", !xi->frontend_csum_supported);
   6.704 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-sg", (int)xi->frontend_sg_supported);
   6.705 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-gso-tcpv4", !!xi->frontend_gso_value);
   6.706 -
   6.707 -  status = XnReadInt32(xi->handle, XN_BASE_BACKEND, "feature-sg", &tmp_ulong);
   6.708 -  if (tmp_ulong) {
   6.709 -    xi->backend_sg_supported = TRUE;
   6.710 -  }
   6.711 -  status = XnReadInt32(xi->handle, XN_BASE_BACKEND, "feature-gso-tcpv4", &tmp_ulong);
   6.712 -  if (tmp_ulong) {
   6.713 -    xi->backend_gso_value = xi->frontend_gso_value;
   6.714 -  }
   6.715 -
   6.716 -  status = XnReadString(xi->handle, XN_BASE_BACKEND, "mac", &tmp_string);
   6.717 -  state = 0;
   6.718 -  octet = 0;
   6.719 -  for (i = 0; state != 3 && i < strlen(tmp_string); i++) {
   6.720 -    if (octet == 6) {
   6.721 -FUNCTION_MSG("AAA - i = %d, state = %d, octet = %d\n", i, state, octet);
   6.722 -      state = 3;
   6.723 -      break;
   6.724 -    }
   6.725 -    switch(state) {
   6.726 -    case 0:
   6.727 -    case 1:
   6.728 -      if (tmp_string[i] >= '0' && tmp_string[i] <= '9') {
   6.729 -        xi->perm_mac_addr[octet] |= (tmp_string[i] - '0') << ((1 - state) * 4);
   6.730 -        state++;
   6.731 -      } else if (tmp_string[i] >= 'A' && tmp_string[i] <= 'F') {
   6.732 -        xi->perm_mac_addr[octet] |= (tmp_string[i] - 'A' + 10) << ((1 - state) * 4);
   6.733 -        state++;
   6.734 -      } else if (tmp_string[i] >= 'a' && tmp_string[i] <= 'f') {
   6.735 -        xi->perm_mac_addr[octet] |= (tmp_string[i] - 'a' + 10) << ((1 - state) * 4);
   6.736 -        state++;
   6.737 -      } else {
   6.738 -        state = 3;
   6.739 -      }
   6.740 -      break;
   6.741 -    case 2:
   6.742 -      if (tmp_string[i] == ':') {
   6.743 -        octet++;
   6.744 -        state = 0;
   6.745 -      } else {
   6.746 -        state = 3;
   6.747 -      }
   6.748 -      break;
   6.749 -    }
   6.750 -  }
   6.751 -  if (octet != 5 || state != 2) {
   6.752 -    FUNCTION_MSG("Failed to parse backend MAC address %s\n", tmp_string);
   6.753 -    XnFreeMem(xi->handle, tmp_string);
   6.754 -    status = NDIS_STATUS_FAILURE;
   6.755 -    goto err;
   6.756 -  } else if ((xi->curr_mac_addr[0] & 0x03) != 0x02) {
   6.757 -    /* only copy if curr_mac_addr is not a LUA */
   6.758 -    memcpy(xi->curr_mac_addr, xi->perm_mac_addr, ETH_ALEN);
   6.759 -  }
   6.760 -  XnFreeMem(xi->handle, tmp_string);
   6.761 -  FUNCTION_MSG("MAC address is %02X:%02X:%02X:%02X:%02X:%02X\n",
   6.762 -    xi->curr_mac_addr[0], xi->curr_mac_addr[1], xi->curr_mac_addr[2], 
   6.763 -    xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5]);
   6.764 -
   6.765 -  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "state", XenbusStateConnected);
   6.766 -
   6.767 -  for (i = 0; i <= 5 && xi->backend_state != XenbusStateConnected; i++) {
   6.768 -    NdisWaitEvent(&xi->backend_event, 1000);
   6.769 -  }
   6.770 -  NdisResetEvent(&xi->backend_event);
   6.771 -  if (xi->backend_state != XenbusStateConnected) {
   6.772 -    FUNCTION_MSG("Backend state timeout\n");
   6.773 -    status = NDIS_STATUS_RESOURCES;
   6.774 -    goto err;
   6.775 -  }
   6.776 +  XenNet_Connect(xi, FALSE);
   6.777  
   6.778    if (!xi->backend_sg_supported)
   6.779      xi->backend_gso_value = min(xi->backend_gso_value, PAGE_SIZE - MAX_PKT_HEADER_LENGTH);
   6.780 @@ -955,9 +692,7 @@ FUNCTION_MSG("AAA - i = %d, state = %d, 
   6.781      //what about backfill here?
   6.782    }
   6.783    #endif
   6.784 -  XenNet_TxInit(xi);
   6.785 -  XenNet_RxInit(xi);
   6.786 -  xi->connected = TRUE;
   6.787 +  xi->device_state = DEVICE_STATE_ACTIVE;
   6.788    FUNCTION_EXIT();
   6.789    return NDIS_STATUS_SUCCESS;
   6.790    
   6.791 @@ -1020,18 +755,7 @@ XenNet_Halt(NDIS_HANDLE adapter_context,
   6.792    UNREFERENCED_PARAMETER(halt_action);
   6.793  
   6.794    FUNCTION_ENTER();
   6.795 -  
   6.796 -  xi->shutting_down = TRUE;
   6.797 -  KeMemoryBarrier(); /* make sure everyone sees that we are now shutting down */
   6.798 -
   6.799 -  XenNet_TxShutdown(xi);
   6.800 -  XenNet_RxShutdown(xi);
   6.801 -
   6.802 -  xi->connected = FALSE;
   6.803 -  KeMemoryBarrier(); /* make sure everyone sees that we are now disconnected */
   6.804 -
   6.805 -  //xi->vectors.XenPci_XenShutdownDevice(xi->vectors.context);
   6.806 -
   6.807 +  XenNet_Disconnect(xi, FALSE);
   6.808    NdisFreeMemory(xi, 0, 0);
   6.809  
   6.810    FUNCTION_EXIT();
     7.1 --- a/xennet/xennet6.h	Sun Jan 06 14:08:22 2013 +1100
     7.2 +++ b/xennet/xennet6.h	Sat Feb 02 18:51:07 2013 +1100
     7.3 @@ -260,9 +260,15 @@ typedef struct {
     7.4  /* don't split incoming large packets. not really useful */
     7.5  #define RX_LSO_SPLIT_NONE 2
     7.6  
     7.7 +#define DEVICE_STATE_DISCONNECTED  0 /* -> INITIALISING */
     7.8 +#define DEVICE_STATE_INITIALISING  1 /* -> ACTIVE or INACTIVE */
     7.9 +#define DEVICE_STATE_INACTIVE      2
    7.10 +#define DEVICE_STATE_ACTIVE        3 /* -> DISCONNECTING */
    7.11 +#define DEVICE_STATE_DISCONNECTING 4 /* -> DISCONNECTED */
    7.12 +
    7.13  struct xennet_info
    7.14  {
    7.15 -  BOOLEAN inactive;
    7.16 +  ULONG device_state;
    7.17    
    7.18    /* Base device vars */
    7.19    PDEVICE_OBJECT pdo;
    7.20 @@ -274,16 +280,13 @@ struct xennet_info
    7.21    /* NDIS-related vars */
    7.22    NDIS_HANDLE adapter_handle;
    7.23    ULONG packet_filter;
    7.24 -  BOOLEAN connected;
    7.25 -  BOOLEAN shutting_down;
    7.26 -  BOOLEAN tx_shutting_down;
    7.27 -  BOOLEAN rx_shutting_down;
    7.28 +  //BOOLEAN connected;
    7.29    uint8_t perm_mac_addr[ETH_ALEN];
    7.30    uint8_t curr_mac_addr[ETH_ALEN];
    7.31    ULONG current_lookahead;
    7.32 -  NDIS_DEVICE_POWER_STATE new_power_state;
    7.33 -  NDIS_DEVICE_POWER_STATE power_state;
    7.34 -  PIO_WORKITEM power_workitem;
    7.35 +  //NDIS_DEVICE_POWER_STATE new_power_state;
    7.36 +  //NDIS_DEVICE_POWER_STATE power_state;
    7.37 +  //PIO_WORKITEM power_workitem;
    7.38  
    7.39    /* Misc. Xen vars */
    7.40    XN_HANDLE handle;
    7.41 @@ -294,35 +297,33 @@ struct xennet_info
    7.42    //ULONG state;
    7.43    //char backend_path[MAX_XENBUS_STR_LEN];
    7.44    ULONG backend_state;
    7.45 -  NDIS_EVENT backend_event;
    7.46 +  KEVENT backend_event;
    7.47    //PVOID config_page;
    7.48    UCHAR multicast_list[MULTICAST_LIST_MAX_SIZE][6];
    7.49    ULONG multicast_list_size;
    7.50 -  KDPC suspend_dpc;
    7.51 -  PIO_WORKITEM resume_work_item;
    7.52 -  KSPIN_LOCK resume_lock;
    7.53 +  //KDPC suspend_dpc;
    7.54 +  //PIO_WORKITEM resume_work_item;
    7.55 +  //KSPIN_LOCK resume_lock;
    7.56    KDPC rxtx_dpc;
    7.57  
    7.58    /* tx related - protected by tx_lock */
    7.59 -  KSPIN_LOCK tx_lock;
    7.60 +  KSPIN_LOCK tx_lock; /* always acquire rx_lock before tx_lock */
    7.61    LIST_ENTRY tx_waiting_pkt_list;
    7.62    netif_tx_sring_t *tx_sring;
    7.63    grant_ref_t tx_sring_gref;
    7.64    struct netif_tx_front_ring tx_ring;
    7.65    ULONG tx_ring_free;
    7.66    tx_shadow_t tx_shadows[NET_TX_RING_SIZE];
    7.67 -  //NDIS_HANDLE tx_buffer_pool;
    7.68  #define TX_HEADER_BUFFER_SIZE 512
    7.69 -//#define TX_COALESCE_BUFFERS (NET_TX_RING_SIZE >> 2)
    7.70  #define TX_COALESCE_BUFFERS (NET_TX_RING_SIZE)
    7.71 -  KEVENT tx_idle_event;
    7.72    ULONG tx_outstanding;
    7.73    ULONG tx_id_free;
    7.74    USHORT tx_id_list[NET_TX_RING_SIZE];
    7.75    NPAGED_LOOKASIDE_LIST tx_lookaside_list;
    7.76 +  KEVENT tx_idle_event;
    7.77  
    7.78    /* rx_related - protected by rx_lock */
    7.79 -  KSPIN_LOCK rx_lock;
    7.80 +  KSPIN_LOCK rx_lock; /* always acquire rx_lock before tx_lock */
    7.81    netif_rx_sring_t *rx_sring;
    7.82    grant_ref_t rx_sring_gref;
    7.83    struct netif_rx_front_ring rx_ring;
    7.84 @@ -343,10 +344,11 @@ struct xennet_info
    7.85    shared_buffer_t *rx_partial_buf;
    7.86    BOOLEAN rx_partial_extra_info_flag ;
    7.87    BOOLEAN rx_partial_more_data_flag;
    7.88 -
    7.89 +  KEVENT rx_idle_event;
    7.90    /* how many packets are in the net stack atm */
    7.91    LONG rx_outstanding;
    7.92  
    7.93 +
    7.94    /* config vars from registry */
    7.95    /* the frontend_* indicate our willingness to support */
    7.96    BOOLEAN frontend_sg_supported;
    7.97 @@ -400,35 +402,13 @@ MINIPORT_CANCEL_SEND XenNet_CancelSend;
    7.98  
    7.99  MINIPORT_RETURN_NET_BUFFER_LISTS XenNet_ReturnNetBufferLists;
   7.100  
   7.101 -BOOLEAN
   7.102 -XenNet_RxInit(xennet_info_t *xi);
   7.103 -
   7.104 -BOOLEAN
   7.105 -XenNet_RxShutdown(xennet_info_t *xi);
   7.106 -
   7.107 -VOID
   7.108 -XenNet_RxResumeStart(xennet_info_t *xi);
   7.109 -
   7.110 -VOID
   7.111 -XenNet_RxResumeEnd(xennet_info_t *xi);
   7.112 +BOOLEAN XenNet_RxInit(xennet_info_t *xi);
   7.113 +VOID XenNet_RxShutdown(xennet_info_t *xi);
   7.114 +BOOLEAN XenNet_RxBufferCheck(struct xennet_info *xi);
   7.115  
   7.116 -BOOLEAN
   7.117 -XenNet_RxBufferCheck(struct xennet_info *xi);
   7.118 -
   7.119 -VOID
   7.120 -XenNet_TxResumeStart(xennet_info_t *xi);
   7.121 -
   7.122 -VOID
   7.123 -XenNet_TxResumeEnd(xennet_info_t *xi);
   7.124 -
   7.125 -BOOLEAN
   7.126 -XenNet_TxInit(xennet_info_t *xi);
   7.127 -
   7.128 -BOOLEAN
   7.129 -XenNet_TxShutdown(xennet_info_t *xi);
   7.130 -
   7.131 -VOID
   7.132 -XenNet_TxBufferGC(struct xennet_info *xi, BOOLEAN dont_set_event);
   7.133 +BOOLEAN XenNet_TxInit(xennet_info_t *xi);
   7.134 +BOOLEAN XenNet_TxShutdown(xennet_info_t *xi);
   7.135 +VOID XenNet_TxBufferGC(struct xennet_info *xi, BOOLEAN dont_set_event);
   7.136  
   7.137  #if 0
   7.138  NDIS_STATUS
     8.1 --- a/xennet/xennet6_oid.c	Sun Jan 06 14:08:22 2013 +1100
     8.2 +++ b/xennet/xennet6_oid.c	Sat Feb 02 18:51:07 2013 +1100
     8.3 @@ -91,7 +91,7 @@ DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_TRAN
     8.4  DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_RECEIVE_BLOCK_SIZE, PAGE_SIZE)
     8.5  DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_MAXIMUM_SEND_PACKETS, 0)
     8.6  DEF_OID_QUERY_ULONG_ROUTINE(OID_802_3_MAXIMUM_LIST_SIZE, MULTICAST_LIST_MAX_SIZE)
     8.7 -DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_HARDWARE_STATUS, xi->connected?NdisHardwareStatusReady:NdisHardwareStatusInitializing)
     8.8 +DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_HARDWARE_STATUS, (xi->device_state != DEVICE_STATE_INACTIVE)?NdisHardwareStatusReady:NdisHardwareStatusInitializing)
     8.9  DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_VENDOR_ID, 0xFFFFFF) // Not guaranteed to be XENSOURCE_MAC_HDR;
    8.10  DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_VENDOR_DRIVER_VERSION, VENDOR_DRIVER_VERSION)
    8.11  DEF_OID_QUERY_ULONG_ROUTINE(OID_GEN_MEDIA_SUPPORTED, NdisMedium802_3)
     9.1 --- a/xennet/xennet6_rx.c	Sun Jan 06 14:08:22 2013 +1100
     9.2 +++ b/xennet/xennet6_rx.c	Sat Feb 02 18:51:07 2013 +1100
     9.3 @@ -35,7 +35,7 @@ get_pb_from_freelist(struct xennet_info 
     9.4    }
     9.5  
     9.6    /* don't allocate a new one if we are shutting down */
     9.7 -  if (xi->shutting_down)
     9.8 +  if (xi->device_state != DEVICE_STATE_INITIALISING && xi->device_state != DEVICE_STATE_ACTIVE)
     9.9      return NULL;
    9.10      
    9.11    pb = NdisAllocateMemoryWithTagPriority(xi->adapter_handle, sizeof(shared_buffer_t), XENNET_POOL_TAG, LowPoolPriority);
    9.12 @@ -112,7 +112,7 @@ get_hb_from_freelist(struct xennet_info 
    9.13    }
    9.14  
    9.15    /* don't allocate a new one if we are shutting down */
    9.16 -  if (xi->shutting_down)
    9.17 +  if (xi->device_state != DEVICE_STATE_INITIALISING && xi->device_state != DEVICE_STATE_ACTIVE)
    9.18      return NULL;
    9.19      
    9.20    hb = NdisAllocateMemoryWithTagPriority(xi->adapter_handle, sizeof(shared_buffer_t) + MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH, XENNET_POOL_TAG, LowPoolPriority);
    9.21 @@ -120,8 +120,7 @@ get_hb_from_freelist(struct xennet_info 
    9.22      return NULL;
    9.23    NdisZeroMemory(hb, sizeof(shared_buffer_t));
    9.24    hb->mdl = IoAllocateMdl(hb + 1, MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH, FALSE, FALSE, NULL);
    9.25 -  if (!hb->mdl)
    9.26 -  {
    9.27 +  if (!hb->mdl) {
    9.28      NdisFreeMemory(hb, sizeof(shared_buffer_t) + MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH, 0);
    9.29      return NULL;
    9.30    }
    9.31 @@ -155,17 +154,14 @@ XenNet_FillRing(struct xennet_info *xi)
    9.32  
    9.33    batch_target = xi->rx_target - (req_prod - xi->rx_ring.rsp_cons);
    9.34  
    9.35 -  if (batch_target < (xi->rx_target >> 2))
    9.36 -  {
    9.37 +  if (batch_target < (xi->rx_target >> 2)) {
    9.38      //FUNCTION_EXIT();
    9.39      return NDIS_STATUS_SUCCESS; /* only refill if we are less than 3/4 full already */
    9.40    }
    9.41  
    9.42 -  for (i = 0; i < batch_target; i++)
    9.43 -  {
    9.44 +  for (i = 0; i < batch_target; i++) {
    9.45      page_buf = get_pb_from_freelist(xi);
    9.46 -    if (!page_buf)
    9.47 -    {
    9.48 +    if (!page_buf) {
    9.49        KdPrint((__DRIVER_NAME "     Added %d out of %d buffers to rx ring (no free pages)\n", i, batch_target));
    9.50        break;
    9.51      }
    9.52 @@ -183,8 +179,7 @@ XenNet_FillRing(struct xennet_info *xi)
    9.53    KeMemoryBarrier();
    9.54    xi->rx_ring.req_prod_pvt = req_prod + i;
    9.55    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xi->rx_ring, notify);
    9.56 -  if (notify)
    9.57 -  {
    9.58 +  if (notify) {
    9.59      XnNotify(xi->handle, xi->event_channel);
    9.60    }
    9.61  
    9.62 @@ -562,8 +557,8 @@ XenNet_ReturnNetBufferLists(NDIS_HANDLE 
    9.63      curr_nbl = next_nbl;
    9.64    }
    9.65    
    9.66 -  if (!xi->rx_outstanding && xi->rx_shutting_down)
    9.67 -    KeSetEvent(&xi->packet_returned_event, IO_NO_INCREMENT, FALSE);
    9.68 +  if (!xi->rx_outstanding && xi->device_state != DEVICE_STATE_ACTIVE)
    9.69 +    KeSetEvent(&xi->rx_idle_event, IO_NO_INCREMENT, FALSE);
    9.70  
    9.71    //FUNCTION_EXIT();
    9.72  }
    9.73 @@ -602,9 +597,6 @@ XenNet_RxBufferCheck(struct xennet_info 
    9.74    BOOLEAN dont_set_event;
    9.75    //FUNCTION_ENTER();
    9.76  
    9.77 -  if (!xi->connected)
    9.78 -    return FALSE; /* a delayed DPC could let this come through... just do nothing */
    9.79 -
    9.80    rc.first_nbl = NULL;
    9.81    rc.last_nbl = NULL;
    9.82    rc.packet_count = 0;
    9.83 @@ -613,15 +605,13 @@ XenNet_RxBufferCheck(struct xennet_info 
    9.84    /* get all the buffers off the ring as quickly as possible so the lock is held for a minimum amount of time */
    9.85    KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
    9.86    
    9.87 -  if (xi->rx_shutting_down)
    9.88 -  {
    9.89 +  if (xi->device_state != DEVICE_STATE_ACTIVE) {
    9.90      /* there is a chance that our Dpc had been queued just before the shutdown... */
    9.91      KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
    9.92      return FALSE;
    9.93    }
    9.94  
    9.95 -  if (xi->rx_partial_buf)
    9.96 -  {
    9.97 +  if (xi->rx_partial_buf) {
    9.98      head_buf = xi->rx_partial_buf;
    9.99      tail_buf = xi->rx_partial_buf;
   9.100      while (tail_buf->next)
   9.101 @@ -635,19 +625,15 @@ XenNet_RxBufferCheck(struct xennet_info 
   9.102      prod = xi->rx_ring.sring->rsp_prod;
   9.103      KeMemoryBarrier(); /* Ensure we see responses up to 'prod'. */
   9.104  
   9.105 -    for (cons = xi->rx_ring.rsp_cons; cons != prod && packet_count < MAXIMUM_PACKETS_PER_INTERRUPT && packet_data < MAXIMUM_DATA_PER_INTERRUPT; cons++)
   9.106 -    {
   9.107 +    for (cons = xi->rx_ring.rsp_cons; cons != prod && packet_count < MAXIMUM_PACKETS_PER_INTERRUPT && packet_data < MAXIMUM_DATA_PER_INTERRUPT; cons++) {
   9.108        id = (USHORT)(cons & (NET_RX_RING_SIZE - 1));
   9.109        page_buf = xi->rx_ring_pbs[id];
   9.110        NT_ASSERT(page_buf);
   9.111        xi->rx_ring_pbs[id] = NULL;
   9.112        xi->rx_id_free++;
   9.113        memcpy(&page_buf->rsp, RING_GET_RESPONSE(&xi->rx_ring, cons), max(sizeof(struct netif_rx_response), sizeof(struct netif_extra_info)));
   9.114 -      if (!extra_info_flag)
   9.115 -      {
   9.116 -        if (page_buf->rsp.status <= 0
   9.117 -          || page_buf->rsp.offset + page_buf->rsp.status > PAGE_SIZE)
   9.118 -        {
   9.119 +      if (!extra_info_flag) {
   9.120 +        if (page_buf->rsp.status <= 0 || page_buf->rsp.offset + page_buf->rsp.status > PAGE_SIZE) {
   9.121            KdPrint((__DRIVER_NAME "     Error: rsp offset %d, size %d\n",
   9.122              page_buf->rsp.offset, page_buf->rsp.status));
   9.123            NT_ASSERT(!extra_info_flag);
   9.124 @@ -656,32 +642,25 @@ XenNet_RxBufferCheck(struct xennet_info 
   9.125          }
   9.126        }
   9.127        
   9.128 -      if (!head_buf)
   9.129 -      {
   9.130 +      if (!head_buf) {
   9.131          head_buf = page_buf;
   9.132          tail_buf = page_buf;
   9.133 -      }
   9.134 -      else
   9.135 -      {
   9.136 +      } else {
   9.137          tail_buf->next = page_buf;
   9.138          tail_buf = page_buf;
   9.139        }
   9.140        page_buf->next = NULL;
   9.141  
   9.142 -      if (extra_info_flag)
   9.143 -      {
   9.144 +      if (extra_info_flag) {
   9.145          ei = (struct netif_extra_info *)&page_buf->rsp;
   9.146          extra_info_flag = ei->flags & XEN_NETIF_EXTRA_FLAG_MORE;
   9.147 -      }
   9.148 -      else
   9.149 -      {
   9.150 +      } else {
   9.151          more_data_flag = (BOOLEAN)(page_buf->rsp.flags & NETRXF_more_data);
   9.152          extra_info_flag = (BOOLEAN)(page_buf->rsp.flags & NETRXF_extra_info);
   9.153          interim_packet_data += page_buf->rsp.status;
   9.154        }
   9.155        
   9.156 -      if (!extra_info_flag && !more_data_flag)
   9.157 -      {
   9.158 +      if (!extra_info_flag && !more_data_flag) {
   9.159          last_buf = page_buf;
   9.160          packet_count++;
   9.161          packet_data += interim_packet_data;
   9.162 @@ -698,8 +677,7 @@ XenNet_RxBufferCheck(struct xennet_info 
   9.163        break;
   9.164  
   9.165      more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xi->rx_ring);
   9.166 -    if (!more_to_do)
   9.167 -    {
   9.168 +    if (!more_to_do) {
   9.169        xi->rx_ring.sring->rsp_event = xi->rx_ring.rsp_cons + 1;
   9.170        KeMemoryBarrier();
   9.171        more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xi->rx_ring);
   9.172 @@ -833,129 +811,73 @@ XenNet_RxBufferCheck(struct xennet_info 
   9.173    return dont_set_event;
   9.174  }
   9.175  
   9.176 -/*
   9.177 -   Free all Rx buffers (on halt, for example) 
   9.178 -   The ring must be stopped at this point.
   9.179 -*/
   9.180 -
   9.181  static VOID
   9.182 -XenNet_PurgeRing(xennet_info_t *xi)
   9.183 +XenNet_BufferFree(xennet_info_t *xi)
   9.184  {
   9.185 +  shared_buffer_t *sb;
   9.186    int i;
   9.187 -  for (i = 0; i < NET_RX_RING_SIZE; i++)
   9.188 -  {
   9.189 -    if (xi->rx_ring_pbs[i] != NULL)
   9.190 -    {
   9.191 +
   9.192 +  for (i = 0; i < NET_RX_RING_SIZE; i++) {
   9.193 +    if (xi->rx_ring_pbs[i] != NULL) {
   9.194        put_pb_on_freelist(xi, xi->rx_ring_pbs[i]);
   9.195        xi->rx_ring_pbs[i] = NULL;
   9.196      }
   9.197    }
   9.198 -}
   9.199 -
   9.200 -static VOID
   9.201 -XenNet_BufferFree(xennet_info_t *xi)
   9.202 -{
   9.203 -  shared_buffer_t *sb;
   9.204 -
   9.205 -  XenNet_PurgeRing(xi);
   9.206  
   9.207    /* because we are shutting down this won't allocate new ones */
   9.208 -  while ((sb = get_pb_from_freelist(xi)) != NULL)
   9.209 -  {
   9.210 +  while ((sb = get_pb_from_freelist(xi)) != NULL) {
   9.211      XnEndAccess(xi->handle,
   9.212          sb->gref, FALSE, (ULONG)'XNRX');
   9.213      IoFreeMdl(sb->mdl);
   9.214      NdisFreeMemory(sb->virtual, sizeof(shared_buffer_t), 0);
   9.215      NdisFreeMemory(sb, PAGE_SIZE, 0);
   9.216    }
   9.217 -  while ((sb = get_hb_from_freelist(xi)) != NULL)
   9.218 -  {
   9.219 +  while ((sb = get_hb_from_freelist(xi)) != NULL) {
   9.220      IoFreeMdl(sb->mdl);
   9.221      NdisFreeMemory(sb, sizeof(shared_buffer_t) + MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH, 0);
   9.222    }
   9.223  }
   9.224  
   9.225 -VOID
   9.226 -XenNet_BufferAlloc(xennet_info_t *xi)
   9.227 -{
   9.228 -  //NDIS_STATUS status;
   9.229 -  int i;
   9.230 -  
   9.231 -  xi->rx_id_free = NET_RX_RING_SIZE;
   9.232 -  xi->rx_outstanding = 0;
   9.233 -
   9.234 -  for (i = 0; i < NET_RX_RING_SIZE; i++)
   9.235 -  {
   9.236 -    xi->rx_ring_pbs[i] = NULL;
   9.237 -  }
   9.238 -}
   9.239 -
   9.240 -VOID
   9.241 -XenNet_RxResumeStart(xennet_info_t *xi)
   9.242 -{
   9.243 -  KIRQL old_irql;
   9.244 -
   9.245 -  FUNCTION_ENTER();
   9.246 -
   9.247 -  KeAcquireSpinLock(&xi->rx_lock, &old_irql);
   9.248 -  XenNet_PurgeRing(xi);
   9.249 -  KeReleaseSpinLock(&xi->rx_lock, old_irql);
   9.250 -  
   9.251 -  FUNCTION_EXIT();
   9.252 -}
   9.253 -
   9.254 -VOID
   9.255 -XenNet_RxResumeEnd(xennet_info_t *xi)
   9.256 -{
   9.257 -  KIRQL old_irql;
   9.258 -
   9.259 -  FUNCTION_ENTER();
   9.260 -
   9.261 -  KeAcquireSpinLock(&xi->rx_lock, &old_irql);
   9.262 -  //XenNet_BufferAlloc(xi);
   9.263 -  XenNet_FillRing(xi);
   9.264 -  KeReleaseSpinLock(&xi->rx_lock, old_irql);
   9.265 -  
   9.266 -  FUNCTION_EXIT();
   9.267 -}
   9.268 -
   9.269  BOOLEAN
   9.270  XenNet_RxInit(xennet_info_t *xi)
   9.271  {
   9.272    NET_BUFFER_LIST_POOL_PARAMETERS nbl_pool_parameters;
   9.273    NET_BUFFER_POOL_PARAMETERS nb_pool_parameters;
   9.274    int ret;
   9.275 -
   9.276 +  int i;
   9.277 +  
   9.278    FUNCTION_ENTER();
   9.279  
   9.280 -  xi->rx_shutting_down = FALSE;
   9.281 +  // this stuff needs to be done once only...
   9.282    KeInitializeSpinLock(&xi->rx_lock);
   9.283    KeInitializeEvent(&xi->packet_returned_event, SynchronizationEvent, FALSE);
   9.284    xi->rxpi = NdisAllocateMemoryWithTagPriority(xi->adapter_handle, sizeof(packet_info_t) * NdisSystemProcessorCount(), XENNET_POOL_TAG, NormalPoolPriority);
   9.285 -  if (!xi->rxpi)
   9.286 -  {
   9.287 +  if (!xi->rxpi) {
   9.288      KdPrint(("NdisAllocateMemoryWithTagPriority failed\n"));
   9.289      return FALSE;
   9.290    }
   9.291    NdisZeroMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount());
   9.292  
   9.293    ret = stack_new(&xi->rx_pb_stack, NET_RX_RING_SIZE * 4);
   9.294 -  if (!ret)
   9.295 -  {
   9.296 +  if (!ret) {
   9.297      FUNCTION_MSG("Failed to allocate rx_pb_stack\n");
   9.298      NdisFreeMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount(), 0);
   9.299      return FALSE;
   9.300    }
   9.301    stack_new(&xi->rx_hb_stack, NET_RX_RING_SIZE * 4);
   9.302 -  if (!ret)
   9.303 -  {
   9.304 +  if (!ret) {
   9.305      FUNCTION_MSG("Failed to allocate rx_hb_stack\n");
   9.306      stack_delete(xi->rx_pb_stack, NULL, NULL);
   9.307      NdisFreeMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount(), 0);
   9.308      return FALSE;
   9.309    }
   9.310  
   9.311 -  XenNet_BufferAlloc(xi);
   9.312 +  xi->rx_id_free = NET_RX_RING_SIZE;
   9.313 +  xi->rx_outstanding = 0;
   9.314 +
   9.315 +  for (i = 0; i < NET_RX_RING_SIZE; i++) {
   9.316 +    xi->rx_ring_pbs[i] = NULL;
   9.317 +  }
   9.318    
   9.319    nbl_pool_parameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
   9.320    nbl_pool_parameters.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
   9.321 @@ -967,8 +889,7 @@ XenNet_RxInit(xennet_info_t *xi)
   9.322    nbl_pool_parameters.DataSize = 0; /* NET_BUFFERS are always allocated separately */
   9.323    
   9.324    xi->rx_nbl_pool = NdisAllocateNetBufferListPool(xi->adapter_handle, &nbl_pool_parameters);
   9.325 -  if (!xi->rx_nbl_pool)
   9.326 -  {
   9.327 +  if (!xi->rx_nbl_pool) {
   9.328      KdPrint(("NdisAllocateNetBufferListPool failed\n"));
   9.329      return FALSE;
   9.330    }
   9.331 @@ -979,8 +900,7 @@ XenNet_RxInit(xennet_info_t *xi)
   9.332    nb_pool_parameters.PoolTag = XENNET_POOL_TAG;
   9.333    nb_pool_parameters.DataSize = 0; /* the buffers come from the ring */
   9.334    xi->rx_nb_pool = NdisAllocateNetBufferPool(xi->adapter_handle, &nb_pool_parameters);
   9.335 -  if (!xi->rx_nb_pool)
   9.336 -  {
   9.337 +  if (!xi->rx_nb_pool) {
   9.338      KdPrint(("NdisAllocateNetBufferPool (rx_nb_pool) failed\n"));
   9.339      return FALSE;
   9.340    }
   9.341 @@ -992,39 +912,32 @@ XenNet_RxInit(xennet_info_t *xi)
   9.342    return TRUE;
   9.343  }
   9.344  
   9.345 -BOOLEAN
   9.346 -XenNet_RxShutdown(xennet_info_t *xi)
   9.347 -{
   9.348 +VOID
   9.349 +XenNet_RxShutdown(xennet_info_t *xi) {
   9.350    KIRQL old_irql;
   9.351 -  //PNDIS_PACKET packet;
   9.352    UNREFERENCED_PARAMETER(xi);
   9.353  
   9.354    FUNCTION_ENTER();
   9.355  
   9.356    KeAcquireSpinLock(&xi->rx_lock, &old_irql);
   9.357 -  xi->rx_shutting_down = TRUE;
   9.358 +  while (xi->rx_outstanding) {
   9.359 +    KdPrint((__DRIVER_NAME "     Waiting for all packets to be returned\n"));
   9.360 +    KeReleaseSpinLock(&xi->rx_lock, old_irql);
   9.361 +    KeWaitForSingleObject(&xi->rx_idle_event, Executive, KernelMode, FALSE, NULL);
   9.362 +    KeAcquireSpinLock(&xi->rx_lock, &old_irql);
   9.363 +  }
   9.364    KeReleaseSpinLock(&xi->rx_lock, old_irql);
   9.365 -
   9.366 -  KeFlushQueuedDpcs();
   9.367 -
   9.368 -  while (xi->rx_outstanding)
   9.369 -  {
   9.370 -    KdPrint((__DRIVER_NAME "     Waiting for all packets to be returned\n"));
   9.371 -    KeWaitForSingleObject(&xi->packet_returned_event, Executive, KernelMode, FALSE, NULL);
   9.372 -  }
   9.373 -
   9.374 -  NdisFreeMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount(), 0);
   9.375 -
   9.376 +  
   9.377    XenNet_BufferFree(xi);
   9.378  
   9.379 -
   9.380    stack_delete(xi->rx_pb_stack, NULL, NULL);
   9.381    stack_delete(xi->rx_hb_stack, NULL, NULL);
   9.382    
   9.383 +  NdisFreeMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount(), 0);
   9.384 +
   9.385    NdisFreeNetBufferPool(xi->rx_nb_pool);
   9.386    NdisFreeNetBufferListPool(xi->rx_nbl_pool);
   9.387  
   9.388    FUNCTION_EXIT();
   9.389 -
   9.390 -  return TRUE;
   9.391 +  return;
   9.392  }
    10.1 --- a/xennet/xennet6_tx.c	Sun Jan 06 14:08:22 2013 +1100
    10.2 +++ b/xennet/xennet6_tx.c	Sat Feb 02 18:51:07 2013 +1100
    10.3 @@ -140,11 +140,10 @@ XenNet_HWSendPacket(struct xennet_info *
    10.4    }
    10.5  
    10.6    /* if we have enough space on the ring then we have enough id's so no need to check for that */
    10.7 -  if (xi->tx_ring_free < frags + 1)
    10.8 -  {
    10.9 +  if (xi->tx_ring_free < frags + 1) {
   10.10      XnFreeGrant(xi->handle, gref, (ULONG)'XNTX');
   10.11      NdisFreeToNPagedLookasideList(&xi->tx_lookaside_list, coalesce_buf);
   10.12 -    FUNCTION_MSG("Full on send - ring full\n");
   10.13 +    //FUNCTION_MSG("Full on send - ring full\n");
   10.14      return FALSE;
   10.15    }
   10.16    XenNet_ParsePacketHeader(&pi, coalesce_buf, PAGE_SIZE);
   10.17 @@ -427,11 +426,8 @@ XenNet_SendQueuedPackets(struct xennet_i
   10.18  
   10.19    //FUNCTION_ENTER();
   10.20  
   10.21 -  NT_ASSERT(!KeTestSpinLock(&xi->tx_lock));
   10.22 -#if 0
   10.23 -  if (xi->device_state->suspend_resume_state_pdo != SR_STATE_RUNNING)
   10.24 +  if (xi->device_state != DEVICE_STATE_ACTIVE)
   10.25      return;
   10.26 -#endif
   10.27  
   10.28    while (!IsListEmpty(&xi->tx_waiting_pkt_list)) {
   10.29      nb_entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
   10.30 @@ -464,15 +460,12 @@ XenNet_TxBufferGC(struct xennet_info *xi
   10.31  
   10.32    //FUNCTION_ENTER();
   10.33  
   10.34 -  if (!xi->connected)
   10.35 -    return; /* a delayed DPC could let this come through... just do nothing */
   10.36    NT_ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
   10.37  
   10.38    KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
   10.39  
   10.40  //  InitializeListHead(&nbl_head);
   10.41 -  if (xi->tx_shutting_down && !xi->tx_outstanding)
   10.42 -  {
   10.43 +  if (xi->device_state != DEVICE_STATE_ACTIVE && !xi->tx_outstanding) {
   10.44      /* there is a chance that our Dpc had been queued just before the shutdown... */
   10.45      KeSetEvent(&xi->tx_idle_event, IO_NO_INCREMENT, FALSE);
   10.46      KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
   10.47 @@ -568,8 +561,7 @@ XenNet_TxBufferGC(struct xennet_info *xi
   10.48    } while (prod != xi->tx_ring.sring->rsp_prod);
   10.49  
   10.50    /* if queued packets, send them now */
   10.51 -  if (!xi->tx_shutting_down)
   10.52 -    XenNet_SendQueuedPackets(xi);
   10.53 +  XenNet_SendQueuedPackets(xi);
   10.54  
   10.55    KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
   10.56  
   10.57 @@ -580,21 +572,11 @@ XenNet_TxBufferGC(struct xennet_info *xi
   10.58    /* must be done after we have truly given back all packets */
   10.59    KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
   10.60    xi->tx_outstanding -= tx_packets;
   10.61 -  if (!xi->tx_outstanding && xi->tx_shutting_down)
   10.62 +  if (xi->device_state != DEVICE_STATE_ACTIVE && !xi->tx_outstanding) {
   10.63      KeSetEvent(&xi->tx_idle_event, IO_NO_INCREMENT, FALSE);
   10.64 +  }
   10.65    KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
   10.66  
   10.67 -#if 0
   10.68 -  if (xi->device_state->suspend_resume_state_pdo == SR_STATE_SUSPENDING
   10.69 -    && xi->device_state->suspend_resume_state_fdo != SR_STATE_SUSPENDING
   10.70 -    && xi->tx_id_free == NET_TX_RING_SIZE)
   10.71 -  {
   10.72 -    KdPrint((__DRIVER_NAME "     Setting SR_STATE_SUSPENDING\n"));
   10.73 -    xi->device_state->suspend_resume_state_fdo = SR_STATE_SUSPENDING;
   10.74 -    KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xi->device_state->pdo_event_channel));
   10.75 -    XnNotify(xi->handle, xi->device_state->pdo_event_channel);
   10.76 -  }
   10.77 -#endif
   10.78    //FUNCTION_EXIT();
   10.79  }
   10.80  
   10.81 @@ -615,11 +597,9 @@ XenNet_SendNetBufferLists(
   10.82    UNREFERENCED_PARAMETER(port_number);
   10.83    //FUNCTION_ENTER();
   10.84  
   10.85 -  if (xi->inactive)
   10.86 -  {
   10.87 +  if (xi->device_state == DEVICE_STATE_INACTIVE) {
   10.88      curr_nbl = nb_lists;
   10.89 -    for (curr_nbl = nb_lists; curr_nbl; curr_nbl = NET_BUFFER_LIST_NEXT_NBL(curr_nbl))
   10.90 -    {
   10.91 +    for (curr_nbl = nb_lists; curr_nbl; curr_nbl = NET_BUFFER_LIST_NEXT_NBL(curr_nbl)) {
   10.92        //KdPrint((__DRIVER_NAME "     NBL %p\n", curr_nbl));
   10.93        curr_nbl->Status = NDIS_STATUS_FAILURE;
   10.94      }
   10.95 @@ -704,31 +684,16 @@ XenNet_CancelSend(NDIS_HANDLE adapter_co
   10.96    FUNCTION_EXIT();
   10.97  }
   10.98  
   10.99 +#if 0
  10.100  VOID
  10.101 -XenNet_TxResumeStart(xennet_info_t *xi)
  10.102 -{
  10.103 +XenNet_TxStartPre(xennet_info_t *xi) {
  10.104    UNREFERENCED_PARAMETER(xi);
  10.105  
  10.106    FUNCTION_ENTER();
  10.107    /* nothing to do here - all packets were already sent */
  10.108    FUNCTION_EXIT();
  10.109  }
  10.110 -
  10.111 -VOID
  10.112 -XenNet_TxResumeEnd(xennet_info_t *xi)
  10.113 -{
  10.114 -  KIRQL old_irql;
  10.115 -
  10.116 -  FUNCTION_ENTER();
  10.117 -
  10.118 -  UNREFERENCED_PARAMETER(xi);
  10.119 -
  10.120 -  KeAcquireSpinLock(&xi->tx_lock, &old_irql);
  10.121 -  //XenNet_SendQueuedPackets(xi);
  10.122 -  KeReleaseSpinLock(&xi->tx_lock, old_irql);
  10.123 -
  10.124 -  FUNCTION_EXIT();
  10.125 -}
  10.126 +#endif
  10.127  
  10.128  BOOLEAN
  10.129  XenNet_TxInit(xennet_info_t *xi)
  10.130 @@ -740,7 +705,6 @@ XenNet_TxInit(xennet_info_t *xi)
  10.131    InitializeListHead(&xi->tx_waiting_pkt_list);
  10.132  
  10.133    KeInitializeEvent(&xi->tx_idle_event, SynchronizationEvent, FALSE);
  10.134 -  xi->tx_shutting_down = FALSE;
  10.135    xi->tx_outstanding = 0;
  10.136    xi->tx_ring_free = NET_TX_RING_SIZE;
  10.137    
  10.138 @@ -765,40 +729,32 @@ on our freelists and harvest anything le
  10.139  BOOLEAN
  10.140  XenNet_TxShutdown(xennet_info_t *xi)
  10.141  {
  10.142 -  //PLIST_ENTRY entry;
  10.143 -  //PNDIS_PACKET packet;
  10.144 -  ////PMDL mdl;
  10.145 -  ////ULONG i;
  10.146 -  KIRQL old_irql;
  10.147    PNET_BUFFER nb;
  10.148    PNET_BUFFER_LIST nbl;
  10.149    PLIST_ENTRY nb_entry;
  10.150    LARGE_INTEGER timeout;
  10.151 +  KIRQL old_irql;
  10.152  
  10.153    FUNCTION_ENTER();
  10.154  
  10.155    KeAcquireSpinLock(&xi->tx_lock, &old_irql);
  10.156 -  xi->tx_shutting_down = TRUE;
  10.157 -  KeReleaseSpinLock(&xi->tx_lock, old_irql);
  10.158  
  10.159 -  while (xi->tx_outstanding)
  10.160 -  {
  10.161 +  while (xi->tx_outstanding) {
  10.162 +    KeReleaseSpinLock(&xi->tx_lock, old_irql);
  10.163      KdPrint((__DRIVER_NAME "     Waiting for %d remaining packets to be sent\n", xi->tx_outstanding));
  10.164      timeout.QuadPart = -1 * 1 * 1000 * 1000 * 10; /* 1 second */
  10.165      KeWaitForSingleObject(&xi->tx_idle_event, Executive, KernelMode, FALSE, &timeout);
  10.166 +    KeAcquireSpinLock(&xi->tx_lock, &old_irql);
  10.167    }
  10.168 -
  10.169 -  KeFlushQueuedDpcs();
  10.170 +  KeReleaseSpinLock(&xi->tx_lock, old_irql);
  10.171  
  10.172    /* Free packets in tx queue */
  10.173 -  while (!IsListEmpty(&xi->tx_waiting_pkt_list))
  10.174 -  {
  10.175 +  while (!IsListEmpty(&xi->tx_waiting_pkt_list)) {
  10.176      nb_entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
  10.177      nb = CONTAINING_RECORD(nb_entry, NET_BUFFER, NB_LIST_ENTRY_FIELD);
  10.178      nbl = NB_NBL(nb);
  10.179      NBL_REF(nbl)--;
  10.180 -    if (!NBL_REF(nbl))
  10.181 -    {
  10.182 +    if (!NBL_REF(nbl)) {
  10.183        nbl->Status = NDIS_STATUS_FAILURE;
  10.184        NdisMSendNetBufferListsComplete(xi->adapter_handle, nbl, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
  10.185      }
    11.1 --- a/xenpci/evtchn.c	Sun Jan 06 14:08:22 2013 +1100
    11.2 +++ b/xenpci/evtchn.c	Sat Feb 02 18:51:07 2013 +1100
    11.3 @@ -40,8 +40,7 @@ static KDEFERRED_ROUTINE EvtChn_DpcBounc
    11.4  #define BITS_PER_LONG_SHIFT (5 + (sizeof(xen_ulong_t) >> 3))
    11.5  
    11.6  static VOID
    11.7 -EvtChn_DpcBounce(PRKDPC Dpc, PVOID Context, PVOID SystemArgument1, PVOID SystemArgument2)
    11.8 -{
    11.9 +EvtChn_DpcBounce(PRKDPC Dpc, PVOID Context, PVOID SystemArgument1, PVOID SystemArgument2) {
   11.10    ev_action_t *action = Context;
   11.11  
   11.12    UNREFERENCED_PARAMETER(Dpc);
   11.13 @@ -50,17 +49,16 @@ EvtChn_DpcBounce(PRKDPC Dpc, PVOID Conte
   11.14  
   11.15    //FUNCTION_ENTER();
   11.16  
   11.17 -  if (action->type != EVT_ACTION_TYPE_EMPTY)
   11.18 -  {
   11.19 +  if (action->type != EVT_ACTION_TYPE_EMPTY) { 
   11.20      action->ServiceRoutine(action->ServiceContext);
   11.21    }
   11.22    //FUNCTION_EXIT();
   11.23  }
   11.24  
   11.25 +#if 0
   11.26  /* Called at DIRQL */
   11.27  BOOLEAN
   11.28 -EvtChn_AckEvent(PVOID context, evtchn_port_t port, BOOLEAN *last_interrupt)
   11.29 -{
   11.30 +EvtChn_AckEvent(PVOID context, evtchn_port_t port, BOOLEAN *last_interrupt) {
   11.31    PXENPCI_DEVICE_DATA xpdd = context;
   11.32    ULONG pcpu = KeGetCurrentProcessorNumber() & 0xff;
   11.33    ULONG evt_word;
   11.34 @@ -84,8 +82,9 @@ EvtChn_AckEvent(PVOID context, evtchn_po
   11.35    
   11.36    return (BOOLEAN)!!val;
   11.37  }
   11.38 +#endif
   11.39  
   11.40 -volatile ULONG in_inq = 0;
   11.41 +//volatile ULONG in_inq = 0;
   11.42  
   11.43  BOOLEAN
   11.44  EvtChn_EvtInterruptIsr(WDFINTERRUPT interrupt, ULONG message_id)
   11.45 @@ -111,20 +110,16 @@ to CPU != 0, but we should always use vc
   11.46  
   11.47    UNREFERENCED_PARAMETER(message_id);
   11.48  
   11.49 -  if (xpdd->interrupts_masked)
   11.50 -  {
   11.51 +  if (xpdd->interrupts_masked) {
   11.52      KdPrint((__DRIVER_NAME "     unhandled interrupt\n"));
   11.53    }
   11.54  
   11.55 -  if (xpdd->hibernated)
   11.56 -  {
   11.57 +  if (xpdd->hibernated) {
   11.58      KdPrint((__DRIVER_NAME "     interrupt while hibernated\n"));
   11.59    }
   11.60  
   11.61 -  for (i = 0; i < ARRAY_SIZE(xpdd->evtchn_pending_pvt[pcpu]); i++)
   11.62 -  {
   11.63 -    if (xpdd->evtchn_pending_pvt[pcpu][i])
   11.64 -    {
   11.65 +  for (i = 0; i < ARRAY_SIZE(xpdd->evtchn_pending_pvt[pcpu]); i++) {
   11.66 +    if (xpdd->evtchn_pending_pvt[pcpu][i]) {
   11.67        KdPrint((__DRIVER_NAME "     Unacknowledged event word = %d, val = %p\n", i, xpdd->evtchn_pending_pvt[pcpu][i]));
   11.68        xpdd->evtchn_pending_pvt[pcpu][i] = 0;
   11.69      }
   11.70 @@ -157,15 +152,11 @@ to CPU != 0, but we should always use vc
   11.71          //KdPrint((__DRIVER_NAME "     EVT_ACTION_TYPE_NORMAL port = %d\n", port));
   11.72          ev_action->ServiceRoutine(ev_action->ServiceContext);
   11.73          break;
   11.74 -      case EVT_ACTION_TYPE_IRQ:
   11.75 -        //KdPrint((__DRIVER_NAME "     EVT_ACTION_TYPE_IRQ port = %d\n", port));
   11.76 -        synch_set_bit(evt_bit, (volatile xen_long_t *)&xpdd->evtchn_pending_pvt[pcpu][evt_word]);
   11.77 -        deferred = TRUE;
   11.78 -        break;
   11.79        case EVT_ACTION_TYPE_DPC:
   11.80          //KdPrint((__DRIVER_NAME "     EVT_ACTION_TYPE_DPC port = %d\n", port));
   11.81          KeInsertQueueDpc(&ev_action->Dpc, NULL, NULL);
   11.82          break;
   11.83 +#if 0
   11.84        case EVT_ACTION_TYPE_SUSPEND:
   11.85          KdPrint((__DRIVER_NAME "     EVT_ACTION_TYPE_SUSPEND\n"));
   11.86          for (i = 0; i < NR_EVENTS; i++)
   11.87 @@ -174,6 +165,7 @@ to CPU != 0, but we should always use vc
   11.88            {
   11.89              switch(xpdd->ev_actions[i].type)
   11.90              {
   11.91 +#if 0            
   11.92              case EVT_ACTION_TYPE_IRQ:
   11.93                {
   11.94                  int suspend_bit = i & (BITS_PER_LONG - 1);
   11.95 @@ -181,6 +173,7 @@ to CPU != 0, but we should always use vc
   11.96                  synch_set_bit(suspend_bit, (volatile xen_long_t *)&xpdd->evtchn_pending_pvt[pcpu][suspend_word]);
   11.97                }
   11.98                break;
   11.99 +#endif
  11.100              case EVT_ACTION_TYPE_NORMAL:
  11.101                if (xpdd->ev_actions[i].ServiceRoutine)
  11.102                {
  11.103 @@ -196,6 +189,7 @@ to CPU != 0, but we should always use vc
  11.104          KeInsertQueueDpc(&ev_action->Dpc, NULL, NULL);
  11.105          deferred = TRUE;
  11.106          break;
  11.107 +#endif
  11.108        default:
  11.109          KdPrint((__DRIVER_NAME "     Unhandled Event!!! port=%d\n", port));
  11.110          break;
  11.111 @@ -235,27 +229,27 @@ EvtChn_EvtInterruptDisable(WDFINTERRUPT 
  11.112  }
  11.113  
  11.114  NTSTATUS
  11.115 -EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags)
  11.116 +EvtChn_Bind(PVOID Context, evtchn_port_t port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags)
  11.117  {
  11.118    PXENPCI_DEVICE_DATA xpdd = Context;
  11.119 -  ev_action_t *action = &xpdd->ev_actions[Port];
  11.120 +  ev_action_t *action = &xpdd->ev_actions[port];
  11.121  
  11.122    FUNCTION_ENTER();
  11.123    
  11.124    if (InterlockedCompareExchange((volatile LONG *)&action->type, EVT_ACTION_TYPE_NEW, EVT_ACTION_TYPE_EMPTY) != EVT_ACTION_TYPE_EMPTY)
  11.125    {
  11.126 -    KdPrint((__DRIVER_NAME " Handler for port %d already registered\n", Port));
  11.127 +    KdPrint((__DRIVER_NAME " Handler for port %d already registered\n", port));
  11.128      return STATUS_UNSUCCESSFUL;
  11.129    }
  11.130  
  11.131 -  xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine;
  11.132 -  xpdd->ev_actions[Port].ServiceContext = ServiceContext;
  11.133 -  xpdd->ev_actions[Port].xpdd = xpdd;
  11.134 -  xpdd->ev_actions[Port].flags = flags;
  11.135 +  xpdd->ev_actions[port].ServiceRoutine = ServiceRoutine;
  11.136 +  xpdd->ev_actions[port].ServiceContext = ServiceContext;
  11.137 +  xpdd->ev_actions[port].xpdd = xpdd;
  11.138 +  xpdd->ev_actions[port].flags = flags;
  11.139    KeMemoryBarrier();
  11.140 -  xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_NORMAL;
  11.141 +  xpdd->ev_actions[port].type = EVT_ACTION_TYPE_NORMAL;
  11.142  
  11.143 -  EvtChn_Unmask(Context, Port);
  11.144 +  EvtChn_Unmask(Context, port);
  11.145  
  11.146    FUNCTION_EXIT();
  11.147  
  11.148 @@ -263,89 +257,88 @@ EvtChn_Bind(PVOID Context, evtchn_port_t
  11.149  }
  11.150  
  11.151  NTSTATUS
  11.152 -EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags)
  11.153 +EvtChn_BindDpc(PVOID Context, evtchn_port_t port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags)
  11.154  {
  11.155    PXENPCI_DEVICE_DATA xpdd = Context;
  11.156 -  ev_action_t *action = &xpdd->ev_actions[Port];
  11.157 +  ev_action_t *action = &xpdd->ev_actions[port];
  11.158  
  11.159    FUNCTION_ENTER();
  11.160    
  11.161    if (InterlockedCompareExchange((volatile LONG *)&action->type, EVT_ACTION_TYPE_NEW, EVT_ACTION_TYPE_EMPTY) != EVT_ACTION_TYPE_EMPTY)
  11.162    {
  11.163 -    KdPrint((__DRIVER_NAME " Handler for port %d already registered\n", Port));
  11.164 +    KdPrint((__DRIVER_NAME " Handler for port %d already registered\n", port));
  11.165      return STATUS_UNSUCCESSFUL;
  11.166    }
  11.167  
  11.168 -  xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine;
  11.169 -  xpdd->ev_actions[Port].ServiceContext = ServiceContext;
  11.170 -  xpdd->ev_actions[Port].xpdd = xpdd;
  11.171 -  xpdd->ev_actions[Port].flags = flags;
  11.172 +  xpdd->ev_actions[port].ServiceRoutine = ServiceRoutine;
  11.173 +  xpdd->ev_actions[port].ServiceContext = ServiceContext;
  11.174 +  xpdd->ev_actions[port].xpdd = xpdd;
  11.175 +  xpdd->ev_actions[port].flags = flags;
  11.176    KeMemoryBarrier(); // make sure that the new service routine is only called once the context is set up
  11.177    InterlockedExchange((volatile LONG *)&action->type, EVT_ACTION_TYPE_DPC);
  11.178  
  11.179 -  EvtChn_Unmask(Context, Port);
  11.180 +  EvtChn_Unmask(Context, port);
  11.181  
  11.182    FUNCTION_EXIT();
  11.183  
  11.184    return STATUS_SUCCESS;
  11.185  }
  11.186  
  11.187 +#if 0
  11.188  NTSTATUS
  11.189 -EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector, PCHAR description, ULONG flags)
  11.190 +EvtChn_BindIrq(PVOID Context, evtchn_port_t port, ULONG vector, PCHAR description, ULONG flags)
  11.191  {
  11.192    PXENPCI_DEVICE_DATA xpdd = Context;
  11.193 -  ev_action_t *action = &xpdd->ev_actions[Port];
  11.194 +  ev_action_t *action = &xpdd->ev_actions[port];
  11.195  
  11.196    FUNCTION_ENTER();
  11.197    
  11.198    if (InterlockedCompareExchange((volatile LONG *)&action->type, EVT_ACTION_TYPE_NEW, EVT_ACTION_TYPE_EMPTY) != EVT_ACTION_TYPE_EMPTY)
  11.199    {
  11.200 -    KdPrint((__DRIVER_NAME " Handler for port %d already registered\n", Port));
  11.201 +    KdPrint((__DRIVER_NAME " Handler for port %d already registered\n", port));
  11.202      return STATUS_UNSUCCESSFUL;
  11.203    }
  11.204  
  11.205 -  xpdd->ev_actions[Port].vector = vector;
  11.206 -  xpdd->ev_actions[Port].xpdd = xpdd;
  11.207 +  xpdd->ev_actions[port].vector = vector;
  11.208 +  xpdd->ev_actions[port].xpdd = xpdd;
  11.209    KeMemoryBarrier();
  11.210 -  xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_IRQ;
  11.211 -  RtlStringCbCopyA(xpdd->ev_actions[Port].description, 128, description);
  11.212 -  xpdd->ev_actions[Port].flags = flags;
  11.213 +  xpdd->ev_actions[port].type = EVT_ACTION_TYPE_IRQ;
  11.214 +  RtlStringCbCopyA(xpdd->ev_actions[port].description, 128, description);
  11.215 +  xpdd->ev_actions[port].flags = flags;
  11.216    
  11.217 -  EvtChn_Unmask(Context, Port);
  11.218 +  EvtChn_Unmask(Context, port);
  11.219  
  11.220    FUNCTION_EXIT();
  11.221  
  11.222    return STATUS_SUCCESS;
  11.223  }
  11.224 +#endif
  11.225  
  11.226  NTSTATUS
  11.227 -EvtChn_Unbind(PVOID Context, evtchn_port_t Port)
  11.228 -{
  11.229 +EvtChn_Unbind(PVOID Context, evtchn_port_t port) {
  11.230    PXENPCI_DEVICE_DATA xpdd = Context;
  11.231 -  ev_action_t *action = &xpdd->ev_actions[Port];
  11.232 +  ev_action_t *action = &xpdd->ev_actions[port];
  11.233    int old_type;
  11.234    
  11.235 -  EvtChn_Mask(Context, Port);
  11.236 +  EvtChn_Mask(Context, port);
  11.237    old_type = InterlockedExchange((volatile LONG *)&action->type, EVT_ACTION_TYPE_EMPTY);
  11.238    
  11.239 -  if (old_type == EVT_ACTION_TYPE_DPC || old_type == EVT_ACTION_TYPE_SUSPEND)
  11.240 -  {
  11.241 -    KeRemoveQueueDpc(&xpdd->ev_actions[Port].Dpc);
  11.242 +  if (old_type == EVT_ACTION_TYPE_DPC) { // || old_type == EVT_ACTION_TYPE_SUSPEND) {
  11.243 +    KeRemoveQueueDpc(&xpdd->ev_actions[port].Dpc);
  11.244  #if (NTDDI_VERSION >= NTDDI_WINXP)
  11.245      KeFlushQueuedDpcs();
  11.246  #endif
  11.247    }
  11.248    
  11.249    KeMemoryBarrier(); // make sure we don't call the old Service Routine with the new data...
  11.250 -  xpdd->ev_actions[Port].ServiceRoutine = NULL;
  11.251 -  xpdd->ev_actions[Port].ServiceContext = NULL;
  11.252 +  xpdd->ev_actions[port].ServiceRoutine = NULL;
  11.253 +  xpdd->ev_actions[port].ServiceContext = NULL;
  11.254  
  11.255    return STATUS_SUCCESS;
  11.256  }
  11.257  
  11.258  NTSTATUS
  11.259 -EvtChn_Mask(PVOID Context, evtchn_port_t port)
  11.260 -{
  11.261 +EvtChn_Mask(PVOID Context, evtchn_port_t port) {
  11.262    PXENPCI_DEVICE_DATA xpdd = Context;
  11.263  
  11.264    synch_set_bit(port & (BITS_PER_LONG - 1),
  11.265 @@ -354,8 +347,7 @@ EvtChn_Mask(PVOID Context, evtchn_port_t
  11.266  }
  11.267  
  11.268  NTSTATUS
  11.269 -EvtChn_Unmask(PVOID context, evtchn_port_t port)
  11.270 -{
  11.271 +EvtChn_Unmask(PVOID context, evtchn_port_t port) {
  11.272    PXENPCI_DEVICE_DATA xpdd = context;
  11.273  
  11.274    synch_clear_bit(port & (BITS_PER_LONG - 1),
  11.275 @@ -364,19 +356,17 @@ EvtChn_Unmask(PVOID context, evtchn_port
  11.276  }
  11.277  
  11.278  NTSTATUS
  11.279 -EvtChn_Notify(PVOID Context, evtchn_port_t Port)
  11.280 -{
  11.281 +EvtChn_Notify(PVOID Context, evtchn_port_t port) {
  11.282    PXENPCI_DEVICE_DATA xpdd = Context;
  11.283    struct evtchn_send send;
  11.284  
  11.285 -  send.port = Port;
  11.286 +  send.port = port;
  11.287    (void)HYPERVISOR_event_channel_op(xpdd, EVTCHNOP_send, &send);
  11.288    return STATUS_SUCCESS;
  11.289  }
  11.290  
  11.291  evtchn_port_t
  11.292 -EvtChn_AllocIpi(PVOID context, ULONG vcpu)
  11.293 -{
  11.294 +EvtChn_AllocIpi(PVOID context, ULONG vcpu) {
  11.295    PXENPCI_DEVICE_DATA xpdd = context;
  11.296    evtchn_bind_ipi_t op;
  11.297    
  11.298 @@ -389,8 +379,7 @@ EvtChn_AllocIpi(PVOID context, ULONG vcp
  11.299  }
  11.300  
  11.301  evtchn_port_t
  11.302 -EvtChn_AllocUnbound(PVOID Context, domid_t Domain)
  11.303 -{
  11.304 +EvtChn_AllocUnbound(PVOID Context, domid_t Domain) {
  11.305    PXENPCI_DEVICE_DATA xpdd = Context;
  11.306    evtchn_alloc_unbound_t op;
  11.307    op.dom = DOMID_SELF;
  11.308 @@ -400,8 +389,7 @@ EvtChn_AllocUnbound(PVOID Context, domid
  11.309  }
  11.310  
  11.311  VOID
  11.312 -EvtChn_Close(PVOID Context, evtchn_port_t port )
  11.313 -{
  11.314 +EvtChn_Close(PVOID Context, evtchn_port_t port) {
  11.315    PXENPCI_DEVICE_DATA xpdd = Context;
  11.316    evtchn_close_t op;
  11.317    op.port = port;
  11.318 @@ -409,6 +397,7 @@ EvtChn_Close(PVOID Context, evtchn_port_
  11.319    return;
  11.320  }
  11.321  
  11.322 +#if 0
  11.323  VOID
  11.324  EvtChn_PdoEventChannelDpc(PVOID context)
  11.325  {
  11.326 @@ -418,6 +407,7 @@ EvtChn_PdoEventChannelDpc(PVOID context)
  11.327    KeSetEvent(&xpdd->pdo_suspend_event, IO_NO_INCREMENT, FALSE);
  11.328    FUNCTION_EXIT();
  11.329  }
  11.330 +#endif
  11.331  
  11.332  NTSTATUS
  11.333  EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
  11.334 @@ -433,17 +423,16 @@ EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
  11.335      EvtChn_Mask(xpdd, i);
  11.336      action = &xpdd->ev_actions[i];
  11.337      action->type = EVT_ACTION_TYPE_EMPTY;
  11.338 +    //action->port = -1;
  11.339      action->count = 0;
  11.340      KeInitializeDpc(&action->Dpc, EvtChn_DpcBounce, action);
  11.341    }
  11.342  
  11.343 -  for (i = 0; i < 8; i++)
  11.344 -  {
  11.345 +  for (i = 0; i < 8; i++) {
  11.346      xpdd->shared_info_area->evtchn_pending[i] = 0;
  11.347    }
  11.348  
  11.349 -  for (i = 0; i < MAX_VIRT_CPUS; i++)
  11.350 -  {
  11.351 +  for (i = 0; i < MAX_VIRT_CPUS; i++) {
  11.352      xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_pending = 0;
  11.353      xpdd->shared_info_area->vcpu_info[i].evtchn_pending_sel = 0;
  11.354      xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 1; /* apparantly this doesn't do anything */
  11.355 @@ -459,12 +448,13 @@ EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
  11.356    xpdd->interrupts_masked = FALSE;
  11.357    KeMemoryBarrier();
  11.358  
  11.359 +#if 0
  11.360    KeInitializeEvent(&xpdd->pdo_suspend_event, SynchronizationEvent, FALSE);
  11.361    xpdd->pdo_event_channel = EvtChn_AllocIpi(xpdd, 0);
  11.362    EvtChn_BindDpc(xpdd, xpdd->pdo_event_channel, EvtChn_PdoEventChannelDpc, xpdd, EVT_ACTION_FLAGS_DEFAULT);
  11.363    xpdd->ev_actions[xpdd->pdo_event_channel].type = EVT_ACTION_TYPE_SUSPEND; /* override dpc type */
  11.364 -  
  11.365    KdPrint((__DRIVER_NAME "     pdo_event_channel = %d\n", xpdd->pdo_event_channel));
  11.366 +#endif  
  11.367  
  11.368    FUNCTION_EXIT();
  11.369    
  11.370 @@ -475,7 +465,6 @@ NTSTATUS
  11.371  EvtChn_Suspend(PXENPCI_DEVICE_DATA xpdd)
  11.372  {
  11.373    int i;
  11.374 -//  LARGE_INTEGER wait_time;
  11.375  
  11.376    xpdd->interrupts_masked = TRUE;
  11.377    for (i = 0; i < MAX_VIRT_CPUS; i++)
  11.378 @@ -483,10 +472,8 @@ EvtChn_Suspend(PXENPCI_DEVICE_DATA xpdd)
  11.379    KeMemoryBarrier();
  11.380    hvm_set_parameter(xpdd, HVM_PARAM_CALLBACK_IRQ, 0);
  11.381  
  11.382 -  for (i = 0; i < NR_EVENTS; i++)
  11.383 -  {
  11.384 -    if (xpdd->ev_actions[i].type == EVT_ACTION_TYPE_DPC)
  11.385 -    {
  11.386 +  for (i = 0; i < NR_EVENTS; i++) {
  11.387 +    if (xpdd->ev_actions[i].type == EVT_ACTION_TYPE_DPC) {
  11.388        KeRemoveQueueDpc(&xpdd->ev_actions[i].Dpc);
  11.389      }
  11.390    }
    12.1 --- a/xenpci/sources	Sun Jan 06 14:08:22 2013 +1100
    12.2 +++ b/xenpci/sources	Sat Feb 02 18:51:07 2013 +1100
    12.3 @@ -3,7 +3,7 @@ TARGETNAME=xenpci
    12.4  INF_NAME=xenpci
    12.5  TARGETTYPE=EXPORT_DRIVER
    12.6  KMDF_VERSION_MAJOR=1
    12.7 -NTTARGETFILES=$(NTTARGETFILES) $(OBJ_PATH)\$(O)\$(INF_NAME).inf
    12.8 +NTTARGETFILE0=$(NTTARGETFILE0) $(OBJ_PATH)\$(O)\$(INF_NAME).inf
    12.9  TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\wdmsec.lib $(DDK_LIB_PATH)\Rtlver.lib \
   12.10             $(DDK_LIB_PATH)\..\..\wlh\*\aux_klib.lib
   12.11  
    13.1 --- a/xenpci/xenbus.c	Sun Jan 06 14:08:22 2013 +1100
    13.2 +++ b/xenpci/xenbus.c	Sat Feb 02 18:51:07 2013 +1100
    13.3 @@ -95,7 +95,7 @@ static void xb_write(
    13.4    /* Remote must see entire message before updating indexes */
    13.5    KeMemoryBarrier();
    13.6    xpdd->xen_store_interface->req_prod = prod;
    13.7 -  EvtChn_Notify(xpdd, xpdd->xen_store_evtchn);
    13.8 +  EvtChn_Notify(xpdd, xpdd->xenbus_event);
    13.9  
   13.10    //FUNCTION_EXIT();
   13.11  }
   13.12 @@ -312,7 +312,7 @@ XenBus_Dpc(PVOID ServiceContext)
   13.13      if (xpdd->xb_msg_offset < sizeof(xsd_sockmsg_t) + xpdd->xb_msg->len)
   13.14      {
   13.15        //KdPrint((__DRIVER_NAME " +++ Message incomplete (header but not full body)\n"));
   13.16 -      EvtChn_Notify(xpdd, xpdd->xen_store_evtchn); /* there is room on the ring now */
   13.17 +      EvtChn_Notify(xpdd, xpdd->xenbus_event); /* there is room on the ring now */
   13.18        break;
   13.19      }
   13.20  
   13.21 @@ -341,7 +341,7 @@ XenBus_Dpc(PVOID ServiceContext)
   13.22        xpdd->xb_msg = NULL;
   13.23        WdfWorkItemEnqueue(workitem);
   13.24      }
   13.25 -    EvtChn_Notify(xpdd, xpdd->xen_store_evtchn); /* there is room on the ring now */
   13.26 +    EvtChn_Notify(xpdd, xpdd->xenbus_event); /* there is room on the ring now */
   13.27    }
   13.28    KeReleaseSpinLockFromDpcLevel(&xpdd->xb_ring_spinlock);
   13.29    
   13.30 @@ -354,12 +354,12 @@ XenBus_Connect(PXENPCI_DEVICE_DATA xpdd)
   13.31    PHYSICAL_ADDRESS pa_xen_store_interface;
   13.32    xen_ulong_t xen_store_mfn;
   13.33  
   13.34 -  xpdd->xen_store_evtchn = (evtchn_port_t)hvm_get_parameter(xpdd, HVM_PARAM_STORE_EVTCHN);
   13.35 +  xpdd->xenbus_event = (evtchn_port_t)hvm_get_parameter(xpdd, HVM_PARAM_STORE_EVTCHN);
   13.36    xen_store_mfn = (xen_ulong_t)hvm_get_parameter(xpdd, HVM_PARAM_STORE_PFN);
   13.37    pa_xen_store_interface.QuadPart = (ULONGLONG)xen_store_mfn << PAGE_SHIFT;
   13.38    xpdd->xen_store_interface = MmMapIoSpace(pa_xen_store_interface, PAGE_SIZE, MmNonCached);
   13.39  
   13.40 -  EvtChn_BindDpc(xpdd, xpdd->xen_store_evtchn, XenBus_Dpc, xpdd, EVT_ACTION_FLAGS_NO_SUSPEND);
   13.41 +  EvtChn_BindDpc(xpdd, xpdd->xenbus_event, XenBus_Dpc, xpdd, EVT_ACTION_FLAGS_NO_SUSPEND);
   13.42    
   13.43    return STATUS_SUCCESS;
   13.44  }
   13.45 @@ -367,7 +367,7 @@ XenBus_Connect(PXENPCI_DEVICE_DATA xpdd)
   13.46  static NTSTATUS
   13.47  XenBus_Disconnect(PXENPCI_DEVICE_DATA xpdd)
   13.48  {
   13.49 -  EvtChn_Unbind(xpdd, xpdd->xen_store_evtchn);
   13.50 +  EvtChn_Unbind(xpdd, xpdd->xenbus_event);
   13.51  
   13.52    MmUnmapIoSpace(xpdd->xen_store_interface, PAGE_SIZE);
   13.53    
    14.1 --- a/xenpci/xenpci.c	Sun Jan 06 14:08:22 2013 +1100
    14.2 +++ b/xenpci/xenpci.c	Sat Feb 02 18:51:07 2013 +1100
    14.3 @@ -148,6 +148,7 @@ XenPci_EvtDeviceAdd_XenPci(WDFDRIVER dri
    14.4    xpdd->wdf_device = device;
    14.5    xpdd->child_list = WdfFdoGetDefaultChildList(device);
    14.6  
    14.7 +  KeInitializeGuardedMutex(&xpdd->suspend_mutex);
    14.8    WdfCollectionCreate(WDF_NO_OBJECT_ATTRIBUTES, &veto_devices);
    14.9    status = WdfDriverOpenParametersRegistryKey(driver, KEY_QUERY_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &param_key);
   14.10    if (NT_SUCCESS(status))
    15.1 --- a/xenpci/xenpci.def	Sun Jan 06 14:08:22 2013 +1100
    15.2 +++ b/xenpci/xenpci.def	Sat Feb 02 18:51:07 2013 +1100
    15.3 @@ -10,10 +10,8 @@ EXPORTS
    15.4   XnCloseDevice
    15.5   XnGetValue
    15.6  
    15.7 - XnAllocateEvent
    15.8 - XnFreeEvent
    15.9   XnBindEvent
   15.10 - XnUnBindEvent
   15.11 + XnUnbindEvent
   15.12   XnNotify
   15.13  
   15.14   XnAllocateGrant
   15.15 @@ -29,3 +27,5 @@ EXPORTS
   15.16   XnWriteInt32
   15.17   XnReadInt64
   15.18   XnWriteInt64
   15.19 +
   15.20 + XnDumpModeHookDebugPrint
   15.21 \ No newline at end of file
    16.1 --- a/xenpci/xenpci.h	Sun Jan 06 14:08:22 2013 +1100
    16.2 +++ b/xenpci/xenpci.h	Sat Feb 02 18:51:07 2013 +1100
    16.3 @@ -67,9 +67,9 @@ DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC82
    16.4  #define EVT_ACTION_TYPE_EMPTY   0
    16.5  #define EVT_ACTION_TYPE_NORMAL  1
    16.6  #define EVT_ACTION_TYPE_DPC     2
    16.7 -#define EVT_ACTION_TYPE_IRQ     3
    16.8 -#define EVT_ACTION_TYPE_SUSPEND 4
    16.9 -#define EVT_ACTION_TYPE_NEW     5 /* setup of event is in progress */
   16.10 +//#define EVT_ACTION_TYPE_IRQ     3
   16.11 +//#define EVT_ACTION_TYPE_SUSPEND 4
   16.12 +#define EVT_ACTION_TYPE_NEW     9 /* setup of event is in progress */
   16.13  
   16.14  #define EVT_ACTION_FLAGS_DEFAULT    0 /* no special flags */
   16.15  #define EVT_ACTION_FLAGS_NO_SUSPEND 1 /* should not be fired on EVT_ACTION_TYPE_SUSPEND event */
   16.16 @@ -85,17 +85,16 @@ extern USHORT xen_version_major;
   16.17  extern USHORT xen_version_minor;
   16.18  
   16.19  typedef struct _ev_action_t {
   16.20 +  PVOID xpdd;
   16.21 +  //evtchn_port_t port;
   16.22    PXN_EVENT_CALLBACK ServiceRoutine;
   16.23    PVOID ServiceContext;
   16.24    CHAR description[128];
   16.25    ULONG type; /* EVT_ACTION_TYPE_* */
   16.26    ULONG flags; /* EVT_ACTION_FLAGS_* */
   16.27    KDPC Dpc;
   16.28 -  ULONG port;
   16.29    ULONG vector;
   16.30    ULONG count;
   16.31 -  PVOID xpdd;
   16.32 -  ULONG generation; /* increases each time the event is renewed */
   16.33  } ev_action_t;
   16.34  
   16.35  typedef struct _XENBUS_WATCH_RING
   16.36 @@ -153,8 +152,8 @@ typedef struct {
   16.37    shared_info_t *shared_info_area;
   16.38    xen_ulong_t evtchn_pending_pvt[MAX_VIRT_CPUS][sizeof(xen_ulong_t) * 8];
   16.39    xen_ulong_t evtchn_pending_suspend[sizeof(xen_ulong_t) * 8];
   16.40 -  evtchn_port_t pdo_event_channel;
   16.41 -  KEVENT pdo_suspend_event;
   16.42 +  //evtchn_port_t pdo_event_channel;
   16.43 +  //KEVENT pdo_suspend_event;
   16.44    BOOLEAN interrupts_masked;
   16.45    
   16.46    PHYSICAL_ADDRESS platform_mmio_addr;
   16.47 @@ -168,7 +167,7 @@ typedef struct {
   16.48  
   16.49    char *hypercall_stubs;
   16.50  
   16.51 -  evtchn_port_t xen_store_evtchn;
   16.52 +  evtchn_port_t xenbus_event;
   16.53  
   16.54    /* grant related */
   16.55    struct stack_state *gnttbl_ss;
   16.56 @@ -210,8 +209,9 @@ typedef struct {
   16.57    
   16.58    WDFCHILDLIST child_list;
   16.59    
   16.60 -  KSPIN_LOCK suspend_lock;  
   16.61 -  evtchn_port_t suspend_evtchn;
   16.62 +  KGUARDED_MUTEX suspend_mutex;
   16.63 +  
   16.64 +  ULONG suspend_evtchn;
   16.65    int suspend_state;
   16.66    
   16.67    UNICODE_STRING legacy_interface_name;
   16.68 @@ -246,6 +246,7 @@ typedef struct {
   16.69  typedef struct {  
   16.70    WDFDEVICE wdf_device;
   16.71    WDFDEVICE wdf_device_bus_fdo;
   16.72 +  PXENPCI_DEVICE_DATA xpdd;
   16.73    BOOLEAN reported_missing;
   16.74    char path[128];
   16.75    char device[128];
   16.76 @@ -257,8 +258,8 @@ typedef struct {
   16.77    domid_t backend_id;
   16.78    KEVENT backend_state_event;
   16.79    ULONG backend_state;
   16.80 -  PXN_BACKEND_STATE_CALLBACK backend_state_callback;
   16.81 -  PVOID backend_state_callback_context;
   16.82 +  PXN_DEVICE_CALLBACK device_callback;
   16.83 +  PVOID device_callback_context;
   16.84    FAST_MUTEX backend_state_mutex;
   16.85    ULONG frontend_state;
   16.86    PMDL config_page_mdl;
   16.87 @@ -335,8 +336,7 @@ XenPci_FreeMem(PVOID Ptr) {
   16.88    ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
   16.89  }
   16.90  
   16.91 -NTSTATUS
   16.92 -XenBus_DeviceFileInit(WDFDEVICE device, PWDF_IO_QUEUE_CONFIG queue_config, WDFFILEOBJECT file_object);
   16.93 +NTSTATUS XenBus_DeviceFileInit(WDFDEVICE device, PWDF_IO_QUEUE_CONFIG queue_config, WDFFILEOBJECT file_object);
   16.94  
   16.95  EVT_WDF_DEVICE_FILE_CREATE XenPci_EvtDeviceFileCreate;
   16.96  EVT_WDF_FILE_CLOSE XenPci_EvtFileClose;
   16.97 @@ -360,10 +360,8 @@ EVT_WDF_IO_QUEUE_IO_DEFAULT XenPci_EvtIo
   16.98  
   16.99  #define XBT_NIL ((xenbus_transaction_t)0)
  16.100  
  16.101 -PVOID
  16.102 -hvm_get_hypercall_stubs();
  16.103 -VOID
  16.104 -hvm_free_hypercall_stubs(PVOID hypercall_stubs);
  16.105 +PVOID hvm_get_hypercall_stubs();
  16.106 +VOID hvm_free_hypercall_stubs(PVOID hypercall_stubs);
  16.107  
  16.108  EVT_WDF_DEVICE_PREPARE_HARDWARE XenPci_EvtDevicePrepareHardware;
  16.109  EVT_WDF_DEVICE_RELEASE_HARDWARE XenPci_EvtDeviceReleaseHardware;
  16.110 @@ -375,61 +373,43 @@ EVT_WDF_DEVICE_QUERY_REMOVE XenPci_EvtDe
  16.111  EVT_WDF_CHILD_LIST_CREATE_DEVICE XenPci_EvtChildListCreateDevice;
  16.112  EVT_WDF_CHILD_LIST_SCAN_FOR_CHILDREN XenPci_EvtChildListScanForChildren;
  16.113  
  16.114 -VOID
  16.115 -XenPci_HideQemuDevices();
  16.116 +VOID XenPci_HideQemuDevices();
  16.117  extern WDFCOLLECTION qemu_hide_devices;
  16.118  extern USHORT qemu_hide_flags_value;
  16.119  
  16.120 -NTSTATUS
  16.121 -XenPci_Pdo_Suspend(WDFDEVICE device);
  16.122 -NTSTATUS
  16.123 -XenPci_Pdo_Resume(WDFDEVICE device);
  16.124 -
  16.125 -VOID
  16.126 -XenPci_DumpPdoConfig(PDEVICE_OBJECT device_object);
  16.127 -
  16.128 -typedef VOID
  16.129 -(*PXENPCI_HIGHSYNC_FUNCTION)(PVOID context);
  16.130 -
  16.131 -VOID
  16.132 -XenPci_HighSync(PXENPCI_HIGHSYNC_FUNCTION function0, PXENPCI_HIGHSYNC_FUNCTION functionN, PVOID context);
  16.133 -
  16.134 -VOID
  16.135 -XenPci_PatchKernel(PXENPCI_DEVICE_DATA xpdd, PVOID base, ULONG length);
  16.136 -
  16.137 -NTSTATUS
  16.138 -XenPci_HookDbgPrint();
  16.139 -NTSTATUS
  16.140 -XenPci_UnHookDbgPrint();
  16.141 +//NTSTATUS XenPci_Pdo_Suspend(WDFDEVICE device);
  16.142 +//NTSTATUS XenPci_Pdo_Resume(WDFDEVICE device);
  16.143  
  16.144 -struct xsd_sockmsg *
  16.145 -XenBus_Raw(PXENPCI_DEVICE_DATA xpdd, struct xsd_sockmsg *msg);
  16.146 -char *
  16.147 -XenBus_Read(PVOID Context, xenbus_transaction_t xbt, char *path, char **value);
  16.148 -char *
  16.149 -XenBus_Write(PVOID Context, xenbus_transaction_t xbt, char *path, char *value);
  16.150 -char *
  16.151 -XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, char *path, char *fmt, ...);
  16.152 -char *
  16.153 -XenBus_StartTransaction(PVOID Context, xenbus_transaction_t *xbt);
  16.154 -char *
  16.155 -XenBus_EndTransaction(PVOID Context, xenbus_transaction_t t, int abort, int *retry);
  16.156 -char *
  16.157 -XenBus_List(PVOID Context, xenbus_transaction_t xbt, char *prefix, char ***contents);
  16.158 -char *
  16.159 -XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXN_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
  16.160 -char *
  16.161 -XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXN_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
  16.162 -//VOID
  16.163 -//XenBus_ThreadProc(PVOID StartContext);
  16.164 -NTSTATUS
  16.165 -XenBus_Init(PXENPCI_DEVICE_DATA xpdd);
  16.166 -NTSTATUS
  16.167 -XenBus_Halt(PXENPCI_DEVICE_DATA xpdd);
  16.168 -NTSTATUS
  16.169 -XenBus_Suspend(PXENPCI_DEVICE_DATA xpdd);
  16.170 -NTSTATUS
  16.171 -XenBus_Resume(PXENPCI_DEVICE_DATA xpdd);
  16.172 +VOID XenPci_BackendStateCallback(char *path, PVOID context);
  16.173 +NTSTATUS XenPci_SuspendPdo(WDFDEVICE device);
  16.174 +NTSTATUS XenPci_ResumePdo(WDFDEVICE device);
  16.175 +
  16.176 +
  16.177 +VOID XenPci_DumpPdoConfig(PDEVICE_OBJECT device_object);
  16.178 +
  16.179 +typedef VOID (*PXENPCI_HIGHSYNC_FUNCTION)(PVOID context);
  16.180 +
  16.181 +VOID XenPci_HighSync(PXENPCI_HIGHSYNC_FUNCTION function0, PXENPCI_HIGHSYNC_FUNCTION functionN, PVOID context);
  16.182 +
  16.183 +VOID XenPci_PatchKernel(PXENPCI_DEVICE_DATA xpdd, PVOID base, ULONG length);
  16.184 +
  16.185 +NTSTATUS XenPci_HookDbgPrint();
  16.186 +NTSTATUS XenPci_UnHookDbgPrint();
  16.187 +VOID XenPci_DumpModeHookDebugPrint();
  16.188 +
  16.189 +struct xsd_sockmsg *XenBus_Raw(PXENPCI_DEVICE_DATA xpdd, struct xsd_sockmsg *msg);
  16.190 +char *XenBus_Read(PVOID Context, xenbus_transaction_t xbt, char *path, char **value);
  16.191 +char *XenBus_Write(PVOID Context, xenbus_transaction_t xbt, char *path, char *value);
  16.192 +char *XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, char *path, char *fmt, ...);
  16.193 +char *XenBus_StartTransaction(PVOID Context, xenbus_transaction_t *xbt);
  16.194 +char *XenBus_EndTransaction(PVOID Context, xenbus_transaction_t t, int abort, int *retry);
  16.195 +char *XenBus_List(PVOID Context, xenbus_transaction_t xbt, char *prefix, char ***contents);
  16.196 +char *XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXN_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
  16.197 +char *XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXN_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
  16.198 +NTSTATUS XenBus_Init(PXENPCI_DEVICE_DATA xpdd);
  16.199 +NTSTATUS XenBus_Halt(PXENPCI_DEVICE_DATA xpdd);
  16.200 +NTSTATUS XenBus_Suspend(PXENPCI_DEVICE_DATA xpdd);
  16.201 +NTSTATUS XenBus_Resume(PXENPCI_DEVICE_DATA xpdd);
  16.202  
  16.203  PHYSICAL_ADDRESS
  16.204  XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len);
  16.205 @@ -438,49 +418,28 @@ EVT_WDF_INTERRUPT_ISR EvtChn_EvtInterrup
  16.206  EVT_WDF_INTERRUPT_ENABLE EvtChn_EvtInterruptEnable;
  16.207  EVT_WDF_INTERRUPT_DISABLE EvtChn_EvtInterruptDisable;
  16.208  
  16.209 -NTSTATUS
  16.210 -EvtChn_Init(PXENPCI_DEVICE_DATA xpdd);
  16.211 -NTSTATUS
  16.212 -EvtChn_Suspend(PXENPCI_DEVICE_DATA xpdd);
  16.213 -NTSTATUS
  16.214 -EvtChn_Resume(PXENPCI_DEVICE_DATA xpdd);
  16.215 +NTSTATUS EvtChn_Init(PXENPCI_DEVICE_DATA xpdd);
  16.216 +NTSTATUS EvtChn_Suspend(PXENPCI_DEVICE_DATA xpdd);
  16.217 +NTSTATUS EvtChn_Resume(PXENPCI_DEVICE_DATA xpdd);
  16.218  
  16.219 -NTSTATUS
  16.220 -EvtChn_Mask(PVOID Context, evtchn_port_t Port);
  16.221 -NTSTATUS
  16.222 -EvtChn_Unmask(PVOID Context, evtchn_port_t Port);
  16.223 -NTSTATUS
  16.224 -EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags);
  16.225 -NTSTATUS
  16.226 -EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags);
  16.227 -NTSTATUS
  16.228 -EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector, PCHAR description, ULONG flags);
  16.229 -evtchn_port_t
  16.230 -EvtChn_AllocIpi(PVOID context, ULONG vcpu);
  16.231 -NTSTATUS
  16.232 -EvtChn_Unbind(PVOID Context, evtchn_port_t Port);
  16.233 -NTSTATUS
  16.234 -EvtChn_Notify(PVOID Context, evtchn_port_t Port);
  16.235 -VOID
  16.236 -EvtChn_Close(PVOID Context, evtchn_port_t Port);
  16.237 -evtchn_port_t
  16.238 -EvtChn_AllocUnbound(PVOID Context, domid_t Domain);
  16.239 -BOOLEAN
  16.240 -EvtChn_AckEvent(PVOID context, evtchn_port_t port, BOOLEAN *last_interrupt);
  16.241 +NTSTATUS EvtChn_Mask(PVOID context, evtchn_port_t port);
  16.242 +NTSTATUS EvtChn_Unmask(PVOID context, evtchn_port_t port);
  16.243 +NTSTATUS EvtChn_Bind(PVOID context, evtchn_port_t port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags);
  16.244 +NTSTATUS EvtChn_BindDpc(PVOID context, evtchn_port_t port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags);
  16.245 +//ULONG EvtChn_AllocIpi(PVOID context, ULONG vcpu);
  16.246 +NTSTATUS EvtChn_Unbind(PVOID context, evtchn_port_t port);
  16.247 +NTSTATUS EvtChn_Notify(PVOID context, evtchn_port_t port);
  16.248 +VOID EvtChn_Close(PVOID context, evtchn_port_t port);
  16.249 +evtchn_port_t EvtChn_AllocUnbound(PVOID context, domid_t domain);
  16.250 +//BOOLEAN EvtChn_AckEvent(PVOID context, evtchn_port_t port, BOOLEAN *last_interrupt);
  16.251 +evtchn_port_t EvtChn_GetEventPort(PVOID context, evtchn_port_t port);
  16.252  
  16.253 -VOID
  16.254 -GntTbl_Init(PXENPCI_DEVICE_DATA xpdd);
  16.255 -VOID
  16.256 -GntTbl_Suspend(PXENPCI_DEVICE_DATA xpdd);
  16.257 -VOID
  16.258 -GntTbl_Resume(PXENPCI_DEVICE_DATA xpdd);
  16.259 -grant_ref_t
  16.260 -GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t, int readonly, grant_ref_t ref, ULONG tag);
  16.261 -BOOLEAN
  16.262 -GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref, ULONG tag);
  16.263 -VOID
  16.264 -GntTbl_PutRef(PVOID Context, grant_ref_t ref, ULONG tag);
  16.265 -grant_ref_t
  16.266 -GntTbl_GetRef(PVOID Context, ULONG tag);
  16.267 +VOID GntTbl_Init(PXENPCI_DEVICE_DATA xpdd);
  16.268 +VOID GntTbl_Suspend(PXENPCI_DEVICE_DATA xpdd);
  16.269 +VOID GntTbl_Resume(PXENPCI_DEVICE_DATA xpdd);
  16.270 +grant_ref_t GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t, int readonly, grant_ref_t ref, ULONG tag);
  16.271 +BOOLEAN GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref, ULONG tag);
  16.272 +VOID GntTbl_PutRef(PVOID Context, grant_ref_t ref, ULONG tag);
  16.273 +grant_ref_t GntTbl_GetRef(PVOID Context, ULONG tag);
  16.274  
  16.275  #endif
    17.1 --- a/xenpci/xenpci_dbgprint.c	Sun Jan 06 14:08:22 2013 +1100
    17.2 +++ b/xenpci/xenpci_dbgprint.c	Sat Feb 02 18:51:07 2013 +1100
    17.3 @@ -216,8 +216,6 @@ typedef struct _hook_info {
    17.4  } hook_info_t;
    17.5  #endif
    17.6  
    17.7 -#if (NTDDI_VERSION < NTDDI_VISTA)
    17.8 -#ifndef _AMD64_ // can't patch IDT on AMD64 unfortunately - results in bug check 0x109
    17.9  static VOID
   17.10  XenPci_HookDbgPrint_High(PVOID context)
   17.11  {
   17.12 @@ -258,8 +256,6 @@ XenPci_UnHookDbgPrint_High(PVOID context
   17.13    idt_entry->addr_32_63 = (ULONG)((ULONG_PTR)Int2dHandlerOld >> 32);
   17.14    #endif
   17.15  }
   17.16 -#endif
   17.17 -#endif
   17.18  
   17.19  NTSTATUS
   17.20  XenPci_HookDbgPrint()
   17.21 @@ -304,6 +300,24 @@ XenPci_HookDbgPrint()
   17.22    return status;
   17.23  }
   17.24  
   17.25 +/* always hook IDT in dump mode - patchguard is turned off so its okay */
   17.26 +/* no need for unhook routine - system is already crashed */
   17.27 +/* only for AMD64 and >= Vista */
   17.28 +VOID
   17.29 +XenPci_DumpModeHookDebugPrint() {
   17.30 +  #if (NTDDI_VERSION >= NTDDI_VISTA)
   17.31 +  #ifdef _AMD64_
   17.32 +  #pragma warning(suppress:28138)
   17.33 +  if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2
   17.34 +    #pragma warning(suppress:28138)
   17.35 +    || READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0xd249) {
   17.36 +    //XenPci_HighSync(XenPci_HookDbgPrint_High, XenPci_HookDbgPrint_High, NULL);
   17.37 +    XenPci_HookDbgPrint_High(NULL);
   17.38 +  }
   17.39 +  #endif
   17.40 +  #endif
   17.41 +}
   17.42 +
   17.43  NTSTATUS
   17.44  XenPci_UnHookDbgPrint()
   17.45  {
   17.46 @@ -312,8 +326,7 @@ XenPci_UnHookDbgPrint()
   17.47    #pragma warning(suppress:28138)
   17.48    if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2
   17.49      #pragma warning(suppress:28138)
   17.50 -    || READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0xd249)
   17.51 -  {
   17.52 +    || READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0xd249) {
   17.53      //#pragma warning(suppress:4055)
   17.54      //DbgSetDebugPrintCallback = (PDBG_SET_DEBUGPRINT_CALLBACK)MmGetSystemRoutineAddress((PUNICODE_STRING)&DbgSetDebugPrintCallbackName);
   17.55  #if (NTDDI_VERSION >= NTDDI_VISTA)
   17.56 @@ -331,14 +344,11 @@ XenPci_UnHookDbgPrint()
   17.57      XenPci_HighSync(XenPci_UnHookDbgPrint_High, XenPci_UnHookDbgPrint_High, NULL);
   17.58  #endif
   17.59  #endif
   17.60 -  }
   17.61 -  else
   17.62 -  {
   17.63 +  } else {
   17.64      status = STATUS_UNSUCCESSFUL;
   17.65    }
   17.66    
   17.67 -  if (!KeDeregisterBugCheckCallback(&callback_record))
   17.68 -  {
   17.69 +  if (!KeDeregisterBugCheckCallback(&callback_record)) {
   17.70      KdPrint((__DRIVER_NAME "     KeDeregisterBugCheckCallback failed\n"));
   17.71      status = STATUS_UNSUCCESSFUL;
   17.72    }
    18.1 --- a/xenpci/xenpci_export.c	Sun Jan 06 14:08:22 2013 +1100
    18.2 +++ b/xenpci/xenpci_export.c	Sat Feb 02 18:51:07 2013 +1100
    18.3 @@ -24,11 +24,10 @@ XnGetVersion() {
    18.4    return 1;
    18.5  }
    18.6  
    18.7 -static VOID
    18.8 -XnBackendStateCallback(char *path, PVOID context) {
    18.9 -  WDFDEVICE device = context;
   18.10 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
   18.11 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
   18.12 +VOID
   18.13 +XenPci_BackendStateCallback(char *path, PVOID context) {
   18.14 +  PXENPCI_PDO_DEVICE_DATA xppdd = context;
   18.15 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
   18.16    PCHAR err;
   18.17    PCHAR value;
   18.18    ULONG backend_state;
   18.19 @@ -48,21 +47,12 @@ XnBackendStateCallback(char *path, PVOID
   18.20    FUNCTION_MSG("Read value=%s\n", value);
   18.21    backend_state = atoi(value);
   18.22    XenPci_FreeMem(value);
   18.23 -  xppdd->backend_state_callback(xppdd->backend_state_callback_context, backend_state);
   18.24 +  xppdd->device_callback(xppdd->device_callback_context, XN_DEVICE_CALLBACK_BACKEND_STATE, (PVOID)(ULONG_PTR)backend_state);
   18.25    FUNCTION_EXIT();
   18.26  }
   18.27  
   18.28 -
   18.29 -char *
   18.30 -XenBus_AddWatchx(
   18.31 -  PVOID Context,
   18.32 -  xenbus_transaction_t xbt,
   18.33 -  char *Path,
   18.34 -  PXN_WATCH_CALLBACK ServiceRoutine,
   18.35 -  PVOID ServiceContext);
   18.36 -
   18.37  XN_HANDLE
   18.38 -XnOpenDevice(PDEVICE_OBJECT pdo, PXN_BACKEND_STATE_CALLBACK callback, PVOID context) {
   18.39 +XnOpenDevice(PDEVICE_OBJECT pdo, PXN_DEVICE_CALLBACK callback, PVOID context) {
   18.40    WDFDEVICE device;
   18.41    PXENPCI_PDO_DEVICE_DATA xppdd;
   18.42    PXENPCI_DEVICE_DATA xpdd;
   18.43 @@ -76,164 +66,114 @@ XnOpenDevice(PDEVICE_OBJECT pdo, PXN_BAC
   18.44      return NULL;
   18.45    }
   18.46    xppdd = GetXppdd(device);
   18.47 -  xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
   18.48 -  xppdd->backend_state_callback = callback;
   18.49 -  xppdd->backend_state_callback_context = context;
   18.50 +  xpdd = xppdd->xpdd;
   18.51 +  xppdd->device_callback = callback;
   18.52 +  xppdd->device_callback_context = context;
   18.53    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
   18.54 -  response = XenBus_AddWatch(xpdd, XBT_NIL, path, XnBackendStateCallback, device);
   18.55 +  response = XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackendStateCallback, xppdd);
   18.56    if (response) {
   18.57      FUNCTION_MSG("XnAddWatch - %s = %s\n", path, response);
   18.58      XenPci_FreeMem(response);
   18.59 -    xppdd->backend_state_callback = NULL;
   18.60 -    xppdd->backend_state_callback_context = NULL;
   18.61 +    xppdd->device_callback = NULL;
   18.62 +    xppdd->device_callback_context = NULL;
   18.63      FUNCTION_EXIT();
   18.64      return NULL;
   18.65    }
   18.66  
   18.67    FUNCTION_EXIT();
   18.68 -  return device;
   18.69 +  return xppdd;
   18.70  }
   18.71  
   18.72  VOID
   18.73  XnCloseDevice(XN_HANDLE handle) {
   18.74 -  UNREFERENCED_PARAMETER(handle);
   18.75 -}
   18.76 -
   18.77 -#if 0
   18.78 -NTSTATUS
   18.79 -XnAddWatch(XN_HANDLE handle, char *path, PXN_WATCH_CALLBACK callback, PVOID context) {
   18.80 -  WDFDEVICE device = handle;
   18.81 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
   18.82 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
   18.83 +  PXENPCI_PDO_DEVICE_DATA xppdd = handle;
   18.84 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
   18.85    PCHAR response;
   18.86 -  NTSTATUS status;
   18.87 -  
   18.88 -  response = XenBus_AddWatch(xpdd, XBT_NIL, path, callback, context);
   18.89 -  if (response == NULL) {
   18.90 -    FUNCTION_MSG("XnAddWatch - %s = NULL\n", path);
   18.91 -    status = STATUS_SUCCESS;
   18.92 -  } else {
   18.93 -    FUNCTION_MSG("XnAddWatch - %s = %s\n", path, response);
   18.94 -    XenPci_FreeMem(response);
   18.95 -    status = STATUS_UNSUCCESSFUL;
   18.96 -  }
   18.97 -  return status;
   18.98 -}
   18.99 +  CHAR path[128];
  18.100  
  18.101 -NTSTATUS
  18.102 -XnRemoveWatch(XN_HANDLE handle, char *path, PXN_WATCH_CALLBACK callback, PVOID context) {
  18.103 -  WDFDEVICE device = handle;
  18.104 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.105 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.106 -  PCHAR response;
  18.107 -  NTSTATUS status;
  18.108 -
  18.109 -  response = XenBus_RemWatch(xpdd, XBT_NIL, path, callback, context);
  18.110 -  if (response == NULL) {
  18.111 -    FUNCTION_MSG("XnRemoveWatch - %s = NULL\n", path);
  18.112 -    status = STATUS_SUCCESS;
  18.113 -  } else {
  18.114 -    FUNCTION_MSG("XnRemoveWatch - %s = %s\n", path, response);
  18.115 +  FUNCTION_ENTER();
  18.116 +  RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
  18.117 +  response = XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackendStateCallback, xppdd);
  18.118 +  if (response) {
  18.119 +    FUNCTION_MSG("XnRemWatch - %s = %s\n", path, response);
  18.120      XenPci_FreeMem(response);
  18.121 -    status = STATUS_UNSUCCESSFUL;
  18.122    }
  18.123 -}
  18.124 -#endif
  18.125 -
  18.126 -evtchn_port_t
  18.127 -XnAllocateEvent(XN_HANDLE handle) {
  18.128 -  WDFDEVICE device = handle;
  18.129 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.130 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.131 -  return EvtChn_AllocUnbound(xpdd, xppdd->backend_id);
  18.132 -}
  18.133 -
  18.134 -VOID
  18.135 -XnFreeEvent(XN_HANDLE handle, evtchn_port_t port) {
  18.136 -  WDFDEVICE device = handle;
  18.137 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.138 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.139 -  EvtChn_Close(xpdd, port);
  18.140 +  xppdd->device_callback = NULL;
  18.141 +  xppdd->device_callback_context = NULL;
  18.142 +  FUNCTION_EXIT();
  18.143    return;
  18.144  }
  18.145  
  18.146  NTSTATUS
  18.147 -XnBindEvent(XN_HANDLE handle, evtchn_port_t port, PXN_EVENT_CALLBACK callback, PVOID context) {
  18.148 -  WDFDEVICE device = handle;
  18.149 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.150 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.151 -  return EvtChn_Bind(xpdd, port, callback, context, EVT_ACTION_FLAGS_DEFAULT);
  18.152 +XnBindEvent(XN_HANDLE handle, evtchn_port_t *port, PXN_EVENT_CALLBACK callback, PVOID context) {
  18.153 +  PXENPCI_PDO_DEVICE_DATA xppdd = handle;
  18.154 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
  18.155 +  *port = EvtChn_AllocUnbound(xpdd, xppdd->backend_id);
  18.156 +  return EvtChn_Bind(xpdd, *port, callback, context, EVT_ACTION_FLAGS_DEFAULT);
  18.157  }
  18.158  
  18.159  NTSTATUS
  18.160 -XnUnBindEvent(XN_HANDLE handle, evtchn_port_t port) {
  18.161 -  WDFDEVICE device = handle;
  18.162 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.163 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.164 -  return EvtChn_Unbind(xpdd, port);
  18.165 +XnUnbindEvent(XN_HANDLE handle, evtchn_port_t port) {
  18.166 +  PXENPCI_PDO_DEVICE_DATA xppdd = handle;
  18.167 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
  18.168 +  EvtChn_Unbind(xpdd, port);
  18.169 +  EvtChn_Close(xpdd, port);
  18.170 +  return STATUS_SUCCESS;
  18.171  }
  18.172  
  18.173  grant_ref_t
  18.174 -XnGrantAccess(XN_HANDLE handle, uint32_t frame, int readonly, grant_ref_t ref, ULONG tag)
  18.175 -{
  18.176 -  WDFDEVICE device = handle;
  18.177 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.178 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.179 +XnGrantAccess(XN_HANDLE handle, uint32_t frame, int readonly, grant_ref_t ref, ULONG tag) {
  18.180 +  PXENPCI_PDO_DEVICE_DATA xppdd = handle;
  18.181 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;  
  18.182    return GntTbl_GrantAccess(xpdd, xppdd->backend_id, frame, readonly, ref, tag);
  18.183  }
  18.184  
  18.185  BOOLEAN
  18.186 -XnEndAccess(XN_HANDLE handle, grant_ref_t ref, BOOLEAN keepref, ULONG tag)
  18.187 -{
  18.188 -  WDFDEVICE device = handle;
  18.189 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.190 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.191 +XnEndAccess(XN_HANDLE handle, grant_ref_t ref, BOOLEAN keepref, ULONG tag) {
  18.192 +  PXENPCI_PDO_DEVICE_DATA xppdd = handle;
  18.193 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
  18.194    return GntTbl_EndAccess(xpdd, ref, keepref, tag);
  18.195  }
  18.196  
  18.197  grant_ref_t
  18.198  XnAllocateGrant(XN_HANDLE handle, ULONG tag) {
  18.199 -  WDFDEVICE device = handle;
  18.200 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.201 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.202 +  PXENPCI_PDO_DEVICE_DATA xppdd = handle;
  18.203 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
  18.204    return GntTbl_GetRef(xpdd, tag);
  18.205  }
  18.206  
  18.207  VOID
  18.208  XnFreeGrant(XN_HANDLE handle, grant_ref_t ref, ULONG tag) {
  18.209 -  WDFDEVICE device = handle;
  18.210 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.211 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.212 +  PXENPCI_PDO_DEVICE_DATA xppdd = handle;
  18.213 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
  18.214    GntTbl_PutRef(xpdd, ref, tag);
  18.215  }
  18.216  
  18.217  /* result must be freed with XnFreeMem() */
  18.218  NTSTATUS
  18.219  XnReadString(XN_HANDLE handle, ULONG base, PCHAR path, PCHAR *value) {
  18.220 -  WDFDEVICE device = handle;
  18.221 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.222 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.223 +  PXENPCI_PDO_DEVICE_DATA xppdd = handle;
  18.224 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
  18.225    PCHAR response;
  18.226    CHAR full_path[1024];
  18.227    
  18.228    switch(base) {
  18.229    case XN_BASE_FRONTEND:
  18.230 -    strncpy(full_path, xppdd->path, 1024);
  18.231 +    RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
  18.232      break;
  18.233    case XN_BASE_BACKEND:
  18.234 -    strncpy(full_path, xppdd->backend_path, 1024);
  18.235 +    RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
  18.236      break;
  18.237    case XN_BASE_GLOBAL:
  18.238 -    strncpy(full_path, "", 1024);
  18.239 +    full_path[0] = 0;
  18.240    }
  18.241 -  strncat(full_path, "/", 1024);
  18.242 -  strncat(full_path, path, 1024);
  18.243 +  RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
  18.244 +  RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
  18.245    
  18.246    response = XenBus_Read(xpdd, XBT_NIL, full_path, value);
  18.247    if (response) {
  18.248 -    FUNCTION_MSG("Error reading shutdown path - %s\n", response);
  18.249 +    FUNCTION_MSG("Error reading %s - %s\n", full_path, response);
  18.250      XenPci_FreeMem(response);
  18.251 -    FUNCTION_EXIT();
  18.252      return STATUS_UNSUCCESSFUL;
  18.253    }
  18.254    return STATUS_SUCCESS;
  18.255 @@ -241,24 +181,24 @@ XnReadString(XN_HANDLE handle, ULONG bas
  18.256  
  18.257  NTSTATUS
  18.258  XnWriteString(XN_HANDLE handle, ULONG base, PCHAR path, PCHAR value) {
  18.259 -  WDFDEVICE device = handle;
  18.260 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.261 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.262 +  PXENPCI_PDO_DEVICE_DATA xppdd = handle;
  18.263 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
  18.264    PCHAR response;
  18.265    CHAR full_path[1024];
  18.266  
  18.267    switch(base) {
  18.268    case XN_BASE_FRONTEND:
  18.269 -    strncpy(full_path, xppdd->path, 1024);
  18.270 +    RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
  18.271      break;
  18.272    case XN_BASE_BACKEND:
  18.273 -    strncpy(full_path, xppdd->backend_path, 1024);
  18.274 +    RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
  18.275      break;
  18.276    case XN_BASE_GLOBAL:
  18.277 -    strncpy(full_path, "", 1024);
  18.278 +    full_path[0] = 0;
  18.279    }
  18.280 -  strncat(full_path, "/", 1024);
  18.281 -  strncat(full_path, path, 1024);
  18.282 +  RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
  18.283 +  RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
  18.284 +
  18.285    FUNCTION_MSG("XnWriteString(%s, %s)\n", full_path, value);
  18.286    response = XenBus_Write(xpdd, XBT_NIL, full_path, value);
  18.287    if (response) {
  18.288 @@ -272,25 +212,25 @@ XnWriteString(XN_HANDLE handle, ULONG ba
  18.289  
  18.290  NTSTATUS
  18.291  XnReadInt32(XN_HANDLE handle, ULONG base, PCHAR path, ULONG *value) {
  18.292 -  WDFDEVICE device = handle;
  18.293 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.294 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.295 +  PXENPCI_PDO_DEVICE_DATA xppdd = handle;
  18.296 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
  18.297    CHAR full_path[1024];
  18.298    PCHAR response;
  18.299    PCHAR string_value;
  18.300  
  18.301    switch(base) {
  18.302    case XN_BASE_FRONTEND:
  18.303 -    strncpy(full_path, xppdd->path, 1024);
  18.304 +    RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
  18.305      break;
  18.306    case XN_BASE_BACKEND:
  18.307 -    strncpy(full_path, xppdd->backend_path, 1024);
  18.308 +    RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
  18.309      break;
  18.310    case XN_BASE_GLOBAL:
  18.311 -    strncpy(full_path, "", 1024);
  18.312 +    full_path[0] = 0;
  18.313    }
  18.314 -  strncat(full_path, "/", 1024);
  18.315 -  strncat(full_path, path, 1024);
  18.316 +  RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
  18.317 +  RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
  18.318 +
  18.319    response = XenBus_Read(xpdd, XBT_NIL, full_path, &string_value);
  18.320    if (response) {
  18.321      FUNCTION_MSG("XnReadInt - %s = %s\n", full_path, response);
  18.322 @@ -304,24 +244,23 @@ XnReadInt32(XN_HANDLE handle, ULONG base
  18.323  
  18.324  NTSTATUS
  18.325  XnWriteInt32(XN_HANDLE handle, ULONG base, PCHAR path, ULONG value) {
  18.326 -  WDFDEVICE device = handle;
  18.327 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.328 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.329 +  PXENPCI_PDO_DEVICE_DATA xppdd = handle;
  18.330 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
  18.331    CHAR full_path[1024];
  18.332    PCHAR response;
  18.333    
  18.334    switch(base) {
  18.335    case XN_BASE_FRONTEND:
  18.336 -    strncpy(full_path, xppdd->path, 1024);
  18.337 +    RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
  18.338      break;
  18.339    case XN_BASE_BACKEND:
  18.340 -    strncpy(full_path, xppdd->backend_path, 1024);
  18.341 +    RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
  18.342      break;
  18.343    case XN_BASE_GLOBAL:
  18.344 -    strncpy(full_path, "", 1024);
  18.345 +    full_path[0] = 0;
  18.346    }
  18.347 -  strncat(full_path, "/", 1024);
  18.348 -  strncat(full_path, path, 1024);
  18.349 +  RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
  18.350 +  RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
  18.351    
  18.352    FUNCTION_MSG("XnWriteInt32(%s, %d)\n", full_path, value);
  18.353    response = XenBus_Printf(xpdd, XBT_NIL, full_path, "%d", value);
  18.354 @@ -336,9 +275,8 @@ XnWriteInt32(XN_HANDLE handle, ULONG bas
  18.355  
  18.356  NTSTATUS
  18.357  XnReadInt64(XN_HANDLE handle, ULONG base, PCHAR path, ULONGLONG *value) {
  18.358 -  WDFDEVICE device = handle;
  18.359 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.360 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.361 +  PXENPCI_PDO_DEVICE_DATA xppdd = handle;
  18.362 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
  18.363    CHAR full_path[1024];
  18.364    PCHAR response;
  18.365    PCHAR string_value;
  18.366 @@ -346,17 +284,17 @@ XnReadInt64(XN_HANDLE handle, ULONG base
  18.367  
  18.368    switch(base) {
  18.369    case XN_BASE_FRONTEND:
  18.370 -    strncpy(full_path, xppdd->path, 1024);
  18.371 +    RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
  18.372      break;
  18.373    case XN_BASE_BACKEND:
  18.374 -    strncpy(full_path, xppdd->backend_path, 1024);
  18.375 +    RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
  18.376      break;
  18.377    case XN_BASE_GLOBAL:
  18.378 -    strncpy(full_path, "", 1024);
  18.379 -    break;
  18.380 +    full_path[0] = 0;
  18.381    }
  18.382 -  strncat(full_path, "/", 1024);
  18.383 -  strncat(full_path, path, 1024);
  18.384 +  RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
  18.385 +  RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
  18.386 +
  18.387    response = XenBus_Read(xpdd, XBT_NIL, full_path, &string_value);
  18.388    if (response) {
  18.389      FUNCTION_MSG("XnReadInt - %s = %s\n", full_path, response);
  18.390 @@ -374,24 +312,23 @@ XnReadInt64(XN_HANDLE handle, ULONG base
  18.391  
  18.392  NTSTATUS
  18.393  XnWriteInt64(XN_HANDLE handle, ULONG base, PCHAR path, ULONGLONG value) {
  18.394 -  WDFDEVICE device = handle;
  18.395 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.396 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.397 +  PXENPCI_PDO_DEVICE_DATA xppdd = handle;
  18.398 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
  18.399    CHAR full_path[1024];
  18.400    PCHAR response;
  18.401    
  18.402    switch(base) {
  18.403    case XN_BASE_FRONTEND:
  18.404 -    strncpy(full_path, xppdd->path, 1024);
  18.405 +    RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->path);
  18.406      break;
  18.407    case XN_BASE_BACKEND:
  18.408 -    strncpy(full_path, xppdd->backend_path, 1024);
  18.409 +    RtlStringCbCopyA(full_path, ARRAY_SIZE(full_path), xppdd->backend_path);
  18.410      break;
  18.411    case XN_BASE_GLOBAL:
  18.412 -    strncpy(full_path, "", 1024);
  18.413 +    full_path[0] = 0;
  18.414    }
  18.415 -  strncat(full_path, "/", 1024);
  18.416 -  strncat(full_path, path, 1024);
  18.417 +  RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), "/");
  18.418 +  RtlStringCbCatA(full_path, ARRAY_SIZE(full_path), path);
  18.419    
  18.420    response = XenBus_Printf(xpdd, XBT_NIL, full_path, "%I64d", value);
  18.421    if (response) {
  18.422 @@ -405,19 +342,16 @@ XnWriteInt64(XN_HANDLE handle, ULONG bas
  18.423  
  18.424  NTSTATUS
  18.425  XnNotify(XN_HANDLE handle, evtchn_port_t port) {
  18.426 -  WDFDEVICE device = handle;
  18.427 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.428 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.429 -  
  18.430 +  PXENPCI_PDO_DEVICE_DATA xppdd = handle;
  18.431 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;  
  18.432    return EvtChn_Notify(xpdd, port);
  18.433  }
  18.434  
  18.435  /* called at PASSIVE_LEVEL */
  18.436  VOID
  18.437  XnGetValue(XN_HANDLE handle, ULONG value_type, PVOID value) {
  18.438 -  WDFDEVICE device = handle;
  18.439 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.440 -  //PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.441 +  PXENPCI_PDO_DEVICE_DATA xppdd = handle;
  18.442 +  //PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
  18.443    DECLARE_UNICODE_STRING_SIZE(my_device_name, 128);
  18.444    ULONG i;
  18.445  
  18.446 @@ -444,193 +378,8 @@ XnGetValue(XN_HANDLE handle, ULONG value
  18.447    }
  18.448  }
  18.449  
  18.450 -#if 0
  18.451 -static NTSTATUS
  18.452 -XenConfig_InitConfigPage(WDFDEVICE device)
  18.453 -{
  18.454 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.455 -  //PXENCONFIG_DEVICE_DATA xcdd = (PXENCONFIG_DEVICE_DATA)device_object->DeviceExtension;
  18.456 -  //PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
  18.457 -  //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
  18.458 -  PUCHAR ptr;
  18.459 -  PDEVICE_OBJECT curr, prev;
  18.460 -  PDRIVER_OBJECT fdo_driver_object;
  18.461 -  PUCHAR fdo_driver_extension;
  18.462 -  
  18.463 -  FUNCTION_ENTER();
  18.464 -  
  18.465 -  ptr = MmGetMdlVirtualAddress(xppdd->config_page_mdl);
  18.466 -  curr = IoGetAttachedDeviceReference(WdfDeviceWdmGetDeviceObject(device));
  18.467 -  //curr = WdfDeviceWdmGetAttachedDevice(device);
  18.468 -  while (curr != NULL)
  18.469 -  {
  18.470 -    fdo_driver_object = curr->DriverObject;
  18.471 -    KdPrint((__DRIVER_NAME "     fdo_driver_object = %p\n", fdo_driver_object));
  18.472 -    if (fdo_driver_object)
  18.473 -    {
  18.474 -      fdo_driver_extension = IoGetDriverObjectExtension(fdo_driver_object, UlongToPtr(XEN_INIT_DRIVER_EXTENSION_MAGIC));
  18.475 -      KdPrint((__DRIVER_NAME "     fdo_driver_extension = %p\n", fdo_driver_extension));
  18.476 -      if (fdo_driver_extension)
  18.477 -      {
  18.478 -        memcpy(ptr, fdo_driver_extension, PAGE_SIZE);
  18.479 -        ObDereferenceObject(curr);
  18.480 -        break;
  18.481 -      }
  18.482 -    }
  18.483 -    prev = curr;
  18.484 -    curr = IoGetLowerDeviceObject(curr);
  18.485 -    ObDereferenceObject(prev);
  18.486 -  }
  18.487 -  
  18.488 -  FUNCTION_EXIT();
  18.489 -  
  18.490 -  return STATUS_SUCCESS;
  18.491 -}
  18.492 -
  18.493 -static NTSTATUS
  18.494 -XenPci_EvtChn_Bind(PVOID context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
  18.495 -{
  18.496 -  WDFDEVICE device = context;
  18.497 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.498 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.499 -  
  18.500 -  return EvtChn_Bind(xpdd, Port, ServiceRoutine, ServiceContext, EVT_ACTION_FLAGS_DEFAULT);
  18.501 -}
  18.502 -
  18.503 -static NTSTATUS
  18.504 -XenPci_EvtChn_BindDpc(PVOID context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
  18.505 -{
  18.506 -  WDFDEVICE device = context;
  18.507 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.508 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.509 -  
  18.510 -  return EvtChn_BindDpc(xpdd, Port, ServiceRoutine, ServiceContext, EVT_ACTION_FLAGS_DEFAULT);
  18.511 -}
  18.512 -
  18.513 -static NTSTATUS
  18.514 -XenPci_EvtChn_Unbind(PVOID context, evtchn_port_t Port)
  18.515 -{
  18.516 -  WDFDEVICE device = context;
  18.517 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.518 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.519 -  
  18.520 -  return EvtChn_Unbind(xpdd, Port);
  18.521 -}
  18.522 -
  18.523 -static NTSTATUS
  18.524 -XenPci_EvtChn_Mask(PVOID context, evtchn_port_t Port)
  18.525 -{
  18.526 -  WDFDEVICE device = context;
  18.527 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.528 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.529 -  
  18.530 -  return EvtChn_Mask(xpdd, Port);
  18.531 -}
  18.532 -
  18.533 -static NTSTATUS
  18.534 -XenPci_EvtChn_Unmask(PVOID context, evtchn_port_t Port)
  18.535 -{
  18.536 -  WDFDEVICE device = context;
  18.537 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.538 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.539 -  
  18.540 -  return EvtChn_Unmask(xpdd, Port);
  18.541 +/* called by storage devices in dump mode to re-hook DebugPrint */
  18.542 +VOID
  18.543 +XnDumpModeHookDebugPrint() {
  18.544 +  XenPci_DumpModeHookDebugPrint();
  18.545  }
  18.546 -
  18.547 -static BOOLEAN
  18.548 -XenPci_EvtChn_AckEvent(PVOID context, evtchn_port_t port, BOOLEAN *last_interrupt)
  18.549 -{
  18.550 -  WDFDEVICE device = context;
  18.551 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.552 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.553 -  
  18.554 -  return EvtChn_AckEvent(xpdd, port, last_interrupt);
  18.555 -}
  18.556 -
  18.557 -typedef struct {
  18.558 -  PXEN_EVTCHN_SYNC_ROUTINE sync_routine;
  18.559 -  PVOID sync_context;
  18.560 -} sync_context_t;
  18.561 -
  18.562 -static BOOLEAN
  18.563 -XenPci_EvtChn_Sync_Routine(WDFINTERRUPT interrupt, WDFCONTEXT context)
  18.564 -{
  18.565 -  sync_context_t *wdf_sync_context = context;
  18.566 -  UNREFERENCED_PARAMETER(interrupt);
  18.567 -  return wdf_sync_context->sync_routine(wdf_sync_context->sync_context);
  18.568 -}
  18.569 -
  18.570 -static BOOLEAN
  18.571 -XenPci_EvtChn_Sync(PVOID context, PXEN_EVTCHN_SYNC_ROUTINE sync_routine, PVOID sync_context)
  18.572 -{
  18.573 -  WDFDEVICE device = context;
  18.574 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.575 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.576 -  sync_context_t wdf_sync_context;
  18.577 -  
  18.578 -  wdf_sync_context.sync_routine = sync_routine;
  18.579 -  wdf_sync_context.sync_context = sync_context;
  18.580 -  
  18.581 -  return WdfInterruptSynchronize(xpdd->interrupt, XenPci_EvtChn_Sync_Routine, &wdf_sync_context);
  18.582 -}
  18.583 -
  18.584 -
  18.585 -PCHAR
  18.586 -XenPci_XenBus_Read(PVOID context, xenbus_transaction_t xbt, char *path, char **value)
  18.587 -{
  18.588 -  WDFDEVICE device = context;
  18.589 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.590 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.591 -  return XenBus_Read(xpdd, xbt, path, value);
  18.592 -}
  18.593 -
  18.594 -PCHAR
  18.595 -XenPci_XenBus_Write(PVOID context, xenbus_transaction_t xbt, char *path, char *value)
  18.596 -{
  18.597 -  WDFDEVICE device = context;
  18.598 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.599 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.600 -  return XenBus_Write(xpdd, xbt, path, value);
  18.601 -}
  18.602 -
  18.603 -PCHAR
  18.604 -XenPci_XenBus_Printf(PVOID context, xenbus_transaction_t xbt, char *path, char *fmt, ...)
  18.605 -{
  18.606 -  //PXENPCI_PDO_DEVICE_DATA xppdd = Context;
  18.607 -  //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
  18.608 -  //return XenBus_Printf(xpdd, xbt, path, value);
  18.609 -  UNREFERENCED_PARAMETER(context);
  18.610 -  UNREFERENCED_PARAMETER(xbt);
  18.611 -  UNREFERENCED_PARAMETER(path);
  18.612 -  UNREFERENCED_PARAMETER(fmt);
  18.613 -  return NULL;
  18.614 -}
  18.615 -
  18.616 -PCHAR
  18.617 -XenPci_XenBus_StartTransaction(PVOID context, xenbus_transaction_t *xbt)
  18.618 -{
  18.619 -  WDFDEVICE device = context;
  18.620 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.621 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.622 -  return XenBus_StartTransaction(xpdd, xbt);
  18.623 -}
  18.624 -
  18.625 -PCHAR
  18.626 -XenPci_XenBus_EndTransaction(PVOID context, xenbus_transaction_t xbt, int abort, int *retry)
  18.627 -{
  18.628 -  WDFDEVICE device = context;
  18.629 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.630 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.631 -  return XenBus_EndTransaction(xpdd, xbt, abort, retry);
  18.632 -}
  18.633 -
  18.634 -PCHAR
  18.635 -XenPci_XenBus_List(PVOID context, xenbus_transaction_t xbt, char *prefix, char ***contents)
  18.636 -{
  18.637 -  WDFDEVICE device = context;
  18.638 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  18.639 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  18.640 -  return XenBus_List(xpdd, xbt, prefix, contents);
  18.641 -}
  18.642 -
  18.643 -#endif
    19.1 --- a/xenpci/xenpci_fdo.c	Sun Jan 06 14:08:22 2013 +1100
    19.2 +++ b/xenpci/xenpci_fdo.c	Sat Feb 02 18:51:07 2013 +1100
    19.3 @@ -470,26 +470,23 @@ XenPci_Suspend0(PVOID context)
    19.4    
    19.5    cancelled = hvm_shutdown(xpdd, SHUTDOWN_suspend);
    19.6  
    19.7 -  if (__readmsr(0x174) != sysenter_cs)
    19.8 -  {
    19.9 +  /* this code was to fix a bug that existed in Xen for a short time... it is harmless but can probably be removed */
   19.10 +  if (__readmsr(0x174) != sysenter_cs) {
   19.11      KdPrint((__DRIVER_NAME "     sysenter_cs not restored. Fixing.\n"));
   19.12      __writemsr(0x174, sysenter_cs);
   19.13    }
   19.14 -  if (__readmsr(0x175) != sysenter_esp)
   19.15 -  {
   19.16 +  if (__readmsr(0x175) != sysenter_esp) {
   19.17      KdPrint((__DRIVER_NAME "     sysenter_esp not restored. Fixing.\n"));
   19.18      __writemsr(0x175, sysenter_esp);
   19.19    }
   19.20 -  if (__readmsr(0x176) != sysenter_eip)
   19.21 -  {
   19.22 +  if (__readmsr(0x176) != sysenter_eip) {
   19.23        KdPrint((__DRIVER_NAME "     sysenter_eip not restored. Fixing.\n"));
   19.24      __writemsr(0x176, sysenter_eip);
   19.25    }
   19.26  
   19.27    KdPrint((__DRIVER_NAME "     back from suspend, cancelled = %d\n", cancelled));
   19.28  
   19.29 -  if (qemu_hide_flags_value)
   19.30 -  {
   19.31 +  if (qemu_hide_flags_value) {
   19.32      XenPci_HideQemuDevices();
   19.33    }
   19.34  
   19.35 @@ -517,8 +514,7 @@ XenPci_ConnectSuspendEvt(PXENPCI_DEVICE_
   19.36  
   19.37  /* called at PASSIVE_LEVEL */
   19.38  static NTSTATUS
   19.39 -XenPci_ConnectSuspendEvt(PXENPCI_DEVICE_DATA xpdd)
   19.40 -{
   19.41 +XenPci_ConnectSuspendEvt(PXENPCI_DEVICE_DATA xpdd) {
   19.42    CHAR path[128];
   19.43  
   19.44    xpdd->suspend_evtchn = EvtChn_AllocUnbound(xpdd, 0);
   19.45 @@ -532,8 +528,7 @@ XenPci_ConnectSuspendEvt(PXENPCI_DEVICE_
   19.46  
   19.47  /* Called at PASSIVE_LEVEL */
   19.48  static VOID
   19.49 -XenPci_SuspendResume(WDFWORKITEM workitem)
   19.50 -{
   19.51 +XenPci_SuspendResume(WDFWORKITEM workitem) {
   19.52    NTSTATUS status;
   19.53    //KAFFINITY ActiveProcessorMask = 0; // this is for Vista+
   19.54    WDFDEVICE device = WdfWorkItemGetParentObject(workitem);
   19.55 @@ -544,19 +539,17 @@ XenPci_SuspendResume(WDFWORKITEM workite
   19.56  
   19.57    FUNCTION_ENTER();
   19.58  
   19.59 -  if (xpdd->suspend_state == SUSPEND_STATE_NONE)
   19.60 -  {
   19.61 +  if (xpdd->suspend_state == SUSPEND_STATE_NONE) {
   19.62 +    KeAcquireGuardedMutex(&xpdd->suspend_mutex);
   19.63      xpdd->suspend_state = SUSPEND_STATE_SCHEDULED;
   19.64      KeMemoryBarrier();
   19.65 -
   19.66 +    
   19.67 +    // how to prevent device addition etc here? is it implied because dom0 initiated the suspend?
   19.68      WDF_CHILD_LIST_ITERATOR_INIT(&child_iterator, WdfRetrievePresentChildren);
   19.69 +      
   19.70      WdfChildListBeginIteration(child_list, &child_iterator);
   19.71 -    while ((status = WdfChildListRetrieveNextDevice(child_list, &child_iterator, &child_device, NULL)) == STATUS_SUCCESS)
   19.72 -    {
   19.73 -      KdPrint((__DRIVER_NAME "     Suspending child\n"));
   19.74 -#if 0
   19.75 -      XenPci_Pdo_Suspend(child_device);
   19.76 -#endif
   19.77 +    while ((status = WdfChildListRetrieveNextDevice(child_list, &child_iterator, &child_device, NULL)) == STATUS_SUCCESS) {
   19.78 +      XenPci_SuspendPdo(child_device);
   19.79      }
   19.80      WdfChildListEndIteration(child_list, &child_iterator);
   19.81  
   19.82 @@ -570,16 +563,13 @@ XenPci_SuspendResume(WDFWORKITEM workite
   19.83      XenPci_ConnectSuspendEvt(xpdd);
   19.84  
   19.85      WdfChildListBeginIteration(child_list, &child_iterator);
   19.86 -    while ((status = WdfChildListRetrieveNextDevice(child_list, &child_iterator, &child_device, NULL)) == STATUS_SUCCESS)
   19.87 -    {
   19.88 -      KdPrint((__DRIVER_NAME "     Resuming child\n"));
   19.89 -#if 0
   19.90 -      XenPci_Pdo_Resume(child_device);
   19.91 -#endif
   19.92 +    while ((status = WdfChildListRetrieveNextDevice(child_list, &child_iterator, &child_device, NULL)) == STATUS_SUCCESS) {
   19.93 +      XenPci_ResumePdo(child_device);
   19.94      }
   19.95      WdfChildListEndIteration(child_list, &child_iterator);
   19.96  
   19.97      xpdd->suspend_state = SUSPEND_STATE_NONE;
   19.98 +    KeReleaseGuardedMutex(&xpdd->suspend_mutex);
   19.99    }
  19.100    FUNCTION_EXIT();
  19.101  }
  19.102 @@ -948,15 +938,13 @@ XenPci_EvtDeviceD0ExitPreInterruptsDisab
  19.103  }
  19.104  
  19.105  NTSTATUS
  19.106 -XenPci_EvtDeviceD0Exit(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state)
  19.107 -{
  19.108 +XenPci_EvtDeviceD0Exit(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state) {
  19.109    NTSTATUS status = STATUS_SUCCESS;
  19.110    PXENPCI_DEVICE_DATA xpdd = GetXpdd(device);
  19.111    
  19.112    FUNCTION_ENTER();
  19.113  
  19.114 -  switch (target_state)
  19.115 -  {
  19.116 +  switch (target_state) {
  19.117    case WdfPowerDeviceD0:
  19.118      KdPrint((__DRIVER_NAME "     WdfPowerDeviceD1\n"));
  19.119      break;
  19.120 @@ -981,15 +969,11 @@ XenPci_EvtDeviceD0Exit(WDFDEVICE device,
  19.121      break;  
  19.122    }
  19.123    
  19.124 -  if (target_state == WdfPowerDeviceD3Final)
  19.125 -  {
  19.126 +  if (target_state == WdfPowerDeviceD3Final) {
  19.127      /* we don't really support exit here */
  19.128 -  }
  19.129 -  else
  19.130 -  {
  19.131 +  } else {
  19.132      EvtChn_Suspend(xpdd);
  19.133      GntTbl_Suspend(xpdd);
  19.134 -    
  19.135    }
  19.136  
  19.137    FUNCTION_EXIT();
    20.1 --- a/xenpci/xenpci_pdo.c	Sun Jan 06 14:08:22 2013 +1100
    20.2 +++ b/xenpci/xenpci_pdo.c	Sat Feb 02 18:51:07 2013 +1100
    20.3 @@ -31,10 +31,12 @@ static EVT_WDF_DEVICE_D0_EXIT XenPciPdo_
    20.4  static EVT_WDF_DEVICE_PREPARE_HARDWARE XenPciPdo_EvtDevicePrepareHardware;
    20.5  static EVT_WDF_DEVICE_RELEASE_HARDWARE XenPciPdo_EvtDeviceReleaseHardware;
    20.6  static EVT_WDF_DEVICE_USAGE_NOTIFICATION XenPciPdo_EvtDeviceUsageNotification;
    20.7 -static EVT_WDFDEVICE_WDM_IRP_PREPROCESS XenPciPdo_EvtDeviceWdmIrpPreprocess_START_DEVICE;
    20.8 -static EVT_WDF_DEVICE_RESOURCE_REQUIREMENTS_QUERY XenPciPdo_EvtDeviceResourceRequirementsQuery;
    20.9 +//static EVT_WDFDEVICE_WDM_IRP_PREPROCESS XenPciPdo_EvtDeviceWdmIrpPreprocess_START_DEVICE;
   20.10 +//static EVT_WDF_DEVICE_RESOURCE_REQUIREMENTS_QUERY XenPciPdo_EvtDeviceResourceRequirementsQuery;
   20.11  static EVT_WDF_DEVICE_PNP_STATE_CHANGE_NOTIFICATION XenPci_EvtDevicePnpStateChange;
   20.12  
   20.13 +
   20.14 +      
   20.15  /*
   20.16  Called at PASSIVE_LEVEL(?)
   20.17  Called during restore
   20.18 @@ -63,23 +65,6 @@ XenPci_ReadBackendState(PXENPCI_PDO_DEVI
   20.19    }
   20.20  }
   20.21  
   20.22 -#if 0
   20.23 -static NTSTATUS
   20.24 -XenPciPdo_ReconfigureCompletionRoutine(
   20.25 -  PDEVICE_OBJECT device_object,
   20.26 -  PIRP irp,
   20.27 -  PVOID context)
   20.28 -{
   20.29 -  UNREFERENCED_PARAMETER(device_object);
   20.30 -  
   20.31 -  if (irp->PendingReturned)
   20.32 -  {
   20.33 -    KeSetEvent ((PKEVENT)context, IO_NO_INCREMENT, FALSE);
   20.34 -  }
   20.35 -  return STATUS_MORE_PROCESSING_REQUIRED;
   20.36 -}
   20.37 -#endif
   20.38 -
   20.39  static VOID
   20.40  XenPci_UpdateBackendState(PVOID context)
   20.41  {
   20.42 @@ -207,610 +192,52 @@ XenPci_GetBackendDetails(WDFDEVICE devic
   20.43    }
   20.44    xppdd->backend_id = (domid_t)atoi(value);
   20.45    XenPci_FreeMem(value);
   20.46 -#if 0
   20.47 -  /* Add watch on backend state */
   20.48 -  RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
   20.49 -  XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackendStateHandler, device);
   20.50 -#endif
   20.51 -
   20.52    FUNCTION_EXIT();  
   20.53    return STATUS_SUCCESS;
   20.54  }
   20.55  
   20.56 -/*
   20.57 -Called at PASSIVE_LEVEL
   20.58 -Called during restore
   20.59 -*/
   20.60 -
   20.61 -static NTSTATUS
   20.62 -XenPci_ChangeFrontendState(WDFDEVICE device, ULONG frontend_state_set, ULONG backend_state_response, ULONG maximum_wait_ms)
   20.63 -{
   20.64 +NTSTATUS
   20.65 +XenPci_SuspendPdo(WDFDEVICE device) {
   20.66    PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
   20.67 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
   20.68 -  LARGE_INTEGER timeout;
   20.69 -  ULONG remaining;
   20.70 -  ULONG thiswait;
   20.71 -  char path[128];
   20.72 -  
   20.73 -  FUNCTION_ENTER();
   20.74 -  
   20.75 -  xppdd->frontend_state = frontend_state_set;
   20.76 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
   20.77 +  PCHAR response;
   20.78 +  CHAR path[128];
   20.79  
   20.80 -  RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
   20.81 -  XenBus_Printf(xpdd, XBT_NIL, path, "%d", frontend_state_set);
   20.82 -
   20.83 -  remaining = maximum_wait_ms;
   20.84 -
   20.85 -  while (xppdd->backend_state != backend_state_response)
   20.86 -  {
   20.87 -    thiswait = min((LONG)remaining, 1000); // 1 second or remaining time, whichever is less
   20.88 -    timeout.QuadPart = (LONGLONG)-1 * thiswait * 1000 * 10;
   20.89 -    if (KeWaitForSingleObject(&xppdd->backend_state_event, Executive, KernelMode, FALSE, &timeout) == STATUS_TIMEOUT)
   20.90 -    {
   20.91 -      /* it's possible that the workitems are blocked because the pagefile isn't available. Lets just re-read the backend value for now */
   20.92 -      XenPci_UpdateBackendState(device);
   20.93 -      remaining -= thiswait;
   20.94 -      if (remaining == 0)
   20.95 -      {
   20.96 -        KdPrint((__DRIVER_NAME "     Timed out waiting for %d!\n", backend_state_response));
   20.97 -        return STATUS_UNSUCCESSFUL;
   20.98 -      }
   20.99 -      KdPrint((__DRIVER_NAME "     Still waiting for %d (currently %d)...\n", backend_state_response, xppdd->backend_state));
  20.100 +  if (xppdd->device_callback) {
  20.101 +    FUNCTION_MSG("Suspending %s\n", xppdd->device);
  20.102 +    xppdd->device_callback(xppdd->device_callback_context, XN_DEVICE_CALLBACK_SUSPEND, NULL);
  20.103 +    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
  20.104 +    response = XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackendStateCallback, xppdd);
  20.105 +    if (response) {
  20.106 +      FUNCTION_MSG("XnRemWatch - %s = %s\n", path, response);
  20.107 +      XenPci_FreeMem(response);
  20.108      }
  20.109    }
  20.110 -  FUNCTION_EXIT();
  20.111 -  return STATUS_SUCCESS;
  20.112 -}
  20.113 -
  20.114 -#if 0
  20.115 -static NTSTATUS
  20.116 -XenPci_ChangeFrontendStateMap(WDFDEVICE device, PXENPCI_STATE_MAP_ELEMENT map)
  20.117 -{
  20.118 -  NTSTATUS status;
  20.119 -  
  20.120 -  FUNCTION_ENTER();
  20.121 -  while(map->front_target)
  20.122 -  {
  20.123 -    //KdPrint((__DRIVER_NAME "     Changing state to %d expecting %d\n", (ULONG)map->front_target, (ULONG)map->back_expected));
  20.124 -    if (!NT_SUCCESS(status = XenPci_ChangeFrontendState(device, (ULONG)map->front_target, (ULONG)map->back_expected, (ULONG)map->wait * 100)))
  20.125 -    {
  20.126 -      FUNCTION_EXIT();
  20.127 -      return status;
  20.128 -    }
  20.129 -    map++;
  20.130 -  }
  20.131 -  FUNCTION_EXIT();
  20.132 -  return STATUS_SUCCESS;
  20.133 -}
  20.134 -
  20.135 -static NTSTATUS
  20.136 -XenPci_XenConfigDevice(WDFDEVICE device);
  20.137 -
  20.138 -static NTSTATUS
  20.139 -XenPci_XenShutdownDevice(PVOID context)
  20.140 -{
  20.141 -  WDFDEVICE device = context;
  20.142 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  20.143 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  20.144 -  PUCHAR in_ptr;
  20.145 -  ULONG i;
  20.146 -  UCHAR type;
  20.147 -  PVOID setting;
  20.148 -  PVOID value;
  20.149 -  PVOID value2;
  20.150 -
  20.151 -  FUNCTION_ENTER();
  20.152 -
  20.153 -  if (xppdd->backend_state == XenbusStateConnected)
  20.154 -  {
  20.155 -    XenPci_ChangeFrontendStateMap(device, xppdd->xb_shutdown_map);
  20.156 -  }
  20.157 -  else if (xppdd->backend_state == XenbusStateClosing)
  20.158 -  {
  20.159 -      XenPci_ChangeFrontendState(device, XenbusStateClosed, XenbusStateClosed, 30000);
  20.160 -  }
  20.161 -
  20.162 -  if (xppdd->assigned_resources_start != NULL)
  20.163 -  {
  20.164 -    ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
  20.165 -    in_ptr = xppdd->assigned_resources_start;
  20.166 -    while((type = GET_XEN_INIT_RSP(&in_ptr, &setting, &value, &value2)) != XEN_INIT_TYPE_END)
  20.167 -    {
  20.168 -      switch (type)
  20.169 -      {
  20.170 -      case XEN_INIT_TYPE_RING: /* frontend ring */
  20.171 -        FreePages(value);
  20.172 -        break;
  20.173 -      case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
  20.174 -      case XEN_INIT_TYPE_EVENT_CHANNEL_DPC: /* frontend event channel bound to dpc */
  20.175 -      case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
  20.176 -        EvtChn_Unbind(xpdd, PtrToUlong(value));
  20.177 -        EvtChn_Close(xpdd, PtrToUlong(value));
  20.178 -        break;
  20.179 -      case XEN_INIT_TYPE_GRANT_ENTRIES:
  20.180 -        for (i = 0; i < PtrToUlong(value); i++)
  20.181 -          GntTbl_EndAccess(xpdd, ((grant_ref_t *)value2)[i], FALSE, PtrToUlong(setting));
  20.182 -        break;
  20.183 -      }
  20.184 -    }
  20.185 -    ExFreePoolWithTag(xppdd->assigned_resources_start, XENPCI_POOL_TAG);
  20.186 -    xppdd->assigned_resources_start = NULL;
  20.187 -  }
  20.188 -
  20.189 -  FUNCTION_EXIT();
  20.190 -
  20.191    return STATUS_SUCCESS;
  20.192  }
  20.193  
  20.194 -struct dummy_sring {
  20.195 -    RING_IDX req_prod, req_event;
  20.196 -    RING_IDX rsp_prod, rsp_event;
  20.197 -    uint8_t  pad[48];
  20.198 -};
  20.199 -#endif
  20.200 -
  20.201 -#if 0
  20.202 -static NTSTATUS
  20.203 -XenPci_XenConfigDeviceSpecifyBuffers(WDFDEVICE device, PUCHAR src, PUCHAR dst)
  20.204 -{
  20.205 +NTSTATUS
  20.206 +XenPci_ResumePdo(WDFDEVICE device) {
  20.207    PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  20.208 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  20.209 -  NTSTATUS status = STATUS_SUCCESS;
  20.210 -  ULONG i;
  20.211 -  char path[128];
  20.212 -  PCHAR setting, value;
  20.213 -  PCHAR res;
  20.214 -  PVOID address;
  20.215 -  UCHAR type;
  20.216 -  PUCHAR in_ptr;
  20.217 -  PUCHAR out_ptr;
  20.218 -  XENPCI_VECTORS vectors;
  20.219 -  ULONG event_channel;
  20.220 -  PMDL ring;
  20.221 -  grant_ref_t gref;
  20.222 -  PVOID value2;
  20.223 -  int map_no;
  20.224 - 
  20.225 -  FUNCTION_ENTER();
  20.226 -
  20.227 -  xppdd->xb_pre_connect_map[0].front_target = 0;
  20.228 -  xppdd->xb_post_connect_map[0].front_target = 0;
  20.229 -  xppdd->xb_shutdown_map[0].front_target = 0;
  20.230 -  
  20.231 -  in_ptr = src;
  20.232 -  out_ptr = dst;
  20.233 -  
  20.234 -  // always add vectors
  20.235 -  vectors.magic = XEN_DATA_MAGIC;
  20.236 -  vectors.length = sizeof(XENPCI_VECTORS);
  20.237 -  vectors.context = device;
  20.238 -  vectors.EvtChn_Bind = XenPci_EvtChn_Bind;
  20.239 -  vectors.EvtChn_BindDpc = XenPci_EvtChn_BindDpc;
  20.240 -  vectors.EvtChn_Unbind = XenPci_EvtChn_Unbind;
  20.241 -  vectors.EvtChn_Mask = XenPci_EvtChn_Mask;
  20.242 -  vectors.EvtChn_Unmask = XenPci_EvtChn_Unmask;
  20.243 -  vectors.EvtChn_Notify = XenPci_EvtChn_Notify;
  20.244 -  vectors.EvtChn_AckEvent = XenPci_EvtChn_AckEvent;
  20.245 -  vectors.EvtChn_Sync = XenPci_EvtChn_Sync;
  20.246 -  vectors.GntTbl_GetRef = XenPci_GntTbl_GetRef;
  20.247 -  vectors.GntTbl_PutRef = XenPci_GntTbl_PutRef;
  20.248 -  vectors.GntTbl_GrantAccess = XenPci_GntTbl_GrantAccess;
  20.249 -  vectors.GntTbl_EndAccess = XenPci_GntTbl_EndAccess;
  20.250 -  vectors.XenPci_XenConfigDevice = XenPci_XenConfigDevice;
  20.251 -  vectors.XenPci_XenShutdownDevice = XenPci_XenShutdownDevice;
  20.252 -  RtlStringCbCopyA(vectors.path, 128, xppdd->path);
  20.253 -  RtlStringCbCopyA(vectors.backend_path, 128, xppdd->backend_path);
  20.254 -  //vectors.pdo_event_channel = xpdd->pdo_event_channel;
  20.255 -  vectors.XenBus_Read = XenPci_XenBus_Read;
  20.256 -  vectors.XenBus_Write = XenPci_XenBus_Write;
  20.257 -  vectors.XenBus_Printf = XenPci_XenBus_Printf;
  20.258 -  vectors.XenBus_StartTransaction = XenPci_XenBus_StartTransaction;
  20.259 -  vectors.XenBus_EndTransaction = XenPci_XenBus_EndTransaction;
  20.260 -  vectors.XenBus_List = XenPci_XenBus_List;
  20.261 -  vectors.XenBus_AddWatch = XenPci_XenBus_AddWatch;
  20.262 -  vectors.XenBus_RemWatch = XenPci_XenBus_RemWatch;
  20.263 -
  20.264 -  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION, NULL, UlongToPtr(qemu_protocol_version), NULL);
  20.265 -  
  20.266 -  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_VECTORS, NULL, &vectors, NULL);
  20.267 -  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_STATE_PTR, NULL, &xppdd->device_state, NULL);
  20.268 -  
  20.269 -  // need to make sure we never get here while backend state is connected or closing...
  20.270 -  // first pass, possibly before state == Connected
  20.271 -  in_ptr = src;
  20.272 -  while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
  20.273 -  {
  20.274 -    ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, type, setting, value, value2);
  20.275 -
  20.276 -    switch (type)
  20.277 -    {
  20.278 -    case XEN_INIT_TYPE_WRITE_STRING: /* frontend setting = value */
  20.279 -      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_WRITE_STRING - %s = %s\n", setting, value));
  20.280 -      RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
  20.281 -      XenBus_Printf(xpdd, XBT_NIL, path, "%s", value);
  20.282 -      break;
  20.283 -    case XEN_INIT_TYPE_RING: /* frontend ring */
  20.284 -      /* we only allocate and do the SHARED_RING_INIT here */
  20.285 -      if ((ring = AllocatePage()) != 0)
  20.286 -      {
  20.287 -        address = MmGetMdlVirtualAddress(ring);
  20.288 -        KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, address));
  20.289 -        SHARED_RING_INIT((struct dummy_sring *)address);
  20.290 -        if ((gref = GntTbl_GrantAccess(
  20.291 -          xpdd, xppdd->backend_id, (ULONG)*MmGetMdlPfnArray(ring), FALSE, INVALID_GRANT_REF, (ULONG)'XPDO')) != INVALID_GRANT_REF)
  20.292 -        {
  20.293 -          RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
  20.294 -          KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %d\n", setting, gref));
  20.295 -          XenBus_Printf(xpdd, XBT_NIL, path, "%d", gref);
  20.296 -          ADD_XEN_INIT_RSP(&out_ptr, type, setting, address, NULL);
  20.297 -          ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, ring, NULL);
  20.298 -          // add the grant entry too so it gets freed automatically
  20.299 -          __ADD_XEN_INIT_UCHAR(&xppdd->assigned_resources_ptr, XEN_INIT_TYPE_GRANT_ENTRIES);
  20.300 -          __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, (ULONG)'XPDO');
  20.301 -          __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, 1);
  20.302 -          __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, gref);
  20.303 -        }
  20.304 -        else
  20.305 -        {
  20.306 -          FreePages(ring);
  20.307 -          status = STATUS_UNSUCCESSFUL;
  20.308 -          goto error;
  20.309 -        }
  20.310 -      }
  20.311 -      else
  20.312 -      {
  20.313 -        status = STATUS_UNSUCCESSFUL;
  20.314 -        goto error;
  20.315 -      }
  20.316 -      break;
  20.317 -    case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
  20.318 -    case XEN_INIT_TYPE_EVENT_CHANNEL_DPC: /* frontend event channel bound to dpc */
  20.319 -    case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
  20.320 -      if ((event_channel = EvtChn_AllocUnbound(xpdd, xppdd->backend_id)) != 0)
  20.321 -      {
  20.322 -        KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, event_channel));
  20.323 -        RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
  20.324 -        XenBus_Printf(xpdd, XBT_NIL, path, "%d", event_channel);
  20.325 -        ADD_XEN_INIT_RSP(&out_ptr, type, setting, UlongToPtr(event_channel), NULL);
  20.326 -        ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, UlongToPtr(event_channel), NULL);
  20.327 -        if (type == XEN_INIT_TYPE_EVENT_CHANNEL_IRQ)
  20.328 -        {
  20.329 -          EvtChn_BindIrq(xpdd, event_channel, xppdd->irq_vector, path, EVT_ACTION_FLAGS_DEFAULT);
  20.330 -        }
  20.331 -        else if (type == XEN_INIT_TYPE_EVENT_CHANNEL_DPC)
  20.332 -        {
  20.333 -          #pragma warning(suppress:4055)
  20.334 -          EvtChn_BindDpc(xpdd, event_channel, (PXEN_EVTCHN_SERVICE_ROUTINE)value, value2, EVT_ACTION_FLAGS_DEFAULT);
  20.335 -        }
  20.336 -        else
  20.337 -        {
  20.338 -          #pragma warning(suppress:4055)
  20.339 -          EvtChn_Bind(xpdd, event_channel, (PXEN_EVTCHN_SERVICE_ROUTINE)value, value2, EVT_ACTION_FLAGS_DEFAULT);
  20.340 -        }
  20.341 -      }
  20.342 -      else
  20.343 -      {
  20.344 -        status = STATUS_UNSUCCESSFUL;
  20.345 -        goto error;
  20.346 -      }
  20.347 -      break;
  20.348 -    case XEN_INIT_TYPE_XB_STATE_MAP_PRE_CONNECT:
  20.349 -      map_no = 0;
  20.350 -      while ((xppdd->xb_pre_connect_map[map_no].front_target = __GET_XEN_INIT_UCHAR(&in_ptr)) != 0)
  20.351 -      {
  20.352 -         xppdd->xb_pre_connect_map[map_no].back_expected = __GET_XEN_INIT_UCHAR(&in_ptr);
  20.353 -         xppdd->xb_pre_connect_map[map_no].wait = __GET_XEN_INIT_UCHAR(&in_ptr);
  20.354 -         __ADD_XEN_INIT_UCHAR(&xppdd->requested_resources_ptr, xppdd->xb_pre_connect_map[map_no].front_target);
  20.355 -         __ADD_XEN_INIT_UCHAR(&xppdd->requested_resources_ptr, xppdd->xb_pre_connect_map[map_no].back_expected);
  20.356 -         __ADD_XEN_INIT_UCHAR(&xppdd->requested_resources_ptr, xppdd->xb_pre_connect_map[map_no].wait);
  20.357 -         map_no++;
  20.358 -      }
  20.359 -      __ADD_XEN_INIT_UCHAR(&xppdd->requested_resources_ptr, 0);
  20.360 -      break;
  20.361 -    case XEN_INIT_TYPE_XB_STATE_MAP_POST_CONNECT:
  20.362 -      map_no = 0;
  20.363 -      while ((xppdd->xb_post_connect_map[map_no].front_target = __GET_XEN_INIT_UCHAR(&in_ptr)) != 0)
  20.364 -      {
  20.365 -         xppdd->xb_post_connect_map[map_no].back_expected = __GET_XEN_INIT_UCHAR(&in_ptr);
  20.366 -         xppdd->xb_post_connect_map[map_no].wait = __GET_XEN_INIT_UCHAR(&in_ptr);
  20.367 -         __ADD_XEN_INIT_UCHAR(&xppdd->requested_resources_ptr, xppdd->xb_post_connect_map[map_no].front_target);
  20.368 -         __ADD_XEN_INIT_UCHAR(&xppdd->requested_resources_ptr, xppdd->xb_post_connect_map[map_no].back_expected);
  20.369 -         __ADD_XEN_INIT_UCHAR(&xppdd->requested_resources_ptr, xppdd->xb_post_connect_map[map_no].wait);
  20.370 -         map_no++;
  20.371 -      }
  20.372 -      __ADD_XEN_INIT_UCHAR(&xppdd->requested_resources_ptr, 0);
  20.373 -      break;
  20.374 -    case XEN_INIT_TYPE_XB_STATE_MAP_SHUTDOWN:
  20.375 -      map_no = 0;
  20.376 -      while ((xppdd->xb_shutdown_map[map_no].front_target = __GET_XEN_INIT_UCHAR(&in_ptr)) != 0)
  20.377 -      {
  20.378 -         xppdd->xb_shutdown_map[map_no].back_expected = __GET_XEN_INIT_UCHAR(&in_ptr);
  20.379 -         xppdd->xb_shutdown_map[map_no].wait = __GET_XEN_INIT_UCHAR(&in_ptr);
  20.380 -         __ADD_XEN_INIT_UCHAR(&xppdd->requested_resources_ptr, xppdd->xb_shutdown_map[map_no].front_target);
  20.381 -         __ADD_XEN_INIT_UCHAR(&xppdd->requested_resources_ptr, xppdd->xb_shutdown_map[map_no].back_expected);
  20.382 -         __ADD_XEN_INIT_UCHAR(&xppdd->requested_resources_ptr, xppdd->xb_shutdown_map[map_no].wait);
  20.383 -         map_no++;
  20.384 -      }
  20.385 -      __ADD_XEN_INIT_UCHAR(&xppdd->requested_resources_ptr, 0);
  20.386 -      break;
  20.387 -    }
  20.388 -  }
  20.389 -  if (!NT_SUCCESS(status))
  20.390 -  {
  20.391 -    goto error;
  20.392 -  }
  20.393 -
  20.394 -  if (XenPci_ChangeFrontendStateMap(device, xppdd->xb_pre_connect_map) != STATUS_SUCCESS)
  20.395 -  {
  20.396 -    status = STATUS_UNSUCCESSFUL;
  20.397 -    goto error;
  20.398 -  }
  20.399 +  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
  20.400 +  PCHAR response;
  20.401 +  CHAR path[128];
  20.402  
  20.403 -  // second pass, possibly after state == Connected
  20.404 -  in_ptr = src;
  20.405 -  while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
  20.406 -  {
  20.407 -    switch(type)
  20.408 -    {
  20.409 -    case XEN_INIT_TYPE_READ_STRING_BACK:
  20.410 -    case XEN_INIT_TYPE_READ_STRING_FRONT:
  20.411 -      if (type == XEN_INIT_TYPE_READ_STRING_FRONT)
  20.412 -        RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
  20.413 -      else
  20.414 -        RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->backend_path, setting);
  20.415 -      res = XenBus_Read(xpdd, XBT_NIL, path, &value);
  20.416 -      if (res)
  20.417 -      {
  20.418 -        KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = <failed>\n", setting));
  20.419 -        XenPci_FreeMem(res);
  20.420 -        ADD_XEN_INIT_RSP(&out_ptr, type, setting, "", "");
  20.421 -      }
  20.422 -      else
  20.423 -      {
  20.424 -        //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
  20.425 -        ADD_XEN_INIT_RSP(&out_ptr, type, setting, value, value2);
  20.426 -        XenPci_FreeMem(value);
  20.427 -      }
  20.428 -      break;
  20.429 -    case XEN_INIT_TYPE_VECTORS:
  20.430 -      // this is always done so ignore the request
  20.431 -      break;
  20.432 -    case XEN_INIT_TYPE_GRANT_ENTRIES:
  20.433 -      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(value)));
  20.434 -      __ADD_XEN_INIT_UCHAR(&out_ptr, type);
  20.435 -      __ADD_XEN_INIT_UCHAR(&xppdd->assigned_resources_ptr, type);
  20.436 -      __ADD_XEN_INIT_ULONG(&out_ptr, PtrToUlong(setting));
  20.437 -      __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, PtrToUlong(setting));
  20.438 -      __ADD_XEN_INIT_ULONG(&out_ptr, PtrToUlong(value));
  20.439 -      __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, PtrToUlong(value));
  20.440 -      for (i = 0; i < PtrToUlong(value); i++)
  20.441 -      {
  20.442 -        gref = GntTbl_GetRef(xpdd, PtrToUlong(setting));
  20.443 -        __ADD_XEN_INIT_ULONG(&out_ptr, gref);
  20.444 -        __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, gref);
  20.445 -      }
  20.446 -      break;
  20.447 -    /* just need to eat these */
  20.448 -    case XEN_INIT_TYPE_XB_STATE_MAP_PRE_CONNECT:
  20.449 -    case XEN_INIT_TYPE_XB_STATE_MAP_POST_CONNECT:
  20.450 -    case XEN_INIT_TYPE_XB_STATE_MAP_SHUTDOWN:
  20.451 -      while ((__GET_XEN_INIT_UCHAR(&in_ptr)) != 0)
  20.452 -      {
  20.453 -         __GET_XEN_INIT_UCHAR(&in_ptr);
  20.454 -         __GET_XEN_INIT_UCHAR(&in_ptr);
  20.455 -      }
  20.456 -      break;
  20.457 +  XenPci_GetBackendDetails(device);
  20.458 +  if (xppdd->device_callback) {
  20.459 +    FUNCTION_MSG("Resuming %s\n", xppdd->device);
  20.460 +    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
  20.461 +    response = XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackendStateCallback, xppdd);
  20.462 +    if (response) {
  20.463 +      FUNCTION_MSG("XnAddWatch - %s = %s\n", path, response);
  20.464 +      XenPci_FreeMem(response);
  20.465 +      xppdd->device_callback = NULL;
  20.466 +      xppdd->device_callback_context = NULL;
  20.467 +      FUNCTION_EXIT();
  20.468 +      return STATUS_UNSUCCESSFUL;
  20.469      }
  20.470 -  }
  20.471 -  if (qemu_hide_flags_value)
  20.472 -  {
  20.473 -    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_QEMU_HIDE_FLAGS, NULL, UlongToPtr(qemu_hide_flags_value), NULL);
  20.474 -  }
  20.475 -  else
  20.476 -  {
  20.477 -    DECLARE_UNICODE_STRING_SIZE(my_device_name, 128);
  20.478 -    
  20.479 -    RtlUnicodeStringPrintf(&my_device_name, L"#%S#", xppdd->device);
  20.480 -    
  20.481 -    for (i = 0; i < WdfCollectionGetCount(qemu_hide_devices); i++)
  20.482 -    {
  20.483 -      WDFSTRING wdf_string = WdfCollectionGetItem(qemu_hide_devices, i);
  20.484 -      UNICODE_STRING hide_device_name;
  20.485 -      
  20.486 -      WdfStringGetUnicodeString(wdf_string, &hide_device_name);
  20.487 -      
  20.488 -      if (RtlCompareUnicodeString(&hide_device_name, &my_device_name, TRUE) != 0)
  20.489 -      {
  20.490 -        ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_QEMU_HIDE_FILTER, NULL, NULL, NULL);
  20.491 -        break;
  20.492 -      }
  20.493 -    }
  20.494 -  }
  20.495 -  
  20.496 -  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
  20.497 -
  20.498 -  if (XenPci_ChangeFrontendStateMap(device, xppdd->xb_post_connect_map) != STATUS_SUCCESS)
  20.499 -  {
  20.500 -    status = STATUS_UNSUCCESSFUL;
  20.501 -    goto error;
  20.502 +    xppdd->device_callback(xppdd->device_callback_context, XN_DEVICE_CALLBACK_RESUME, NULL);
  20.503    }
  20.504 -  FUNCTION_EXIT();
  20.505 -  return status;
  20.506 -
  20.507 -error:
  20.508 -  KdPrint((__DRIVER_NAME "     Error\n"));
  20.509 -  XenPci_ChangeFrontendState(device, XenbusStateInitialising, XenbusStateInitWait, 2000);
  20.510 -  FUNCTION_EXIT_STATUS(status);
  20.511 -  return status;
  20.512 -}
  20.513 -
  20.514 -static NTSTATUS
  20.515 -XenPci_XenConfigDevice(WDFDEVICE device)
  20.516 -{
  20.517 -  NTSTATUS status;
  20.518 -  PUCHAR src, dst;
  20.519 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  20.520 -
  20.521 -  src = ExAllocatePoolWithTag(NonPagedPool, xppdd->config_page_length, XENPCI_POOL_TAG);
  20.522 -  dst = MmMapIoSpace(xppdd->config_page_phys, xppdd->config_page_length, MmNonCached);
  20.523 -  memcpy(src, dst, xppdd->config_page_length);
  20.524 -  
  20.525 -  status = XenPci_XenConfigDeviceSpecifyBuffers(device, src, dst);
  20.526 -
  20.527 -  MmUnmapIoSpace(dst, xppdd->config_page_length);
  20.528 -  ExFreePoolWithTag(src, XENPCI_POOL_TAG);
  20.529 -  
  20.530 -  return status;
  20.531 -}
  20.532 -#endif
  20.533 -
  20.534 -static NTSTATUS
  20.535 -XenPciPdo_EvtDeviceWdmIrpPreprocess_START_DEVICE(WDFDEVICE device, PIRP irp)
  20.536 -{
  20.537 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  20.538 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  20.539 -  PIO_STACK_LOCATION stack;
  20.540 -  PCM_PARTIAL_RESOURCE_LIST prl;
  20.541 -  PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
  20.542 -  ULONG i;
  20.543 -  //char path[128];
  20.544 -  //PMDL mdl;
  20.545 - 
  20.546 -  FUNCTION_ENTER();
  20.547 -  KdPrint((__DRIVER_NAME "     %s\n", xppdd->path));
  20.548 -
  20.549 -  stack = IoGetCurrentIrpStackLocation(irp);
  20.550 -
  20.551 -  prl = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
  20.552 -  for (i = 0; i < prl->Count; i++)
  20.553 -  {
  20.554 -    prd = & prl->PartialDescriptors[i];
  20.555 -    switch (prd->Type)
  20.556 -    {
  20.557 -    case CmResourceTypeMemory:
  20.558 -      if (prd->u.Memory.Start.QuadPart == xpdd->platform_mmio_addr.QuadPart && prd->u.Memory.Length == 0)
  20.559 -      {
  20.560 -        prd->u.Memory.Start.QuadPart = MmGetMdlPfnArray(xppdd->config_page_mdl)[0] << PAGE_SHIFT;
  20.561 -        prd->u.Memory.Length = MmGetMdlByteCount(xppdd->config_page_mdl);
  20.562 -      }
  20.563 -      else if (prd->u.Memory.Start.QuadPart == xpdd->platform_mmio_addr.QuadPart + 1 && prd->u.Memory.Length == 0)
  20.564 -      {
  20.565 -        RtlZeroMemory(prd, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
  20.566 -        prd->Type = CmResourceTypeInterrupt;
  20.567 -        prd->ShareDisposition = CmResourceShareShared;
  20.568 -        prd->Flags = (xpdd->irq_mode == Latched)?CM_RESOURCE_INTERRUPT_LATCHED:CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
  20.569 -        prd->u.Interrupt.Level = 0;       // Set group and level to zero (group = upper word)
  20.570 -        prd->u.Interrupt.Level = xpdd->irq_number & 0xffff; // Only set the lower word
  20.571 -        prd->u.Interrupt.Vector = xpdd->irq_number;
  20.572 -        prd->u.Interrupt.Affinity = xpdd->irq_affinity; //KeQueryActiveProcessors();
  20.573 -        xppdd->irq_number = xpdd->irq_number;
  20.574 -      }
  20.575 -      break;
  20.576 -    }
  20.577 -  }
  20.578 -
  20.579 -  prl = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
  20.580 -  for (i = 0; i < prl->Count; i++)
  20.581 -  {
  20.582 -    prd = & prl->PartialDescriptors[i];
  20.583 -    switch (prd->Type)
  20.584 -    {
  20.585 -    case CmResourceTypeMemory:
  20.586 -      KdPrint((__DRIVER_NAME "     CmResourceTypeMemory (%d)\n", i));
  20.587 -      KdPrint((__DRIVER_NAME "     Start = %08x, Length = %d\n", prd->u.Memory.Start.LowPart, prd->u.Memory.Length));
  20.588 -      if (prd->u.Memory.Start.QuadPart == xpdd->platform_mmio_addr.QuadPart)
  20.589 -      {
  20.590 -        if (prd->u.Memory.Length == 0)
  20.591 -        {
  20.592 -          KdPrint((__DRIVER_NAME "     pfn[0] = %08x\n", (ULONG)MmGetMdlPfnArray(xppdd->config_page_mdl)[0]));
  20.593 -          prd->u.Memory.Start.QuadPart = (ULONGLONG)MmGetMdlPfnArray(xppdd->config_page_mdl)[0] << PAGE_SHIFT;
  20.594 -          prd->u.Memory.Length = MmGetMdlByteCount(xppdd->config_page_mdl);
  20.595 -          KdPrint((__DRIVER_NAME "     New Start = %08x%08x, Length = %d\n", prd->u.Memory.Start.HighPart, prd->u.Memory.Start.LowPart, prd->u.Memory.Length));
  20.596 -        }
  20.597 -        xppdd->config_page_phys = prd->u.Memory.Start;
  20.598 -        xppdd->config_page_length = prd->u.Memory.Length;
  20.599 -        xppdd->requested_resources_start = xppdd->requested_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
  20.600 -        //xppdd->assigned_resources_start = xppdd->assigned_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
  20.601 -        
  20.602 -#if 0
  20.603 -        status = XenPci_XenConfigDevice(device);
  20.604 -        if (!NT_SUCCESS(status))
  20.605 -        {
  20.606 -          RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
  20.607 -          XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackendStateHandler, device);
  20.608 -          FUNCTION_EXIT_STATUS(status);
  20.609 -          return status;
  20.610 -        }
  20.611 -#endif
  20.612 -      }
  20.613 -      else if (prd->u.Memory.Start.QuadPart == xpdd->platform_mmio_addr.QuadPart + 1 && prd->u.Memory.Length == 0)
  20.614 -      {
  20.615 -        RtlZeroMemory(prd, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
  20.616 -        prd->Type = CmResourceTypeInterrupt;
  20.617 -        prd->ShareDisposition = CmResourceShareShared;
  20.618 -        prd->Flags = (xpdd->irq_mode == Latched)?CM_RESOURCE_INTERRUPT_LATCHED:CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
  20.619 -        prd->u.Interrupt.Level = 0;       // Set group and level to zero (group = upper word)
  20.620 -        prd->u.Interrupt.Level = xpdd->irq_level & 0xffff; // Only set the lower word
  20.621 -        prd->u.Interrupt.Vector = xpdd->irq_vector;
  20.622 -        prd->u.Interrupt.Affinity = xpdd->irq_affinity; //KeQueryActiveProcessors();
  20.623 -        xppdd->irq_vector = xpdd->irq_vector;
  20.624 -        xppdd->irq_level = xpdd->irq_level;
  20.625 -      }
  20.626 -      break;
  20.627 -    }
  20.628 -  }
  20.629 -
  20.630 -  IoSkipCurrentIrpStackLocation(irp);
  20.631 -  
  20.632 -  FUNCTION_EXIT();
  20.633 -
  20.634 -  return WdfDeviceWdmDispatchPreprocessedIrp(device, irp);
  20.635 -}
  20.636 -
  20.637 -#if 0
  20.638 -static NTSTATUS
  20.639 -XenPciPdo_EvtDeviceResourcesQuery(WDFDEVICE device, WDFCMRESLIST resources)
  20.640 -{
  20.641 -}
  20.642 -#endif
  20.643 -
  20.644 -static NTSTATUS
  20.645 -XenPciPdo_EvtDeviceResourceRequirementsQuery(WDFDEVICE device, WDFIORESREQLIST requirements_list)
  20.646 -{
  20.647 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  20.648 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  20.649 -  WDFIORESLIST res_list;
  20.650 -  IO_RESOURCE_DESCRIPTOR ird;
  20.651 -
  20.652 -  //FUNCTION_ENTER();
  20.653 -  
  20.654 -  WdfIoResourceRequirementsListSetInterfaceType(requirements_list, PNPBus);
  20.655 -  
  20.656 -  WdfIoResourceListCreate(requirements_list, WDF_NO_OBJECT_ATTRIBUTES, &res_list);
  20.657 -  ird.Option = 0;
  20.658 -  ird.Type = CmResourceTypeMemory;
  20.659 -  ird.ShareDisposition = CmResourceShareShared;
  20.660 -  ird.Flags = CM_RESOURCE_MEMORY_READ_WRITE | CM_RESOURCE_MEMORY_CACHEABLE;
  20.661 -  ird.u.Memory.MinimumAddress.QuadPart = xpdd->platform_mmio_addr.QuadPart;
  20.662 -  ird.u.Memory.MaximumAddress.QuadPart = xpdd->platform_mmio_addr.QuadPart;
  20.663 -  ird.u.Memory.Length = 0;
  20.664 -  ird.u.Memory.Alignment = 1; //PAGE_SIZE;
  20.665 -  WdfIoResourceListAppendDescriptor(res_list, &ird);
  20.666 -  
  20.667 -  ird.Option = 0;
  20.668 -  ird.Type = CmResourceTypeMemory;
  20.669 -  ird.ShareDisposition = CmResourceShareShared;
  20.670 -  ird.Flags = CM_RESOURCE_MEMORY_READ_WRITE | CM_RESOURCE_MEMORY_CACHEABLE;
  20.671 -  ird.u.Memory.MinimumAddress.QuadPart = xpdd->platform_mmio_addr.QuadPart + 1;
  20.672 -  ird.u.Memory.MaximumAddress.QuadPart = xpdd->platform_mmio_addr.QuadPart + 1;
  20.673 -  ird.u.Memory.Length = 0;
  20.674 -  ird.u.Memory.Alignment = 1; //PAGE_SIZE;
  20.675 -  WdfIoResourceListAppendDescriptor(res_list, &ird);
  20.676 -  
  20.677 -  WdfIoResourceRequirementsListAppendIoResList(requirements_list, res_list);
  20.678 -
  20.679 -  //FUNCTION_EXIT();
  20.680 -  
  20.681    return STATUS_SUCCESS;
  20.682  }
  20.683  
  20.684 @@ -1054,8 +481,7 @@ XenPci_EvtDevicePnpStateChange(WDFDEVICE
  20.685  NTSTATUS
  20.686  XenPci_EvtChildListCreateDevice(WDFCHILDLIST child_list,
  20.687    PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER identification_header,
  20.688 -  PWDFDEVICE_INIT child_init)
  20.689 -{
  20.690 +  PWDFDEVICE_INIT child_init) {
  20.691    NTSTATUS status = STATUS_SUCCESS;
  20.692    WDF_OBJECT_ATTRIBUTES child_attributes;
  20.693    WDFDEVICE child_device;
  20.694 @@ -1064,10 +490,10 @@ XenPci_EvtChildListCreateDevice(WDFCHILD
  20.695    DECLARE_UNICODE_STRING_SIZE(buffer, 512);
  20.696    DECLARE_CONST_UNICODE_STRING(location, L"Xen Bus");
  20.697    PXENPCI_PDO_DEVICE_DATA xppdd;
  20.698 -  //PXENPCI_DEVICE_DATA xpdd = GetXpdd(WdfChildListGetDevice(child_list));
  20.699 -  WDF_PDO_EVENT_CALLBACKS pdo_callbacks;
  20.700 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(WdfChildListGetDevice(child_list));
  20.701 +  //WDF_PDO_EVENT_CALLBACKS pdo_callbacks;
  20.702    WDF_PNPPOWER_EVENT_CALLBACKS child_pnp_power_callbacks;
  20.703 -  UCHAR pnp_minor_functions[] = { IRP_MN_START_DEVICE };
  20.704 +  //UCHAR pnp_minor_functions[] = { IRP_MN_START_DEVICE };
  20.705    WDF_DEVICE_POWER_CAPABILITIES child_power_capabilities;
  20.706    
  20.707    FUNCTION_ENTER();
  20.708 @@ -1087,19 +513,18 @@ XenPci_EvtChildListCreateDevice(WDFCHILD
  20.709    KdPrint((__DRIVER_NAME "     device = '%s', index = '%d', path = '%s'\n",
  20.710      identification->device, identification->index, identification->path));
  20.711    
  20.712 -  status = WdfDeviceInitAssignWdmIrpPreprocessCallback(child_init, XenPciPdo_EvtDeviceWdmIrpPreprocess_START_DEVICE,
  20.713 -    IRP_MJ_PNP, pnp_minor_functions, ARRAY_SIZE(pnp_minor_functions));
  20.714 -  if (!NT_SUCCESS(status))
  20.715 -  {
  20.716 -    return status;
  20.717 -  }
  20.718 +  //status = WdfDeviceInitAssignWdmIrpPreprocessCallback(child_init, XenPciPdo_EvtDeviceWdmIrpPreprocess_START_DEVICE,
  20.719 +  //  IRP_MJ_PNP, pnp_minor_functions, ARRAY_SIZE(pnp_minor_functions));
  20.720 +  //if (!NT_SUCCESS(status)) {
  20.721 +  //  return status;
  20.722 +  //}
  20.723    
  20.724 -  WDF_PDO_EVENT_CALLBACKS_INIT(&pdo_callbacks);
  20.725 +  //WDF_PDO_EVENT_CALLBACKS_INIT(&pdo_callbacks);
  20.726    //pdo_callbacks.EvtDeviceResourcesQuery = XenPciPdo_EvtDeviceResourcesQuery;
  20.727 -  pdo_callbacks.EvtDeviceResourceRequirementsQuery = XenPciPdo_EvtDeviceResourceRequirementsQuery;
  20.728 +  //pdo_callbacks.EvtDeviceResourceRequirementsQuery = XenPciPdo_EvtDeviceResourceRequirementsQuery;
  20.729    //pdo_callbacks.EvtDeviceEject = XenPciPdo_EvtDeviceEject;
  20.730    //pdo_callbacks.EvtDeviceSetLock  = XenPciPdo_EvtDeviceSetLock;
  20.731 -  WdfPdoInitSetEventCallbacks(child_init, &pdo_callbacks);
  20.732 +  //WdfPdoInitSetEventCallbacks(child_init, &pdo_callbacks);
  20.733  
  20.734    RtlUnicodeStringPrintf(&buffer, L"xen\\%S", identification->device);
  20.735    status = WdfPdoInitAssignDeviceID(child_init, &buffer);
  20.736 @@ -1148,16 +573,10 @@ XenPci_EvtChildListCreateDevice(WDFCHILD
  20.737    
  20.738    xppdd->wdf_device = child_device;
  20.739    xppdd->wdf_device_bus_fdo = WdfChildListGetDevice(child_list);
  20.740 +  xppdd->xpdd = xpdd;
  20.741  
  20.742    xppdd->config_page_mdl = AllocateUncachedPage();
  20.743  
  20.744 -#if 0
  20.745 -  xppdd->device_state.magic = XEN_DEVICE_STATE_MAGIC;
  20.746 -  xppdd->device_state.length = sizeof(XENPCI_DEVICE_STATE);
  20.747 -  xppdd->device_state.suspend_resume_state_pdo = SR_STATE_RUNNING;
  20.748 -  xppdd->device_state.suspend_resume_state_fdo = SR_STATE_RUNNING;
  20.749 -  xppdd->device_state.pdo_event_channel = xpdd->pdo_event_channel;
  20.750 -#endif
  20.751    WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFilePaging, TRUE);
  20.752    WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileHibernation, TRUE);
  20.753    WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileDump, TRUE);
  20.754 @@ -1198,149 +617,4 @@ XenPci_EvtChildListCreateDevice(WDFCHILD
  20.755    FUNCTION_EXIT();
  20.756    
  20.757    return status;
  20.758 -}
  20.759 -
  20.760 -#if 0
  20.761 -static __forceinline VOID
  20.762 -XenPci_Pdo_ChangeSuspendState(WDFDEVICE device, ULONG new_state)
  20.763 -{
  20.764 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  20.765 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  20.766 -
  20.767 -  FUNCTION_ENTER();
  20.768 -  KdPrint((__DRIVER_NAME "     setting pdo state to %d\n", new_state));
  20.769 -  xppdd->device_state.suspend_resume_state_pdo = new_state;
  20.770 -  KeMemoryBarrier();
  20.771 -  KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xpdd->pdo_event_channel));
  20.772 -  EvtChn_Notify(xpdd, xpdd->pdo_event_channel);    
  20.773 -  while(xppdd->device_state.suspend_resume_state_fdo != xppdd->device_state.suspend_resume_state_pdo)
  20.774 -  {
  20.775 -    KdPrint((__DRIVER_NAME "     waiting...\n"));
  20.776 -    KeWaitForSingleObject(&xpdd->pdo_suspend_event, Executive, KernelMode, FALSE, NULL);
  20.777 -  }
  20.778 -  KdPrint((__DRIVER_NAME "     fdo state set to %d\n", new_state));
  20.779 -  FUNCTION_EXIT();
  20.780 -}
  20.781 -
  20.782 -/* called at PASSIVE_LEVEL */
  20.783 -NTSTATUS
  20.784 -XenPci_Pdo_Suspend(WDFDEVICE device)
  20.785 -{
  20.786 -  NTSTATUS status = STATUS_SUCCESS;
  20.787 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  20.788 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  20.789 -  char path[128];
  20.790 -  PUCHAR in_ptr;
  20.791 -  UCHAR type;
  20.792 -  PVOID setting;
  20.793 -  PVOID value;
  20.794 -  PVOID value2;
  20.795 -  int i;
  20.796 -
  20.797 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (%s)\n", xppdd->path));
  20.798 -
  20.799 -  if (xppdd->backend_state == XenbusStateConnected)
  20.800 -  {
  20.801 -    xppdd->restart_on_resume = TRUE;
  20.802 -    XenPci_Pdo_ChangeSuspendState(device, SR_STATE_SUSPENDING);
  20.803 -
  20.804 -    XenPci_ChangeFrontendState(device, XenbusStateClosing, XenbusStateClosing, 30000);
  20.805 -    XenPci_ChangeFrontendState(device, XenbusStateClosed, XenbusStateClosed, 30000);
  20.806 -    XenPci_ChangeFrontendState(device, XenbusStateInitialising, XenbusStateInitWait, 30000);
  20.807 -
  20.808 -    if (xppdd->assigned_resources_start != NULL)
  20.809 -    {
  20.810 -      in_ptr = xppdd->assigned_resources_ptr;
  20.811 -      ADD_XEN_INIT_RSP(&in_ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
  20.812 -      in_ptr = xppdd->assigned_resources_start;
  20.813 -      while((type = GET_XEN_INIT_RSP(&in_ptr, &setting, &value, &value2)) != XEN_INIT_TYPE_END)
  20.814 -      {
  20.815 -        switch (type)
  20.816 -        {
  20.817 -        case XEN_INIT_TYPE_RING: /* frontend ring */
  20.818 -          FreePages(value);
  20.819 -          break;
  20.820 -        case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
  20.821 -        case XEN_INIT_TYPE_EVENT_CHANNEL_DPC: /* frontend event channel bound to dpc */
  20.822 -        case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
  20.823 -          EvtChn_Unbind(xpdd, PtrToUlong(value));
  20.824 -          EvtChn_Close(xpdd, PtrToUlong(value));
  20.825 -          break;
  20.826 -        case XEN_INIT_TYPE_GRANT_ENTRIES:
  20.827 -          for (i = 0; i < (int)PtrToUlong(value); i++)
  20.828 -            GntTbl_EndAccess(xpdd, ((grant_ref_t *)value2)[i], FALSE, PtrToUlong(setting));
  20.829 -          break;
  20.830 -        }
  20.831 -      }
  20.832 -    }
  20.833 -
  20.834 -    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
  20.835 -    XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackendStateHandler, device);  
  20.836 -  }
  20.837 -  else
  20.838 -  {
  20.839 -    xppdd->restart_on_resume = FALSE;
  20.840 -  }
  20.841 -
  20.842 -  FUNCTION_EXIT();
  20.843 -  
  20.844 -  return status;
  20.845 -}
  20.846 -
  20.847 -NTSTATUS
  20.848 -XenPci_Pdo_Resume(WDFDEVICE device)
  20.849 -{
  20.850 -  NTSTATUS status = STATUS_SUCCESS;
  20.851 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  20.852 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  20.853 -  ULONG old_backend_state;
  20.854 -  PUCHAR src, dst;
  20.855 -
  20.856 -  FUNCTION_ENTER();
  20.857 -  KdPrint((__DRIVER_NAME "     path = %s\n", xppdd->path));
  20.858 -
  20.859 -  xppdd->device_state.pdo_event_channel = xpdd->pdo_event_channel;
  20.860 -  old_backend_state = xppdd->backend_state;
  20.861 -
  20.862 -  if (xppdd->restart_on_resume)
  20.863 -  {  
  20.864 -    status = XenPci_GetBackendDetails(device);
  20.865 -  
  20.866 -    if (XenPci_ChangeFrontendState(device, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
  20.867 -    {
  20.868 -      KdPrint((__DRIVER_NAME "     Failed to change frontend state to Initialising\n"));
  20.869 -      // this is probably an unrecoverable situation...
  20.870 -      FUNCTION_EXIT();
  20.871 -      return STATUS_UNSUCCESSFUL;
  20.872 -    }
  20.873 -    if (xppdd->assigned_resources_ptr)
  20.874 -    {
  20.875 -      // reset things - feed the 'requested resources' back in
  20.876 -      ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
  20.877 -      src = xppdd->requested_resources_start;
  20.878 -      xppdd->requested_resources_ptr = xppdd->requested_resources_start = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);;
  20.879 -      xppdd->assigned_resources_ptr = xppdd->assigned_resources_start;
  20.880 -
  20.881 -      dst = MmMapIoSpace(xppdd->config_page_phys, xppdd->config_page_length, MmNonCached);
  20.882 -
  20.883 -      status = XenPci_XenConfigDeviceSpecifyBuffers(device, src, dst);
  20.884 -
  20.885 -      MmUnmapIoSpace(dst, xppdd->config_page_length);
  20.886 -      ExFreePoolWithTag(src, XENPCI_POOL_TAG);
  20.887 -    }
  20.888 -    if (XenPci_ChangeFrontendState(device, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
  20.889 -    {
  20.890 -      // this is definitely an unrecoverable situation...
  20.891 -      KdPrint((__DRIVER_NAME "     Failed to change frontend state to connected\n"));
  20.892 -      FUNCTION_EXIT();
  20.893 -      return STATUS_UNSUCCESSFUL;
  20.894 -    }
  20.895 -    XenPci_Pdo_ChangeSuspendState(device, SR_STATE_RESUMING);
  20.896 -    XenPci_Pdo_ChangeSuspendState(device, SR_STATE_RUNNING);
  20.897 -  }
  20.898 -
  20.899 -  FUNCTION_EXIT();
  20.900 -
  20.901 -  return STATUS_SUCCESS;
  20.902 -}
  20.903 -#endif
  20.904 \ No newline at end of file
  20.905 +}
  20.906 \ No newline at end of file
    21.1 --- a/xenvbd/makefile	Sun Jan 06 14:08:22 2013 +1100
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,1 +0,0 @@
    21.4 -!INCLUDE $(NTMAKEENV)\makefile.def
    21.5 \ No newline at end of file
    22.1 --- a/xenvbd/makefile.inc	Sun Jan 06 14:08:22 2013 +1100
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,6 +0,0 @@
    22.4 -_LNG=$(LANGUAGE)
    22.5 -STAMP=stampinf -f $@ -a $(_BUILDARCH) -d * -v $(GPLPV_VERSION)
    22.6 -
    22.7 -$(OBJ_PATH)\$(O)\$(TARGETNAME).inf: $(TARGETNAME).inx sources ..\common.inc
    22.8 -    copy $(@B).inx $@
    22.9 -    $(STAMP)
    23.1 --- a/xenvbd/makefile.mingw	Sun Jan 06 14:08:22 2013 +1100
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,7 +0,0 @@
    23.4 -W32API_PATH=/home/agrover/temp/w32api-3.11
    23.5 -
    23.6 -CFLAGS = -O2 -Wall -L$(W32API_PATH)/lib/ddk -I$(W32API_PATH)/include/ddk -I../common/include -I../common/include/public -Wno-multichar -Wno-unknown-pragmas -DDBG
    23.7 -
    23.8 -xenvbd.sys: xenvbd.c scsiport.c ../mingw/mingw_extras.c
    23.9 -	i586-mingw32msvc-gcc $(CFLAGS) -o $@ -shared -Wl,--entry,_DriverEntry@8 -nostartfiles -nostdlib -lntoskrnl -lhal -lscsiport
   23.10 -
    24.1 --- a/xenvbd/sources	Sun Jan 06 14:08:22 2013 +1100
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,19 +0,0 @@
    24.4 -!INCLUDE "..\common.inc"
    24.5 -!UNDEF KMDF_VERSION
    24.6 -!UNDEF KMDF_VERSION_MAJOR
    24.7 -TARGETNAME=xenvbd
    24.8 -TARGETTYPE=DRIVER
    24.9 -!IF $(386)
   24.10 -TARGETLIBS=$(TARGETLIBS) ..\xenpci\obj$(BUILD_ALT_DIR)\i386\xenpci.lib
   24.11 -!ELSE
   24.12 -TARGETLIBS=$(TARGETLIBS) ..\xenpci\obj$(BUILD_ALT_DIR)\AMD64\xenpci.lib
   24.13 -!ENDIF
   24.14 -!IF "$(DDK_TARGET_OS)" == "Win2K" || "$(DDK_TARGET_OS)" == "WinXP" || "$(DDK_TARGET_OS)" == "WinNET"
   24.15 -TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\scsiport.lib
   24.16 -C_DEFINES=$(C_DEFINES) -D_GPLPV_SCSIPORT
   24.17 -!ELSE
   24.18 -TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\storport.lib
   24.19 -C_DEFINES=$(C_DEFINES) -D_GPLPV_STORPORT
   24.20 -!ENDIF
   24.21 -SOURCES=xenvbd.rc xenvbd.c
   24.22 -NTTARGETFILES=$(NTTARGETFILES) $(OBJ_PATH)\$(O)\$(TARGETNAME).inf
    25.1 --- a/xenvbd/xenvbd.c	Sun Jan 06 14:08:22 2013 +1100
    25.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.3 @@ -1,5 +0,0 @@
    25.4 -#ifdef _GPLPV_SCSIPORT
    25.5 -#include "xenvbd_scsiport.c"
    25.6 -#else
    25.7 -#include "xenvbd_storport.c"
    25.8 -#endif
    26.1 --- a/xenvbd/xenvbd.inx	Sun Jan 06 14:08:22 2013 +1100
    26.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.3 @@ -1,73 +0,0 @@
    26.4 -[Version]
    26.5 -Signature="$WINDOWS NT$"
    26.6 -Class=SCSIAdapter
    26.7 -ClassGuid={4D36E97B-E325-11CE-BFC1-08002BE10318}
    26.8 -Provider=%XenGplPv%
    26.9 -CatalogFile="xenvbd.cat"
   26.10 -
   26.11 -[DestinationDirs]
   26.12 -DefaultDestDir = 12
   26.13 -
   26.14 -[ControlFlags]
   26.15 -ExcludeFromSelect=*
   26.16 -
   26.17 -[Manufacturer]
   26.18 -%XenGplPv%=XenGplPv,NT$ARCH$
   26.19 -
   26.20 -[XenGplPv.NT$ARCH$]
   26.21 -%XenVbd.DRVDESC%=XenVbd_Inst, XEN\VBD
   26.22 -
   26.23 -[XenGplPv]
   26.24 -%XenVbd.DRVDESC%=XenVbd_Inst, XEN\VBD
   26.25 -
   26.26 -[XenVbd_Inst.NT]
   26.27 -CopyFiles=XenVbd.CopyFiles
   26.28 -
   26.29 -[XenVbd.CopyFiles]
   26.30 -xenvbd.sys,,0x00001000 ; COPYFLG_REPLACE_BOOT_FILE
   26.31 -
   26.32 -[XenVbd_Inst.NT.Services]
   26.33 -AddService=XenVbd,2,XenVbd_Service, XenVbd_EventLog
   26.34 -
   26.35 -[XenVbd_Service]
   26.36 -DisplayName    = %XenVbd.SVCDESC%                            
   26.37 -ServiceType    = 1
   26.38 -StartType      = 0
   26.39 -ErrorControl   = 1
   26.40 -LoadOrderGroup = System Bus Extender
   26.41 -ServiceBinary  = %12%\xenvbd.sys                            
   26.42 -AddReg = XenVbd_Service_AddReg
   26.43 -
   26.44 -[XenVbd_Service_AddReg]
   26.45 -HKR,"Parameters\PnpInterface", "15", 0x00010001, 0x00000001
   26.46 -; hide Qemu IDE in XenPCI
   26.47 -HKLM,"SYSTEM\CurrentControlSet\Services\XenPCI\Parameters", "hide_devices", 0x00010008, "#vbd#"
   26.48 -HKLM,"SYSTEM\CurrentControlSet\Services\XenPCI\Parameters", "hide_devices", 0x00010008, "VEN_8086&DEV_7010"
   26.49 -HKLM,"SYSTEM\CurrentControlSet\Services\XenPCI\Parameters", "hide_devices", 0x00010008, "primary_ide_channel"
   26.50 -HKLM,"SYSTEM\CurrentControlSet\Services\XenPCI\Parameters", "hide_devices", 0x00010008, "secondary_ide_channel"
   26.51 -HKLM,"SYSTEM\CurrentControlSet\Services\XenPCI\Parameters", "hide_devices", 0x00010008, "*pnp0600"
   26.52 -; tell Qemu to hide stuff
   26.53 -HKLM,"SYSTEM\CurrentControlSet\Services\XenPCI\Parameters", "qemu_hide_flags", 0x00010008, %QEMU_UNPLUG_ALL_IDE_DISKS%
   26.54 -
   26.55 -[XenVbd_EventLog]
   26.56 -AddReg = XenVbd_EventLog_AddReg
   26.57 -
   26.58 -[XenVbd_EventLog_AddReg]
   26.59 -HKR,,EventMessageFile,0x00020000,"%SystemRoot%\System32\IoLogMsg.dll;%SystemRoot%\System32\drivers\XenVbd.sys"
   26.60 -HKR,,TypesSupported,0x00010001,7
   26.61 -
   26.62 -[SourceDisksFiles]
   26.63 -xenvbd.sys=1
   26.64 -
   26.65 -[SourceDisksNames]
   26.66 -1 = %DISK_NAME%
   26.67 -
   26.68 -[Strings]
   26.69 -XenGplPv = "Xen GPL PV Driver Developers"
   26.70 -XenVbd.SVCDESC = "Xen Block Device Driver"
   26.71 -XenVbd.DRVDESC = "Xen Block Device Driver"
   26.72 -DISK_NAME = "Xen Block Device Driver Install Disk"
   26.73 -FLG_ADDREG_TYPE_DWORD = 0x00010001
   26.74 -QEMU_UNPLUG_ALL_IDE_DISKS = 1
   26.75 -QEMU_UNPLUG_ALL_NICS      = 2
   26.76 -QEMU_UNPLUG_AUX_IDE_DISKS = 4
    27.1 --- a/xenvbd/xenvbd.rc	Sun Jan 06 14:08:22 2013 +1100
    27.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.3 @@ -1,28 +0,0 @@
    27.4 -#include <windows.h>
    27.5 -#include <ntverp.h>
    27.6 -#include "gplpv_version.h"
    27.7 -
    27.8 -#define VER_FILETYPE                VFT_DRV
    27.9 -#define VER_FILESUBTYPE             VFT2_DRV_SYSTEM
   27.10 -#ifdef DEBUG
   27.11 -  #define VER_FILEDESCRIPTION_STR     "GPLPV XenVbd Driver"
   27.12 -#else
   27.13 -  #define VER_FILEDESCRIPTION_STR     "GPLPV XenVbd Driver (Checked Build)"
   27.14 -#endif
   27.15 -#define VER_INTERNALNAME_STR        "xenvbd.sys"
   27.16 -#define VER_ORIGINALFILENAME_STR    "xenvbd.sys"
   27.17 -
   27.18 -#undef VER_PRODUCTVERSION
   27.19 -#define VER_PRODUCTVERSION          VER_FILEVERSION
   27.20 -#undef VER_PRODUCTVERSION_STR
   27.21 -#define VER_PRODUCTVERSION_STR      VER_FILEVERSION_STR
   27.22 -#define VER_LEGALCOPYRIGHT_STR      "Copyright (C) 2009 James Harper" 
   27.23 -
   27.24 -#ifdef VER_COMPANYNAME_STR
   27.25 -#undef VER_COMPANYNAME_STR
   27.26 -#define VER_COMPANYNAME_STR         "James Harper"
   27.27 -#endif
   27.28 -#undef VER_PRODUCTNAME_STR
   27.29 -#define VER_PRODUCTNAME_STR         "PV Drivers for Windows"
   27.30 -
   27.31 -#include "common.ver"
    28.1 --- a/xenvbd/xenvbd_scsiport.c	Sun Jan 06 14:08:22 2013 +1100
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,1782 +0,0 @@
    28.4 -/*
    28.5 -PV Drivers for Windows Xen HVM Domains
    28.6 -Copyright (C) 2007 James Harper
    28.7 -
    28.8 -This program is free software; you can redistribute it and/or
    28.9 -modify it under the terms of the GNU General Public License
   28.10 -as published by the Free Software Foundation; either version 2
   28.11 -of the License, or (at your option) any later version.
   28.12 -
   28.13 -This program is distributed in the hope that it will be useful,
   28.14 -but WITHOUT ANY WARRANTY; without even the implied warranty of
   28.15 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   28.16 -GNU General Public License for more details.
   28.17 -
   28.18 -You should have received a copy of the GNU General Public License
   28.19 -along with this program; if not, write to the Free Software
   28.20 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   28.21 -*/
   28.22 -
   28.23 -#define INITGUID
   28.24 -#include "xenvbd_scsiport.h"
   28.25 -#include <io/blkif.h>
   28.26 -#include <scsi.h>
   28.27 -#include <ntddscsi.h>
   28.28 -#include <ntdddisk.h>
   28.29 -#include <stdlib.h>
   28.30 -#include <xen_public.h>
   28.31 -#include <io/xenbus.h>
   28.32 -#include <io/protocols.h>
   28.33 -
   28.34 -#pragma warning(disable: 4127)
   28.35 -
   28.36 -#if defined(__x86_64__)
   28.37 -  #define LongLongToPtr(x) (PVOID)(x)
   28.38 -#else
   28.39 -  #define LongLongToPtr(x) UlongToPtr(x)
   28.40 -#endif
   28.41 -
   28.42 -/* Not really necessary but keeps PREfast happy */
   28.43 -DRIVER_INITIALIZE DriverEntry;
   28.44 -
   28.45 -static BOOLEAN dump_mode = FALSE;
   28.46 -#define DUMP_MODE_ERROR_LIMIT 64
   28.47 -static ULONG dump_mode_errors = 0;
   28.48 -
   28.49 -CHAR scsi_device_manufacturer[8];
   28.50 -CHAR scsi_disk_model[16];
   28.51 -CHAR scsi_cdrom_model[16];
   28.52 -
   28.53 -ULONGLONG parse_numeric_string(PCHAR string)
   28.54 -{
   28.55 -  ULONGLONG val = 0;
   28.56 -  while (*string != 0)
   28.57 -  {
   28.58 -    val = val * 10 + (*string - '0');
   28.59 -    string++;
   28.60 -  }
   28.61 -  return val;
   28.62 -}
   28.63 -
   28.64 -static blkif_shadow_t *
   28.65 -get_shadow_from_freelist(PXENVBD_DEVICE_DATA xvdd)
   28.66 -{
   28.67 -  if (xvdd->shadow_free == 0)
   28.68 -  {
   28.69 -    KdPrint((__DRIVER_NAME "     No more shadow entries\n"));
   28.70 -    return NULL;
   28.71 -  }
   28.72 -  xvdd->shadow_free--;
   28.73 -  if (xvdd->shadow_free < xvdd->shadow_min_free)
   28.74 -    xvdd->shadow_min_free = xvdd->shadow_free;
   28.75 -  return &xvdd->shadows[xvdd->shadow_free_list[xvdd->shadow_free]];
   28.76 -}
   28.77 -
   28.78 -static VOID
   28.79 -put_shadow_on_freelist(PXENVBD_DEVICE_DATA xvdd, blkif_shadow_t *shadow)
   28.80 -{
   28.81 -  xvdd->shadow_free_list[xvdd->shadow_free] = (USHORT)(shadow->req.id & SHADOW_ID_ID_MASK);
   28.82 -  shadow->srb = NULL;
   28.83 -  shadow->reset = FALSE;
   28.84 -  xvdd->shadow_free++;
   28.85 -}
   28.86 -
   28.87 -static blkif_response_t *
   28.88 -XenVbd_GetResponse(PXENVBD_DEVICE_DATA xvdd, int i)
   28.89 -{
   28.90 -  blkif_other_response_t *rep;
   28.91 -  if (!xvdd->use_other)
   28.92 -    return RING_GET_RESPONSE(&xvdd->ring, i);
   28.93 -  rep = RING_GET_RESPONSE(&xvdd->other_ring, i);
   28.94 -  xvdd->tmp_rep.id = rep->id;
   28.95 -  xvdd->tmp_rep.operation = rep->operation;
   28.96 -  xvdd->tmp_rep.status = rep->status;
   28.97 -  return &xvdd->tmp_rep;
   28.98 -}
   28.99 -
  28.100 -static VOID
  28.101 -XenVbd_PutRequest(PXENVBD_DEVICE_DATA xvdd, blkif_request_t *req)
  28.102 -{
  28.103 -  blkif_other_request_t *other_req;
  28.104 -
  28.105 -  if (!xvdd->use_other)
  28.106 -  {
  28.107 -    *RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt) = *req;
  28.108 -  }
  28.109 -  else
  28.110 -  {  
  28.111 -    other_req = RING_GET_REQUEST(&xvdd->other_ring, xvdd->ring.req_prod_pvt);
  28.112 -    other_req->operation = req->operation;
  28.113 -    other_req->nr_segments = req->nr_segments;
  28.114 -    other_req->handle = req->handle;
  28.115 -    other_req->id = req->id;
  28.116 -    other_req->sector_number = req->sector_number;
  28.117 -    memcpy(other_req->seg, req->seg, sizeof(struct blkif_request_segment) * req->nr_segments);
  28.118 -  }
  28.119 -  xvdd->ring.req_prod_pvt++;
  28.120 -}
  28.121 -
  28.122 -static ULONG
  28.123 -XenVbd_InitFromConfig(PXENVBD_DEVICE_DATA xvdd)
  28.124 -{
  28.125 -  ULONG i;
  28.126 -  PUCHAR ptr;
  28.127 -  USHORT type;
  28.128 -  PCHAR setting, value, value2;
  28.129 -  ULONG qemu_protocol_version = 0;
  28.130 -  BOOLEAN qemu_hide_filter = FALSE;
  28.131 -  ULONG qemu_hide_flags_value = 0;
  28.132 -
  28.133 -  xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
  28.134 -  xvdd->sring = NULL;
  28.135 -  xvdd->event_channel = 0;
  28.136 -  
  28.137 -  xvdd->inactive = TRUE;  
  28.138 -  ptr = xvdd->device_base;
  28.139 -  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
  28.140 -  {
  28.141 -    switch(type)
  28.142 -    {
  28.143 -    case XEN_INIT_TYPE_RING: /* frontend ring */
  28.144 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
  28.145 -      if (strcmp(setting, "ring-ref") == 0)
  28.146 -      {
  28.147 -        xvdd->sring = (blkif_sring_t *)value;
  28.148 -        FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE);
  28.149 -        /* this bit is for when we have to take over an existing ring on a crash dump */
  28.150 -        xvdd->ring.req_prod_pvt = xvdd->sring->req_prod;
  28.151 -        xvdd->ring.rsp_cons = xvdd->ring.req_prod_pvt;
  28.152 -      }
  28.153 -      break;
  28.154 -    case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
  28.155 -    case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel */
  28.156 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value) & 0x3FFFFFFF));
  28.157 -      if (strcmp(setting, "event-channel") == 0)
  28.158 -      {
  28.159 -        /* cheat here - save the state of the ring in the topmost bits of the event-channel */
  28.160 -        xvdd->event_channel_ptr = (ULONG *)(((PCHAR)ptr) - sizeof(ULONG));
  28.161 -        xvdd->event_channel = PtrToUlong(value) & 0x3FFFFFFF;
  28.162 -        if (PtrToUlong(value) & 0x80000000)
  28.163 -        {
  28.164 -          xvdd->cached_use_other_valid = TRUE;
  28.165 -          xvdd->cached_use_other = (BOOLEAN)!!(PtrToUlong(value) & 0x40000000);
  28.166 -          KdPrint((__DRIVER_NAME "     cached_use_other = %d\n", xvdd->cached_use_other));
  28.167 -        }
  28.168 -        else
  28.169 -        {
  28.170 -          xvdd->cached_use_other_valid = FALSE;
  28.171 -        }
  28.172 -      }
  28.173 -      break;
  28.174 -    case XEN_INIT_TYPE_READ_STRING_BACK:
  28.175 -    case XEN_INIT_TYPE_READ_STRING_FRONT:
  28.176 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
  28.177 -      if (strcmp(setting, "sectors") == 0)
  28.178 -        xvdd->total_sectors = parse_numeric_string(value);
  28.179 -      else if (strcmp(setting, "sector-size") == 0)
  28.180 -        xvdd->bytes_per_sector = (ULONG)parse_numeric_string(value);
  28.181 -      else if (strcmp(setting, "device-type") == 0)
  28.182 -      {
  28.183 -        if (strcmp(value, "disk") == 0)
  28.184 -        {
  28.185 -          KdPrint((__DRIVER_NAME "     device-type = Disk\n"));    
  28.186 -          xvdd->device_type = XENVBD_DEVICETYPE_DISK;
  28.187 -        }
  28.188 -        else if (strcmp(value, "cdrom") == 0)
  28.189 -        {
  28.190 -          KdPrint((__DRIVER_NAME "     device-type = CDROM\n"));    
  28.191 -          xvdd->device_type = XENVBD_DEVICETYPE_CDROM;
  28.192 -        }
  28.193 -        else
  28.194 -        {
  28.195 -          KdPrint((__DRIVER_NAME "     device-type = %s (This probably won't work!)\n", value));
  28.196 -          xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
  28.197 -        }
  28.198 -      }
  28.199 -      else if (strcmp(setting, "mode") == 0)
  28.200 -      {
  28.201 -        if (strncmp(value, "r", 1) == 0)
  28.202 -        {
  28.203 -          KdPrint((__DRIVER_NAME "     mode = r\n"));    
  28.204 -          xvdd->device_mode = XENVBD_DEVICEMODE_READ;
  28.205 -        }
  28.206 -        else if (strncmp(value, "w", 1) == 0)
  28.207 -        {
  28.208 -          KdPrint((__DRIVER_NAME "     mode = w\n"));    
  28.209 -          xvdd->device_mode = XENVBD_DEVICEMODE_WRITE;
  28.210 -        }
  28.211 -        else
  28.212 -        {
  28.213 -          KdPrint((__DRIVER_NAME "     mode = unknown\n"));
  28.214 -          xvdd->device_mode = XENVBD_DEVICEMODE_UNKNOWN;
  28.215 -        }
  28.216 -      }
  28.217 -      break;
  28.218 -    case XEN_INIT_TYPE_VECTORS:
  28.219 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
  28.220 -      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
  28.221 -        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
  28.222 -      {
  28.223 -        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
  28.224 -          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
  28.225 -        KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  28.226 -        return SP_RETURN_BAD_CONFIG;
  28.227 -      }
  28.228 -      else
  28.229 -        memcpy(&xvdd->vectors, value, sizeof(XENPCI_VECTORS));
  28.230 -      break;
  28.231 -    case XEN_INIT_TYPE_STATE_PTR:
  28.232 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
  28.233 -      xvdd->device_state = (PXENPCI_DEVICE_STATE)value;
  28.234 -      break;
  28.235 -    case XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION:
  28.236 -      qemu_protocol_version = PtrToUlong(value);
  28.237 -      break;
  28.238 -    case XEN_INIT_TYPE_QEMU_HIDE_FLAGS:
  28.239 -      qemu_hide_flags_value = PtrToUlong(value);
  28.240 -      KdPrint((__DRIVER_NAME "     qemu_hide_flags_value = %d\n", qemu_hide_flags_value));
  28.241 -      break;
  28.242 -    case XEN_INIT_TYPE_QEMU_HIDE_FILTER:
  28.243 -      qemu_hide_filter = TRUE;
  28.244 -      KdPrint((__DRIVER_NAME "     qemu_hide_filter = TRUE\n"));
  28.245 -      break;
  28.246 -    default:
  28.247 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
  28.248 -      break;
  28.249 -    }
  28.250 -  }
  28.251 -  
  28.252 -  if (((qemu_hide_flags_value & QEMU_UNPLUG_ALL_IDE_DISKS) && xvdd->device_type != XENVBD_DEVICETYPE_CDROM) || qemu_hide_filter)
  28.253 -    xvdd->inactive = FALSE;
  28.254 -  
  28.255 -  if (!xvdd->inactive && (xvdd->device_type == XENVBD_DEVICETYPE_UNKNOWN
  28.256 -      || xvdd->sring == NULL
  28.257 -      || xvdd->event_channel == 0
  28.258 -      || xvdd->total_sectors == 0
  28.259 -      || xvdd->bytes_per_sector == 0))
  28.260 -  {
  28.261 -    KdPrint((__DRIVER_NAME "     Missing settings\n"));
  28.262 -    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  28.263 -    return SP_RETURN_BAD_CONFIG;
  28.264 -  }
  28.265 -
  28.266 -  if (xvdd->inactive)
  28.267 -    KdPrint((__DRIVER_NAME "     Device is inactive\n"));
  28.268 -  else
  28.269 -  {
  28.270 -    if (xvdd->device_type == XENVBD_DEVICETYPE_CDROM)
  28.271 -    {
  28.272 -      /* CD/DVD drives must have bytes_per_sector = 2048. */
  28.273 -      xvdd->bytes_per_sector = 2048;
  28.274 -    }
  28.275 -
  28.276 -    /* for some reason total_sectors is measured in 512 byte sectors always, so correct this to be in bytes_per_sectors */
  28.277 -    xvdd->total_sectors /= xvdd->bytes_per_sector / 512;
  28.278 -
  28.279 -    xvdd->shadow_free = 0;
  28.280 -    memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
  28.281 -    for (i = 0; i < SHADOW_ENTRIES; i++)
  28.282 -    {
  28.283 -      xvdd->shadows[i].req.id = i;
  28.284 -      /* make sure leftover real requests's are never confused with dump mode requests */
  28.285 -      if (dump_mode)
  28.286 -        xvdd->shadows[i].req.id |= SHADOW_ID_DUMP_FLAG;
  28.287 -      put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
  28.288 -    }
  28.289 -  }
  28.290 -  
  28.291 -  return SP_RETURN_FOUND;
  28.292 -}
  28.293 -
  28.294 -static __inline ULONG
  28.295 -decode_cdb_length(PSCSI_REQUEST_BLOCK srb)
  28.296 -{
  28.297 -  switch (srb->Cdb[0])
  28.298 -  {
  28.299 -  case SCSIOP_READ:
  28.300 -  case SCSIOP_WRITE:
  28.301 -    return ((ULONG)(UCHAR)srb->Cdb[7] << 8) | (ULONG)(UCHAR)srb->Cdb[8];
  28.302 -  case SCSIOP_READ16:
  28.303 -  case SCSIOP_WRITE16:
  28.304 -    return ((ULONG)(UCHAR)srb->Cdb[10] << 24) | ((ULONG)(UCHAR)srb->Cdb[11] << 16) | ((ULONG)(UCHAR)srb->Cdb[12] << 8) | (ULONG)(UCHAR)srb->Cdb[13];    
  28.305 -  default:
  28.306 -    return 0;
  28.307 -  }
  28.308 -}
  28.309 -
  28.310 -static __inline ULONGLONG
  28.311 -decode_cdb_sector(PSCSI_REQUEST_BLOCK srb)
  28.312 -{
  28.313 -  ULONGLONG sector;
  28.314 -  
  28.315 -  switch (srb->Cdb[0])
  28.316 -  {
  28.317 -  case SCSIOP_READ:
  28.318 -  case SCSIOP_WRITE:
  28.319 -    sector = ((ULONG)(UCHAR)srb->Cdb[2] << 24) | ((ULONG)(UCHAR)srb->Cdb[3] << 16) | ((ULONG)(UCHAR)srb->Cdb[4] << 8) | (ULONG)(UCHAR)srb->Cdb[5];
  28.320 -    break;
  28.321 -  case SCSIOP_READ16:
  28.322 -  case SCSIOP_WRITE16:
  28.323 -    sector = ((ULONGLONG)(UCHAR)srb->Cdb[2] << 56) | ((ULONGLONG)(UCHAR)srb->Cdb[3] << 48)
  28.324 -           | ((ULONGLONG)(UCHAR)srb->Cdb[4] << 40) | ((ULONGLONG)(UCHAR)srb->Cdb[5] << 32)
  28.325 -           | ((ULONGLONG)(UCHAR)srb->Cdb[6] << 24) | ((ULONGLONG)(UCHAR)srb->Cdb[7] << 16)
  28.326 -           | ((ULONGLONG)(UCHAR)srb->Cdb[8] << 8) | ((ULONGLONG)(UCHAR)srb->Cdb[9]);
  28.327 -    //KdPrint((__DRIVER_NAME "     sector_number = %d (high) %d (low)\n", (ULONG)(sector >> 32), (ULONG)sector));
  28.328 -    break;
  28.329 -  default:
  28.330 -    sector = 0;
  28.331 -    break;
  28.332 -  }
  28.333 -  return sector;
  28.334 -}
  28.335 -
  28.336 -static __inline BOOLEAN
  28.337 -decode_cdb_is_read(PSCSI_REQUEST_BLOCK srb)
  28.338 -{
  28.339 -  switch (srb->Cdb[0])
  28.340 -  {
  28.341 -  case SCSIOP_READ:
  28.342 -  case SCSIOP_READ16:
  28.343 -    return TRUE;
  28.344 -  case SCSIOP_WRITE:
  28.345 -  case SCSIOP_WRITE16:
  28.346 -    return FALSE;
  28.347 -  default:
  28.348 -    return FALSE;
  28.349 -  }
  28.350 -}
  28.351 -
  28.352 -static VOID
  28.353 -XenVbd_PutSrbOnList(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
  28.354 -{
  28.355 -  srb_list_entry_t *list_entry = srb->SrbExtension;
  28.356 -  list_entry->srb = srb;
  28.357 -  InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)list_entry);
  28.358 -}
  28.359 -
  28.360 -static VOID
  28.361 -XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVICE_DATA xvdd)
  28.362 -{
  28.363 -  PSCSI_REQUEST_BLOCK srb;
  28.364 -  srb_list_entry_t *srb_entry;
  28.365 -  ULONGLONG sector_number;
  28.366 -  ULONG block_count;
  28.367 -  blkif_shadow_t *shadow;
  28.368 -  ULONG remaining, offset, length;
  28.369 -  grant_ref_t gref;
  28.370 -  PUCHAR ptr;
  28.371 -  int notify;
  28.372 -  int i;
  28.373 -  #if DBG && NTDDI_VERSION >= NTDDI_WINXP
  28.374 -  LARGE_INTEGER current_time;
  28.375 -  #endif
  28.376 -
  28.377 -  //FUNCTION_ENTER();
  28.378 -
  28.379 -  #if DBG && NTDDI_VERSION >= NTDDI_WINXP
  28.380 -  ScsiPortQuerySystemTime(&current_time);
  28.381 -  #endif
  28.382 -  
  28.383 -  while ((!dump_mode || xvdd->shadow_free == SHADOW_ENTRIES)
  28.384 -        && xvdd->ring_detect_state == RING_DETECT_STATE_COMPLETE
  28.385 -        && !xvdd->aligned_buffer_in_use
  28.386 -        && xvdd->shadow_free
  28.387 -        && (srb_entry = (srb_list_entry_t *)RemoveHeadList(&xvdd->srb_list)) != (srb_list_entry_t *)&xvdd->srb_list) /* RemoveHeadList must be last in the expression */
  28.388 -  {
  28.389 -    srb = srb_entry->srb;
  28.390 -    block_count = decode_cdb_length(srb);;
  28.391 -    block_count *= xvdd->bytes_per_sector / 512;
  28.392 -    sector_number = decode_cdb_sector(srb);
  28.393 -    sector_number *= xvdd->bytes_per_sector / 512;
  28.394 -    
  28.395 -    /* look for pending writes that overlap this one */
  28.396 -    /* we get warnings from drbd if we don't */
  28.397 -    for (i = 0; i < MAX_SHADOW_ENTRIES; i++)
  28.398 -    {
  28.399 -      PSCSI_REQUEST_BLOCK srb2;
  28.400 -      ULONGLONG sector_number2;
  28.401 -      ULONG block_count2;
  28.402 -      
  28.403 -      srb2 = xvdd->shadows[i].srb;
  28.404 -      if (!srb2)
  28.405 -        continue;
  28.406 -      if (decode_cdb_is_read(srb2))
  28.407 -        continue;
  28.408 -      block_count2 = decode_cdb_length(srb2);;
  28.409 -      block_count2 *= xvdd->bytes_per_sector / 512;
  28.410 -      sector_number2 = decode_cdb_sector(srb2);
  28.411 -      sector_number2 *= xvdd->bytes_per_sector / 512;
  28.412 -      
  28.413 -      if (sector_number < sector_number2 && sector_number + block_count <= sector_number2)
  28.414 -        continue;
  28.415 -      if (sector_number2 < sector_number && sector_number2 + block_count2 <= sector_number)
  28.416 -        continue;
  28.417 -
  28.418 -#if 0
  28.419 -      /* check if the data being written is identical to the data in the pipe */
  28.420 -      {
  28.421 -        PUCHAR buf, buf2;
  28.422 -        ULONG byte_count;
  28.423 -        int j;
  28.424 -
  28.425 -        buf = (PUCHAR)srb->DataBuffer + (max(sector_number, sector_number2) - sector_number) * xvdd->bytes_per_sector;
  28.426 -        buf2 = (PUCHAR)srb2->DataBuffer + (max(sector_number, sector_number2) - sector_number2) * xvdd->bytes_per_sector;
  28.427 -        byte_count = (ULONG)(min(sector_number + block_count, sector_number2 + block_count2) - max(sector_number, sector_number2)) * xvdd->bytes_per_sector;
  28.428 -        for (j = 0; j < (int)byte_count; j++)
  28.429 -        {
  28.430 -          if (buf[j] != buf2[j])
  28.431 -            break;
  28.432 -        }
  28.433 -      }
  28.434 -#endif
  28.435 -
  28.436 -      KdPrint((__DRIVER_NAME "     Concurrent outstanding write detected (%I64d, %d) (%I64d, %d)\n",
  28.437 -        sector_number, block_count, sector_number2, block_count2));
  28.438 -      /* put the srb back at the start of the queue */
  28.439 -      InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
  28.440 -      break;
  28.441 -    }
  28.442 -    if (i < MAX_SHADOW_ENTRIES)
  28.443 -      break; /* stall the queue but fall through so the notify is triggered */    
  28.444 -
  28.445 -    remaining = block_count * 512;
  28.446 -    shadow = get_shadow_from_freelist(xvdd);
  28.447 -    ASSERT(shadow);
  28.448 -    ASSERT(!shadow->aligned_buffer_in_use);
  28.449 -    ASSERT(!shadow->srb);
  28.450 -    shadow->reset = FALSE;
  28.451 -    shadow->req.sector_number = sector_number;
  28.452 -    shadow->req.handle = 0;
  28.453 -    shadow->req.operation = decode_cdb_is_read(srb)?BLKIF_OP_READ:BLKIF_OP_WRITE;
  28.454 -    shadow->req.nr_segments = 0;
  28.455 -    shadow->srb = srb;
  28.456 -
  28.457 -    if ((ULONG_PTR)srb->DataBuffer & 511)
  28.458 -    {
  28.459 -      if (dump_mode)
  28.460 -        KdPrint((__DRIVER_NAME "     unaligned dump mode buffer = %d bytes\n", block_count * 512));
  28.461 -      ASSERT(!dump_mode || block_count * 512 < BLKIF_MAX_SEGMENTS_PER_REQUEST_DUMP_MODE * PAGE_SIZE);
  28.462 -      xvdd->aligned_buffer_in_use = TRUE;
  28.463 -      ptr = xvdd->aligned_buffer;
  28.464 -      if (!decode_cdb_is_read(srb))
  28.465 -        memcpy(ptr, srb->DataBuffer, block_count * 512);
  28.466 -      shadow->aligned_buffer_in_use = TRUE;
  28.467 -    }
  28.468 -    else
  28.469 -    {
  28.470 -      ptr = srb->DataBuffer;
  28.471 -      shadow->aligned_buffer_in_use = FALSE;
  28.472 -    }
  28.473 -
  28.474 -    //KdPrint((__DRIVER_NAME "     sector_number = %d, block_count = %d\n", (ULONG)shadow->req.sector_number, block_count));
  28.475 -    //KdPrint((__DRIVER_NAME "     SrbExtension = %p\n", srb->SrbExtension));
  28.476 -    //KdPrint((__DRIVER_NAME "     DataBuffer   = %p\n", srb->DataBuffer));
  28.477 -
  28.478 -    //KdPrint((__DRIVER_NAME "     sector_number = %d\n", (ULONG)shadow->req.sector_number));
  28.479 -    //KdPrint((__DRIVER_NAME "     handle = %d\n", shadow->req.handle));
  28.480 -    //KdPrint((__DRIVER_NAME "     operation = %d\n", shadow->req.operation));
  28.481 -    
  28.482 -    while (remaining > 0)
  28.483 -    {
  28.484 -      PHYSICAL_ADDRESS physical_address = MmGetPhysicalAddress(ptr);
  28.485 -      
  28.486 -      gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context,
  28.487 -               (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, (ULONG)'SCSI');
  28.488 -      if (gref == INVALID_GRANT_REF)
  28.489 -      {
  28.490 -        ULONG i;
  28.491 -        for (i = 0; i < shadow->req.nr_segments; i++)
  28.492 -        {
  28.493 -          xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
  28.494 -            shadow->req.seg[i].gref, FALSE, (ULONG)'SCSI');
  28.495 -        }
  28.496 -        if (shadow->aligned_buffer_in_use)
  28.497 -        {
  28.498 -          shadow->aligned_buffer_in_use = FALSE;
  28.499 -          xvdd->aligned_buffer_in_use = FALSE;
  28.500 -        }
  28.501 -        /* put the srb back at the start of the queue, then fall through so that the notify is triggered*/
  28.502 -        InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
  28.503 -        put_shadow_on_freelist(xvdd, shadow);
  28.504 -        KdPrint((__DRIVER_NAME "     Out of gref's. Deferring\n"));
  28.505 -        break;
  28.506 -      }
  28.507 -      offset = physical_address.LowPart & (PAGE_SIZE - 1);
  28.508 -      length = min(PAGE_SIZE - offset, remaining);
  28.509 -      ASSERT((offset & 511) == 0);
  28.510 -      ASSERT((length & 511) == 0);
  28.511 -      ASSERT(offset + length <= PAGE_SIZE);
  28.512 -      shadow->req.seg[shadow->req.nr_segments].gref = gref;
  28.513 -      shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset >> 9);
  28.514 -      shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) >> 9) - 1);
  28.515 -      remaining -= length;
  28.516 -      ptr += length;
  28.517 -      shadow->req.nr_segments++;
  28.518 -    }
  28.519 -
  28.520 -    //KdPrint((__DRIVER_NAME "     nr_segments = %d\n", shadow->req.nr_segments));
  28.521 -
  28.522 -    XenVbd_PutRequest(xvdd, &shadow->req);
  28.523 -    #if DBG && NTDDI_VERSION >= NTDDI_WINXP
  28.524 -    shadow->ring_submit_time = current_time;
  28.525 -    #endif
  28.526 -
  28.527 -    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
  28.528 -    if (notify)
  28.529 -    {
  28.530 -      //KdPrint((__DRIVER_NAME "     Notifying\n"));
  28.531 -      xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
  28.532 -    }
  28.533 -  }
  28.534 -  if (xvdd->shadow_free && !xvdd->aligned_buffer_in_use)
  28.535 -  {
  28.536 -    ScsiPortNotification(NextLuRequest, xvdd, 0, 0, 0);
  28.537 -  }
  28.538 -  //FUNCTION_EXIT();
  28.539 -}
  28.540 -
  28.541 -static ULONG
  28.542 -XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
  28.543 -{
  28.544 -//  PACCESS_RANGE AccessRange;
  28.545 -  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
  28.546 -  ULONG status;
  28.547 -//  PXENPCI_XEN_DEVICE_DATA XenDeviceData;
  28.548 -  PACCESS_RANGE access_range;
  28.549 -
  28.550 -  UNREFERENCED_PARAMETER(HwContext);
  28.551 -  UNREFERENCED_PARAMETER(BusInformation);
  28.552 -  UNREFERENCED_PARAMETER(ArgumentString);
  28.553 -
  28.554 -  FUNCTION_ENTER(); 
  28.555 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  28.556 -  KdPrint((__DRIVER_NAME "     xvdd = %p\n", xvdd));
  28.557 -
  28.558 -  RtlZeroMemory(xvdd, sizeof(XENVBD_DEVICE_DATA));
  28.559 -  *Again = FALSE;
  28.560 -
  28.561 -  KdPrint((__DRIVER_NAME "     BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
  28.562 -  KdPrint((__DRIVER_NAME "     BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector));
  28.563 -
  28.564 -  KdPrint((__DRIVER_NAME "     NumberOfAccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));    
  28.565 -  if (ConfigInfo->NumberOfAccessRanges != 1 && ConfigInfo->NumberOfAccessRanges != 2)
  28.566 -  {
  28.567 -    return SP_RETURN_BAD_CONFIG;
  28.568 -  }
  28.569 -
  28.570 -  access_range = &((*(ConfigInfo->AccessRanges))[0]);
  28.571 -  KdPrint((__DRIVER_NAME "     RangeStart = %08x, RangeLength = %08x\n",
  28.572 -    access_range->RangeStart.LowPart, access_range->RangeLength));
  28.573 -  xvdd->device_base = ScsiPortGetDeviceBase(
  28.574 -    DeviceExtension,
  28.575 -    ConfigInfo->AdapterInterfaceType,
  28.576 -    ConfigInfo->SystemIoBusNumber,
  28.577 -    access_range->RangeStart,
  28.578 -    access_range->RangeLength,
  28.579 -    !access_range->RangeInMemory);
  28.580 -  if (!xvdd->device_base)
  28.581 -  {
  28.582 -    FUNCTION_MSG("ScsiPortGetDeviceBase failed\n");
  28.583 -    FUNCTION_EXIT(); 
  28.584 -    return SP_RETURN_BAD_CONFIG;
  28.585 -  }
  28.586 -  
  28.587 -  status = XenVbd_InitFromConfig(xvdd);
  28.588 -  if (status != SP_RETURN_FOUND)
  28.589 -  {
  28.590 -    FUNCTION_EXIT();
  28.591 -    return status;
  28.592 -  }
  28.593 -
  28.594 -  xvdd->aligned_buffer_in_use = FALSE;
  28.595 -  /* align the buffer to PAGE_SIZE */
  28.596 -  xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
  28.597 -  KdPrint((__DRIVER_NAME "     aligned_buffer_data = %p\n", xvdd->aligned_buffer_data));
  28.598 -  KdPrint((__DRIVER_NAME "     aligned_buffer = %p\n", xvdd->aligned_buffer));
  28.599 -
  28.600 -  if (!dump_mode)
  28.601 -  {
  28.602 -    ConfigInfo->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
  28.603 -    ConfigInfo->NumberOfPhysicalBreaks = BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
  28.604 -    //ConfigInfo->ScatterGather = TRUE;
  28.605 -  }
  28.606 -  else
  28.607 -  {
  28.608 -    ConfigInfo->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST_DUMP_MODE * PAGE_SIZE;
  28.609 -    ConfigInfo->NumberOfPhysicalBreaks = BLKIF_MAX_SEGMENTS_PER_REQUEST_DUMP_MODE - 1;
  28.610 -    //ConfigInfo->ScatterGather = FALSE;
  28.611 -  }
  28.612 -  KdPrint((__DRIVER_NAME "     ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength));
  28.613 -  KdPrint((__DRIVER_NAME "     ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks));
  28.614 -  ConfigInfo->ScatterGather = FALSE;
  28.615 -  ConfigInfo->AlignmentMask = 0;
  28.616 -  ConfigInfo->NumberOfBuses = 1;
  28.617 -  ConfigInfo->InitiatorBusId[0] = 1;
  28.618 -  ConfigInfo->MaximumNumberOfLogicalUnits = 1;
  28.619 -  ConfigInfo->MaximumNumberOfTargets = 2;
  28.620 -  KdPrint((__DRIVER_NAME "     ConfigInfo->CachesData was initialised to %d\n", ConfigInfo->CachesData));
  28.621 -  ConfigInfo->CachesData = FALSE;
  28.622 -  ConfigInfo->BufferAccessScsiPortControlled = FALSE;
  28.623 -
  28.624 -  if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
  28.625 -  {
  28.626 -    ConfigInfo->Master = TRUE;
  28.627 -    ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
  28.628 -    ConfigInfo->Dma32BitAddresses = FALSE;
  28.629 -    KdPrint((__DRIVER_NAME "     Dma64BitAddresses supported\n"));
  28.630 -  }
  28.631 -  else
  28.632 -  {
  28.633 -    ConfigInfo->Master = FALSE;
  28.634 -    ConfigInfo->Dma32BitAddresses = TRUE;
  28.635 -    KdPrint((__DRIVER_NAME "     Dma64BitAddresses not supported\n"));
  28.636 -  }
  28.637 -
  28.638 -  FUNCTION_EXIT();
  28.639 -
  28.640 -  return SP_RETURN_FOUND;
  28.641 -}
  28.642 -
  28.643 -static VOID
  28.644 -XenVbd_StartRingDetection(PXENVBD_DEVICE_DATA xvdd)
  28.645 -{
  28.646 -  blkif_request_t *req;
  28.647 -  int notify;
  28.648 -
  28.649 -  xvdd->ring_detect_state = RING_DETECT_STATE_DETECT1;
  28.650 -  RtlZeroMemory(xvdd->sring->ring, PAGE_SIZE - FIELD_OFFSET(blkif_sring_t, ring));
  28.651 -  req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
  28.652 -  req->operation = 0xff;
  28.653 -  xvdd->ring.req_prod_pvt++;
  28.654 -  req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
  28.655 -  req->operation = 0xff;
  28.656 -  xvdd->ring.req_prod_pvt++;
  28.657 -
  28.658 -  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
  28.659 -  if (notify)
  28.660 -    xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
  28.661 -}
  28.662 -
  28.663 -static BOOLEAN
  28.664 -XenVbd_HwScsiInitialize(PVOID DeviceExtension)
  28.665 -{
  28.666 -  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
  28.667 -  
  28.668 -  FUNCTION_ENTER();
  28.669 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  28.670 -  KdPrint((__DRIVER_NAME "     dump_mode = %d\n", dump_mode));
  28.671 -
  28.672 -  if (!xvdd->inactive)
  28.673 -  {
  28.674 -    xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED;
  28.675 -    if (xvdd->cached_use_other_valid)
  28.676 -    {
  28.677 -      if (xvdd->cached_use_other)
  28.678 -      {
  28.679 -        xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
  28.680 -        xvdd->use_other = TRUE;
  28.681 -      }
  28.682 -      xvdd->ring_detect_state = RING_DETECT_STATE_COMPLETE;
  28.683 -    }
  28.684 -    InitializeListHead(&xvdd->srb_list);
  28.685 -  }
  28.686 -  FUNCTION_EXIT();
  28.687 -
  28.688 -  return TRUE;
  28.689 -}
  28.690 -
  28.691 -static ULONG
  28.692 -XenVbd_FillModePage(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
  28.693 -{
  28.694 -  PMODE_PARAMETER_HEADER parameter_header = NULL;
  28.695 -  PMODE_PARAMETER_HEADER10 parameter_header10 = NULL;
  28.696 -  PMODE_PARAMETER_BLOCK param_block;
  28.697 -  PMODE_FORMAT_PAGE format_page;
  28.698 -  ULONG offset = 0;
  28.699 -  UCHAR buffer[1024];
  28.700 -  BOOLEAN valid_page = FALSE;
  28.701 -  BOOLEAN cdb_llbaa;
  28.702 -  BOOLEAN cdb_dbd;
  28.703 -  UCHAR cdb_page_code;
  28.704 -  USHORT cdb_allocation_length;
  28.705 -
  28.706 -  UNREFERENCED_PARAMETER(xvdd);
  28.707 -
  28.708 -  RtlZeroMemory(srb->DataBuffer, srb->DataTransferLength);
  28.709 -  RtlZeroMemory(buffer, ARRAY_SIZE(buffer));
  28.710 -  offset = 0;
  28.711 -
  28.712 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  28.713 -  
  28.714 -  switch (srb->Cdb[0])
  28.715 -  {
  28.716 -  case SCSIOP_MODE_SENSE:
  28.717 -    cdb_llbaa = FALSE;
  28.718 -    cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
  28.719 -    cdb_page_code = srb->Cdb[2] & 0x3f;
  28.720 -    cdb_allocation_length = srb->Cdb[4];
  28.721 -    KdPrint((__DRIVER_NAME "     SCSIOP_MODE_SENSE llbaa = %d, dbd = %d, page_code = %d, allocation_length = %d\n",
  28.722 -      cdb_llbaa, cdb_dbd, cdb_page_code, cdb_allocation_length));
  28.723 -    parameter_header = (PMODE_PARAMETER_HEADER)&buffer[offset];
  28.724 -    parameter_header->MediumType = 0;
  28.725 -    parameter_header->DeviceSpecificParameter = 0;
  28.726 -    if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
  28.727 -    {
  28.728 -      KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
  28.729 -      parameter_header->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT; 
  28.730 -    }
  28.731 -    offset += sizeof(MODE_PARAMETER_HEADER);
  28.732 -    break;
  28.733 -  case SCSIOP_MODE_SENSE10:
  28.734 -    cdb_llbaa = (BOOLEAN)!!(srb->Cdb[1] & 16);
  28.735 -    cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
  28.736 -    cdb_page_code = srb->Cdb[2] & 0x3f;
  28.737 -    cdb_allocation_length = (srb->Cdb[7] << 8) | srb->Cdb[8];
  28.738 -    KdPrint((__DRIVER_NAME "     SCSIOP_MODE_SENSE10 llbaa = %d, dbd = %d, page_code = %d, allocation_length = %d\n",
  28.739 -      cdb_llbaa, cdb_dbd, cdb_page_code, cdb_allocation_length));
  28.740 -    parameter_header10 = (PMODE_PARAMETER_HEADER10)&buffer[offset];
  28.741 -    parameter_header10->MediumType = 0;
  28.742 -    parameter_header10->DeviceSpecificParameter = 0;
  28.743 -    if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
  28.744 -    {
  28.745 -      KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
  28.746 -      parameter_header10->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT; 
  28.747 -    }
  28.748 -    offset += sizeof(MODE_PARAMETER_HEADER10);
  28.749 -    break;
  28.750 -  default:
  28.751 -    KdPrint((__DRIVER_NAME "     SCSIOP_MODE_SENSE_WTF (%02x)\n", (ULONG)srb->Cdb[0]));
  28.752 -    return FALSE;
  28.753 -  }  
  28.754 -  
  28.755 -  if (!cdb_dbd)
  28.756 -  {
  28.757 -    param_block = (PMODE_PARAMETER_BLOCK)&buffer[offset];
  28.758 -    if (xvdd->device_type == XENVBD_DEVICETYPE_DISK)
  28.759 -    {
  28.760 -      if (xvdd->total_sectors >> 32) 
  28.761 -      {
  28.762 -        param_block->DensityCode = 0xff;
  28.763 -        param_block->NumberOfBlocks[0] = 0xff;
  28.764 -        param_block->NumberOfBlocks[1] = 0xff;
  28.765 -        param_block->NumberOfBlocks[2] = 0xff;
  28.766 -      }
  28.767 -      else
  28.768 -      {
  28.769 -        param_block->DensityCode = (UCHAR)((xvdd->total_sectors >> 24) & 0xff);
  28.770 -        param_block->NumberOfBlocks[0] = (UCHAR)((xvdd->total_sectors >> 16) & 0xff);
  28.771 -        param_block->NumberOfBlocks[1] = (UCHAR)((xvdd->total_sectors >> 8) & 0xff);
  28.772 -        param_block->NumberOfBlocks[2] = (UCHAR)((xvdd->total_sectors >> 0) & 0xff);
  28.773 -      }
  28.774 -      param_block->BlockLength[0] = (UCHAR)((xvdd->bytes_per_sector >> 16) & 0xff);
  28.775 -      param_block->BlockLength[1] = (UCHAR)((xvdd->bytes_per_sector >> 8) & 0xff);
  28.776 -      param_block->BlockLength[2] = (UCHAR)((xvdd->bytes_per_sector >> 0) & 0xff);
  28.777 -    }
  28.778 -    offset += sizeof(MODE_PARAMETER_BLOCK);
  28.779 -  }
  28.780 -  switch (srb->Cdb[0])
  28.781 -  {
  28.782 -  case SCSIOP_MODE_SENSE:
  28.783 -    parameter_header->BlockDescriptorLength = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER));
  28.784 -    break;
  28.785 -  case SCSIOP_MODE_SENSE10:
  28.786 -    parameter_header10->BlockDescriptorLength[0] = (UCHAR)((offset - sizeof(MODE_PARAMETER_HEADER10)) >> 8);
  28.787 -    parameter_header10->BlockDescriptorLength[1] = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER10));
  28.788 -    break;
  28.789 -  }
  28.790 -  if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_FORMAT_DEVICE || cdb_page_code == MODE_SENSE_RETURN_ALL))
  28.791 -  {
  28.792 -    valid_page = TRUE;
  28.793 -    format_page = (PMODE_FORMAT_PAGE)&buffer[offset];
  28.794 -    format_page->PageCode = MODE_PAGE_FORMAT_DEVICE;
  28.795 -    format_page->PageLength = sizeof(MODE_FORMAT_PAGE) - FIELD_OFFSET(MODE_FORMAT_PAGE, PageLength);
  28.796 -    /* 256 sectors per track */
  28.797 -    format_page->SectorsPerTrack[0] = 0x01;
  28.798 -    format_page->SectorsPerTrack[1] = 0x00;
  28.799 -    /* xxx bytes per sector */
  28.800 -    format_page->BytesPerPhysicalSector[0] = (UCHAR)(xvdd->bytes_per_sector >> 8);
  28.801 -    format_page->BytesPerPhysicalSector[1] = (UCHAR)(xvdd->bytes_per_sector & 0xff);
  28.802 -    format_page->HardSectorFormating = TRUE;
  28.803 -    format_page->SoftSectorFormating = TRUE;
  28.804 -    offset += sizeof(MODE_FORMAT_PAGE);
  28.805 -  }
  28.806 -  if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_CACHING || cdb_page_code == MODE_SENSE_RETURN_ALL))
  28.807 -  {
  28.808 -    PMODE_CACHING_PAGE caching_page;
  28.809 -    valid_page = TRUE;
  28.810 -    caching_page = (PMODE_CACHING_PAGE)&buffer[offset];
  28.811 -    caching_page->PageCode = MODE_PAGE_CACHING;
  28.812 -    caching_page->PageLength = sizeof(MODE_CACHING_PAGE) - FIELD_OFFSET(MODE_CACHING_PAGE, PageLength);
  28.813 -    // caching_page-> // all zeros is just fine... maybe
  28.814 -    offset += sizeof(MODE_CACHING_PAGE);
  28.815 -  }
  28.816 -  if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_MEDIUM_TYPES || cdb_page_code == MODE_SENSE_RETURN_ALL))
  28.817 -  {
  28.818 -    PUCHAR medium_types_page;
  28.819 -    valid_page = TRUE;
  28.820 -    medium_types_page = &buffer[offset];
  28.821 -    medium_types_page[0] = MODE_PAGE_MEDIUM_TYPES;
  28.822 -    medium_types_page[1] = 0x06;
  28.823 -    medium_types_page[2] = 0;
  28.824 -    medium_types_page[3] = 0;
  28.825 -    medium_types_page[4] = 0;
  28.826 -    medium_types_page[5] = 0;
  28.827 -    medium_types_page[6] = 0;
  28.828 -    medium_types_page[7] = 0;
  28.829 -    offset += 8;
  28.830 -  }
  28.831 -  switch (srb->Cdb[0])
  28.832 -  {
  28.833 -  case SCSIOP_MODE_SENSE:
  28.834 -    parameter_header->ModeDataLength = (UCHAR)(offset - 1);
  28.835 -    break;
  28.836 -  case SCSIOP_MODE_SENSE10:
  28.837 -    parameter_header10->ModeDataLength[0] = (UCHAR)((offset - 2) >> 8);
  28.838 -    parameter_header10->ModeDataLength[1] = (UCHAR)(offset - 2);
  28.839 -    break;
  28.840 -  }
  28.841 -
  28.842 -  if (!valid_page && cdb_page_code != MODE_SENSE_RETURN_ALL)
  28.843 -  {
  28.844 -    srb->SrbStatus = SRB_STATUS_ERROR;
  28.845 -  }
  28.846 -  else if(offset < srb->DataTransferLength)
  28.847 -    srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
  28.848 -  else
  28.849 -    srb->SrbStatus = SRB_STATUS_SUCCESS;
  28.850 -  srb->DataTransferLength = min(srb->DataTransferLength, offset);
  28.851 -  srb->ScsiStatus = 0;
  28.852 -  memcpy(srb->DataBuffer, buffer, srb->DataTransferLength);
  28.853 -  
  28.854 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  28.855 -
  28.856 -  return TRUE;
  28.857 -}
  28.858 -
  28.859 -static VOID
  28.860 -XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, UCHAR sense_key, UCHAR additional_sense_code)
  28.861 -{
  28.862 -  PSENSE_DATA sd = srb->SenseInfoBuffer;
  28.863 - 
  28.864 -  UNREFERENCED_PARAMETER(xvdd);
  28.865 -  
  28.866 -  if (!srb->SenseInfoBuffer)
  28.867 -    return;
  28.868 -  
  28.869 -  sd->ErrorCode = 0x70;
  28.870 -  sd->Valid = 1;
  28.871 -  sd->SenseKey = sense_key;
  28.872 -  sd->AdditionalSenseLength = sizeof(SENSE_DATA) - FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
  28.873 -  sd->AdditionalSenseCode = additional_sense_code;
  28.874 -  return;
  28.875 -}
  28.876 -
  28.877 -static VOID
  28.878 -XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
  28.879 -{
  28.880 -  if (srb->SrbStatus == SRB_STATUS_SUCCESS || srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)
  28.881 -    return;
  28.882 -  XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
  28.883 -  srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
  28.884 -}
  28.885 -
  28.886 -static BOOLEAN
  28.887 -XenVbd_HwScsiInterrupt(PVOID DeviceExtension)
  28.888 -{
  28.889 -  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
  28.890 -  PSCSI_REQUEST_BLOCK srb;
  28.891 -  RING_IDX i, rp;
  28.892 -  ULONG j;
  28.893 -  blkif_response_t *rep;
  28.894 -  int block_count;
  28.895 -  int more_to_do = TRUE;
  28.896 -  blkif_shadow_t *shadow;
  28.897 -  ULONG suspend_resume_state_pdo;
  28.898 -  BOOLEAN last_interrupt = FALSE;
  28.899 -  ULONG start_ring_detect_state = xvdd->ring_detect_state;
  28.900 -  #if DBG && NTDDI_VERSION >= NTDDI_WINXP
  28.901 -  srb_list_entry_t *srb_entry;
  28.902 -  ULONG elapsed;
  28.903 -  LARGE_INTEGER current_time;
  28.904 -  #endif
  28.905 -
  28.906 -  /* in dump mode I think we get called on a timer, not by an actual IRQ */
  28.907 -  if (!dump_mode && !xvdd->vectors.EvtChn_AckEvent(xvdd->vectors.context, xvdd->event_channel, &last_interrupt))
  28.908 -    return FALSE; /* interrupt was not for us */
  28.909 -
  28.910 -  suspend_resume_state_pdo = xvdd->device_state->suspend_resume_state_pdo;
  28.911 -  KeMemoryBarrier();
  28.912 -
  28.913 -  if (suspend_resume_state_pdo != xvdd->device_state->suspend_resume_state_fdo)
  28.914 -  {
  28.915 -    FUNCTION_ENTER();
  28.916 -    switch (suspend_resume_state_pdo)
  28.917 -    {
  28.918 -      case SR_STATE_SUSPENDING:
  28.919 -        KdPrint((__DRIVER_NAME "     New pdo state SR_STATE_SUSPENDING\n"));
  28.920 -        break;
  28.921 -      case SR_STATE_RESUMING:
  28.922 -        KdPrint((__DRIVER_NAME "     New pdo state SR_STATE_RESUMING\n"));
  28.923 -        XenVbd_InitFromConfig(xvdd);
  28.924 -        xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
  28.925 -        xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
  28.926 -        break;
  28.927 -      case SR_STATE_RUNNING:
  28.928 -        KdPrint((__DRIVER_NAME "     New pdo state %d\n", suspend_resume_state_pdo));
  28.929 -        xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
  28.930 -        xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
  28.931 -        ScsiPortNotification(NextRequest, DeviceExtension);
  28.932 -      default:
  28.933 -        KdPrint((__DRIVER_NAME "     New pdo state %d\n", suspend_resume_state_pdo));
  28.934 -        xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
  28.935 -        xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
  28.936 -        break;
  28.937 -    }
  28.938 -    KeMemoryBarrier();
  28.939 -  }
  28.940 -
  28.941 -  if (xvdd->device_state->suspend_resume_state_fdo != SR_STATE_RUNNING)
  28.942 -  {
  28.943 -    return last_interrupt;
  28.944 -  }
  28.945 -
  28.946 -  #if DBG && NTDDI_VERSION >= NTDDI_WINXP
  28.947 -  ScsiPortQuerySystemTime(&current_time);
  28.948 -  #endif
  28.949 -
  28.950 -  while (more_to_do)
  28.951 -  {
  28.952 -    rp = xvdd->ring.sring->rsp_prod;
  28.953 -    KeMemoryBarrier();
  28.954 -    for (i = xvdd->ring.rsp_cons; i != rp; i++)
  28.955 -    {
  28.956 -      rep = XenVbd_GetResponse(xvdd, i);
  28.957 -/*
  28.958 -* This code is to automatically detect if the backend is using the same
  28.959 -* bit width or a different bit width to us. Later versions of Xen do this
  28.960 -* via a xenstore value, but not all. That 0x0fffffff (notice
  28.961 -* that the msb is not actually set, so we don't have any problems with
  28.962 -* sign extending) is to signify the last entry on the right, which is
  28.963 -* different under 32 and 64 bits, and that is why we set it up there.
  28.964 -
  28.965 -* To do the detection, we put two initial entries on the ring, with an op
  28.966 -* of 0xff (which is invalid). The first entry is mostly okay, but the
  28.967 -* second will be grossly misaligned if the backend bit width is different,
  28.968 -* and we detect this and switch frontend structures.
  28.969 -*/
  28.970 -      switch (xvdd->ring_detect_state)
  28.971 -      {
  28.972 -      case RING_DETECT_STATE_NOT_STARTED:
  28.973 -        KdPrint((__DRIVER_NAME "     premature IRQ\n"));
  28.974 -        break;
  28.975 -      case RING_DETECT_STATE_DETECT1:
  28.976 -        KdPrint((__DRIVER_NAME "     ring_detect_state = %d, index = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, i, rep->operation, rep->id, rep->status));
  28.977 -        KdPrint((__DRIVER_NAME "     req_prod = %d, rsp_prod = %d, rsp_cons = %d\n", xvdd->sring->req_prod, xvdd->sring->rsp_prod, xvdd->ring.rsp_cons));
  28.978 -        xvdd->ring_detect_state = RING_DETECT_STATE_DETECT2;
  28.979 -        break;
  28.980 -      case RING_DETECT_STATE_DETECT2:
  28.981 -        KdPrint((__DRIVER_NAME "     ring_detect_state = %d, index = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, i, rep->operation, rep->id, rep->status));
  28.982 -        KdPrint((__DRIVER_NAME "     req_prod = %d, rsp_prod = %d, rsp_cons = %d\n", xvdd->sring->req_prod, xvdd->sring->rsp_prod, xvdd->ring.rsp_cons));
  28.983 -        *xvdd->event_channel_ptr |= 0x80000000;
  28.984 -        if (rep->operation != 0xff)
  28.985 -        {
  28.986 -          KdPrint((__DRIVER_NAME "     switching to 'other' ring size\n"));
  28.987 -          xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
  28.988 -          xvdd->use_other = TRUE;
  28.989 -          *xvdd->event_channel_ptr |= 0x40000000;
  28.990 -        }
  28.991 -        xvdd->ring_detect_state = RING_DETECT_STATE_COMPLETE;
  28.992 -        ScsiPortNotification(NextRequest, DeviceExtension);
  28.993 -        break;
  28.994 -      case RING_DETECT_STATE_COMPLETE:
  28.995 -        shadow = &xvdd->shadows[rep->id & SHADOW_ID_ID_MASK];
  28.996 -        if (shadow->reset)
  28.997 -        {
  28.998 -          shadow->srb->SrbStatus = SRB_STATUS_BUS_RESET;
  28.999 -          ScsiPortNotification(RequestComplete, xvdd, shadow->srb);
 28.1000 -          KdPrint((__DRIVER_NAME "     discarding reset shadow\n"));
 28.1001 -          for (j = 0; j < shadow->req.nr_segments; j++)
 28.1002 -          {
 28.1003 -            xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
 28.1004 -              shadow->req.seg[j].gref, FALSE, (ULONG)'SCSI');
 28.1005 -          }
 28.1006 -        }
 28.1007 -        else if (dump_mode && !(rep->id & SHADOW_ID_DUMP_FLAG))
 28.1008 -        {
 28.1009 -          KdPrint((__DRIVER_NAME "     discarding stale (non-dump-mode) shadow\n"));
 28.1010 -        }
 28.1011 -        else
 28.1012 -        {
 28.1013 -          srb = shadow->srb;
 28.1014 -          ASSERT(srb);
 28.1015 -          block_count = decode_cdb_length(srb);
 28.1016 -          block_count *= xvdd->bytes_per_sector / 512;
 28.1017 -          #if DBG && NTDDI_VERSION >= NTDDI_WINXP
 28.1018 -          srb_entry = srb->SrbExtension;
 28.1019 -          elapsed = (ULONG)((current_time.QuadPart - shadow->ring_submit_time.QuadPart) / 10000L);
 28.1020 -          if (elapsed > 5000)
 28.1021 -            KdPrint((__DRIVER_NAME "     WARNING: SRB completion time %dms\n", elapsed));
 28.1022 -          #endif
 28.1023 -          if (rep->status == BLKIF_RSP_OKAY || (dump_mode &&  dump_mode_errors++ < DUMP_MODE_ERROR_LIMIT))
 28.1024 -            /* a few errors occur in dump mode because Xen refuses to allow us to map pages we are using for other stuff. Just ignore them */
 28.1025 -            srb->SrbStatus = SRB_STATUS_SUCCESS;
 28.1026 -          else
 28.1027 -          {
 28.1028 -            KdPrint((__DRIVER_NAME "     Xen Operation returned error\n"));
 28.1029 -            if (decode_cdb_is_read(srb))
 28.1030 -              KdPrint((__DRIVER_NAME "     Operation = Read\n"));
 28.1031 -            else
 28.1032 -              KdPrint((__DRIVER_NAME "     Operation = Write\n"));
 28.1033 -            if (dump_mode)
 28.1034 -            {
 28.1035 -              KdPrint((__DRIVER_NAME "     Sector = %08X, Count = %d\n", (ULONG)shadow->req.sector_number, block_count));
 28.1036 -              KdPrint((__DRIVER_NAME "     DataBuffer = %p, aligned_buffer = %p\n", srb->DataBuffer, xvdd->aligned_buffer));
 28.1037 -              KdPrint((__DRIVER_NAME "     Physical = %08x%08x\n", MmGetPhysicalAddress(srb->DataBuffer).HighPart, MmGetPhysicalAddress(srb->DataBuffer).LowPart));
 28.1038 -              KdPrint((__DRIVER_NAME "     PFN = %08x\n", (ULONG)(MmGetPhysicalAddress(srb->DataBuffer).QuadPart >> PAGE_SHIFT)));
 28.1039 -
 28.1040 -              for (j = 0; j < shadow->req.nr_segments; j++)
 28.1041 -              {
 28.1042 -                KdPrint((__DRIVER_NAME "     gref = %d\n", shadow->req.seg[j].gref));
 28.1043 -                KdPrint((__DRIVER_NAME "     first_sect = %d\n", shadow->req.seg[j].first_sect));
 28.1044 -                KdPrint((__DRIVER_NAME "     last_sect = %d\n", shadow->req.seg[j].last_sect));
 28.1045 -              }
 28.1046 -            }
 28.1047 -            srb->SrbStatus = SRB_STATUS_ERROR;
 28.1048 -            srb->ScsiStatus = 0x02;
 28.1049 -            xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
 28.1050 -            xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
 28.1051 -            XenVbd_MakeAutoSense(xvdd, srb);
 28.1052 -          }
 28.1053 -          if (shadow->aligned_buffer_in_use)
 28.1054 -          {
 28.1055 -            ASSERT(xvdd->aligned_buffer_in_use);
 28.1056 -            xvdd->aligned_buffer_in_use = FALSE;
 28.1057 -            if (srb->SrbStatus == SRB_STATUS_SUCCESS && decode_cdb_is_read(srb))
 28.1058 -              memcpy(srb->DataBuffer, xvdd->aligned_buffer, block_count * 512);
 28.1059 -          }
 28.1060 -          for (j = 0; j < shadow->req.nr_segments; j++)
 28.1061 -          {
 28.1062 -            xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
 28.1063 -              shadow->req.seg[j].gref, FALSE, (ULONG)'SCSI');
 28.1064 -          }
 28.1065 -          ScsiPortNotification(RequestComplete, xvdd, srb);
 28.1066 -        }
 28.1067 -        shadow->aligned_buffer_in_use = FALSE;
 28.1068 -        shadow->reset = FALSE;
 28.1069 -        shadow->srb = NULL;
 28.1070 -        put_shadow_on_freelist(xvdd, shadow);
 28.1071 -        break;
 28.1072 -      }
 28.1073 -    }
 28.1074 -
 28.1075 -    xvdd->ring.rsp_cons = i;
 28.1076 -    if (i != xvdd->ring.req_prod_pvt)
 28.1077 -    {
 28.1078 -      RING_FINAL_CHECK_FOR_RESPONSES(&xvdd->ring, more_to_do);
 28.1079 -    }
 28.1080 -    else
 28.1081 -    {
 28.1082 -      xvdd->ring.sring->rsp_event = i + 1;
 28.1083 -      more_to_do = FALSE;
 28.1084 -    }
 28.1085 -  }
 28.1086 -
 28.1087 -  if (start_ring_detect_state > RING_DETECT_STATE_NOT_STARTED)
 28.1088 -    XenVbd_PutQueuedSrbsOnRing(xvdd);
 28.1089 -
 28.1090 -  if (suspend_resume_state_pdo == SR_STATE_SUSPENDING)
 28.1091 -  {
 28.1092 -    if (xvdd->inactive || xvdd->shadow_free == SHADOW_ENTRIES)
 28.1093 -    {
 28.1094 -      /* all entries are purged from the list (or we are inactive). ready to suspend */
 28.1095 -      xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
 28.1096 -      KeMemoryBarrier();
 28.1097 -      KdPrint((__DRIVER_NAME "     Set fdo state SR_STATE_SUSPENDING\n"));
 28.1098 -      KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xvdd->device_state->pdo_event_channel));
 28.1099 -      xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
 28.1100 -    }
 28.1101 -    FUNCTION_EXIT();
 28.1102 -  }
 28.1103 -
 28.1104 -  return last_interrupt;
 28.1105 -}
 28.1106 -
 28.1107 -static BOOLEAN
 28.1108 -XenVbd_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK srb)
 28.1109 -{
 28.1110 -  PUCHAR data_buffer;
 28.1111 -  //ULONG data_buffer_length;
 28.1112 -  PCDB cdb;
 28.1113 -  PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
 28.1114 -  ULONG data_transfer_length = srb->DataTransferLength;
 28.1115 -
 28.1116 -  if (xvdd->inactive)
 28.1117 -  {
 28.1118 -    KdPrint((__DRIVER_NAME "     Inactive srb->Function = %08X\n", srb->Function));
 28.1119 -    srb->SrbStatus = SRB_STATUS_NO_DEVICE;
 28.1120 -    ScsiPortNotification(RequestComplete, DeviceExtension, srb);
 28.1121 -    ScsiPortNotification(NextRequest, DeviceExtension);
 28.1122 -    return TRUE;
 28.1123 -  }
 28.1124 -  
 28.1125 -  // If we haven't enumerated all the devices yet then just defer the request
 28.1126 -  if (xvdd->ring_detect_state < RING_DETECT_STATE_COMPLETE)
 28.1127 -  {
 28.1128 -    if (xvdd->ring_detect_state == RING_DETECT_STATE_NOT_STARTED)
 28.1129 -      XenVbd_StartRingDetection(xvdd);
 28.1130 -  }
 28.1131 -
 28.1132 -  if (xvdd->device_state->suspend_resume_state_pdo != SR_STATE_RUNNING)
 28.1133 -  {
 28.1134 -    KdPrint((__DRIVER_NAME " --> HwScsiStartIo (Suspending/Resuming)\n"));
 28.1135 -    srb->SrbStatus = SRB_STATUS_BUSY;
 28.1136 -    ScsiPortNotification(RequestComplete, DeviceExtension, srb);
 28.1137 -    KdPrint((__DRIVER_NAME " <-- HwScsiStartIo (Suspending/Resuming)\n"));
 28.1138 -    return TRUE;
 28.1139 -  }
 28.1140 -
 28.1141 -  if (srb->PathId != 0 || srb->TargetId != 0 || srb->Lun != 0)
 28.1142 -  {
 28.1143 -    srb->SrbStatus = SRB_STATUS_NO_DEVICE;
 28.1144 -    ScsiPortNotification(RequestComplete, DeviceExtension, srb);
 28.1145 -    ScsiPortNotification(NextRequest, DeviceExtension);
 28.1146 -    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Out of bounds)\n"));
 28.1147 -    return TRUE;
 28.1148 -  }
 28.1149 -
 28.1150 -  switch (srb->Function)
 28.1151 -  {
 28.1152 -  case SRB_FUNCTION_EXECUTE_SCSI:
 28.1153 -    cdb = (PCDB)srb->Cdb;
 28.1154 -
 28.1155 -    switch(cdb->CDB6GENERIC.OperationCode)
 28.1156 -    {
 28.1157 -    case SCSIOP_TEST_UNIT_READY:
 28.1158 -      if (dump_mode)
 28.1159 -        KdPrint((__DRIVER_NAME "     Command = TEST_UNIT_READY\n"));
 28.1160 -      srb->SrbStatus = SRB_STATUS_SUCCESS;
 28.1161 -      srb->ScsiStatus = 0;
 28.1162 -      break;
 28.1163 -    case SCSIOP_INQUIRY:
 28.1164 -      if (dump_mode)
 28.1165 -      {
 28.1166 -        //PHYSICAL_ADDRESS physical;
 28.1167 -        KdPrint((__DRIVER_NAME "     Command = INQUIRY\n"));
 28.1168 -        //KdPrint((__DRIVER_NAME "     srb->Databuffer = %p\n", srb->DataBuffer));
 28.1169 -        //physical = ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length);
 28.1170 -        //KdPrint((__DRIVER_NAME "     ScsiPortGetPhysicalAddress = %08x:%08x\n", physical.LowPart, physical.HighPart));
 28.1171 -      }
 28.1172 -//      KdPrint((__DRIVER_NAME "     (LUN = %d, EVPD = %d, Page Code = %02X)\n", srb->Cdb[1] >> 5, srb->Cdb[1] & 1, srb->Cdb[2]));
 28.1173 -//      KdPrint((__DRIVER_NAME "     (Length = %d)\n", srb->DataTransferLength));
 28.1174 -      
 28.1175 -      //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
 28.1176 -      data_buffer = srb->DataBuffer;
 28.1177 -      RtlZeroMemory(data_buffer, srb->DataTransferLength);
 28.1178 -      srb->SrbStatus = SRB_STATUS_SUCCESS;
 28.1179 -      switch (xvdd->device_type)
 28.1180 -      {
 28.1181 -      case XENVBD_DEVICETYPE_DISK:
 28.1182 -        if ((srb->Cdb[1] & 1) == 0)
 28.1183 -        {
 28.1184 -          if (srb->Cdb[2])
 28.1185 -          {
 28.1186 -            srb->SrbStatus = SRB_STATUS_ERROR;
 28.1187 -          }
 28.1188 -          else
 28.1189 -          {
 28.1190 -            PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
 28.1191 -            id->DeviceType = DIRECT_ACCESS_DEVICE;
 28.1192 -            id->Versions = 4; /* minimum that WHQL says we must support */
 28.1193 -            id->ResponseDataFormat = 2; /* not sure about this but WHQL complains otherwise */
 28.1194 -            id->HiSupport = 1; /* WHQL test says we should set this */
 28.1195 -            //id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
 28.1196 -            id->AdditionalLength = sizeof(INQUIRYDATA) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength) - 1;
 28.1197 -            id->CommandQueue = 1;
 28.1198 -            memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
 28.1199 -            memcpy(id->ProductId, scsi_disk_model, 16); // product id
 28.1200 -            memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
 28.1201 -            data_transfer_length = sizeof(INQUIRYDATA);
 28.1202 -          }
 28.1203 -        }
 28.1204 -        else
 28.1205 -        {
 28.1206 -          switch (srb->Cdb[2])
 28.1207 -          {
 28.1208 -          case VPD_SUPPORTED_PAGES: /* list of pages we support */
 28.1209 -            data_buffer[0] = DIRECT_ACCESS_DEVICE;
 28.1210 -            data_buffer[1] = VPD_SUPPORTED_PAGES;
 28.1211 -            data_buffer[2] = 0x00;
 28.1212 -            data_buffer[3] = 2;
 28.1213 -            data_buffer[4] = 0x00;
 28.1214 -            data_buffer[5] = 0x80;
 28.1215 -            data_transfer_length = 6;
 28.1216 -            break;
 28.1217 -          case VPD_SERIAL_NUMBER: /* serial number */
 28.1218 -            data_buffer[0] = DIRECT_ACCESS_DEVICE;
 28.1219 -            data_buffer[1] = VPD_SERIAL_NUMBER;
 28.1220 -            data_buffer[2] = 0x00;
 28.1221 -            data_buffer[3] = 8;
 28.1222 -            memset(&data_buffer[4], ' ', 8);
 28.1223 -            data_transfer_length = 12;
 28.1224 -            break;
 28.1225 -          case VPD_DEVICE_IDENTIFIERS: /* identification - we don't support any so just return zero */
 28.1226 -            data_buffer[0] = DIRECT_ACCESS_DEVICE;
 28.1227 -            data_buffer[1] = VPD_DEVICE_IDENTIFIERS;
 28.1228 -            data_buffer[2] = 0x00;
 28.1229 -            data_buffer[3] = 4 + (UCHAR)strlen(xvdd->vectors.path); /* length */
 28.1230 -            data_buffer[4] = 2; /* ASCII */
 28.1231 -            data_buffer[5] = 1; /* VendorId */
 28.1232 -            data_buffer[6] = 0;
 28.1233 -            data_buffer[7] = (UCHAR)strlen(xvdd->vectors.path);
 28.1234 -            memcpy(&data_buffer[8], xvdd->vectors.path, strlen(xvdd->vectors.path));
 28.1235 -            data_transfer_length = (ULONG)(8 + strlen(xvdd->vectors.path));
 28.1236 -            break;
 28.1237 -          default:
 28.1238 -            //KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", srb->Cdb[2]));
 28.1239 -            srb->SrbStatus = SRB_STATUS_ERROR;
 28.1240 -            break;
 28.1241 -          }
 28.1242 -        }
 28.1243 -        break;
 28.1244 -      case XENVBD_DEVICETYPE_CDROM:
 28.1245 -        if ((srb->Cdb[1] & 1) == 0)
 28.1246 -        {
 28.1247 -          PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
 28.1248 -          id->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
 28.1249 -          id->RemovableMedia = 1;
 28.1250 -          id->Versions = 3;
 28.1251 -          id->ResponseDataFormat = 0;
 28.1252 -          id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
 28.1253 -          id->CommandQueue = 1;
 28.1254 -          memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
 28.1255 -          memcpy(id->ProductId, scsi_cdrom_model, 16); // product id
 28.1256 -          memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
 28.1257 -        }
 28.1258 -        else
 28.1259 -        {
 28.1260 -          switch (srb->Cdb[2])
 28.1261 -          {
 28.1262 -          case 0x00:
 28.1263 -            data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
 28.1264 -            data_buffer[1] = 0x00;
 28.1265 -            data_buffer[2] = 0x00;
 28.1266 -            data_buffer[3] = 2;
 28.1267 -            data_buffer[4] = 0x00;
 28.1268 -            data_buffer[5] = 0x80;
 28.1269 -            break;
 28.1270 -          case 0x80:
 28.1271 -            data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
 28.1272 -            data_buffer[1] = 0x80;
 28.1273 -            data_buffer[2] = 0x00;
 28.1274 -            data_buffer[3] = 8;
 28.1275 -            data_buffer[4] = 0x31;
 28.1276 -            data_buffer[5] = 0x32;
 28.1277 -            data_buffer[6] = 0x33;
 28.1278 -            data_buffer[7] = 0x34;
 28.1279 -            data_buffer[8] = 0x35;
 28.1280 -            data_buffer[9] = 0x36;
 28.1281 -            data_buffer[10] = 0x37;
 28.1282 -            data_buffer[11] = 0x38;
 28.1283 -            break;
 28.1284 -          default:
 28.1285 -            //KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", srb->Cdb[2]));
 28.1286 -            srb->SrbStatus = SRB_STATUS_ERROR;
 28.1287 -            break;
 28.1288 -          }
 28.1289 -        }
 28.1290 -        break;
 28.1291 -      default:
 28.1292 -        //KdPrint((__DRIVER_NAME "     Unknown DeviceType %02x requested\n", xvdd->device_type));
 28.1293 -        srb->SrbStatus = SRB_STATUS_ERROR;
 28.1294 -        break;
 28.1295 -      }
 28.1296 -      break;
 28.1297 -    case SCSIOP_READ_CAPACITY:
 28.1298 -      if (dump_mode)
 28.1299 -        KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
 28.1300 -      //KdPrint((__DRIVER_NAME "       LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
 28.1301 -      //KdPrint((__DRIVER_NAME "       LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
 28.1302 -      //KdPrint((__DRIVER_NAME "       PMI = %d\n", srb->Cdb[8] & 1));
 28.1303 -      //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
 28.1304 -      data_buffer = srb->DataBuffer;
 28.1305 -      RtlZeroMemory(data_buffer, srb->DataTransferLength);
 28.1306 -      if ((xvdd->total_sectors - 1) >> 32)
 28.1307 -      {
 28.1308 -        data_buffer[0] = 0xff;
 28.1309 -        data_buffer[1] = 0xff;
 28.1310 -        data_buffer[2] = 0xff;
 28.1311 -        data_buffer[3] = 0xff;
 28.1312 -      }
 28.1313 -      else
 28.1314 -      {
 28.1315 -        data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
 28.1316 -        data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
 28.1317 -        data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
 28.1318 -        data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
 28.1319 -      }
 28.1320 -      data_buffer[4] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
 28.1321 -      data_buffer[5] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
 28.1322 -      data_buffer[6] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
 28.1323 -      data_buffer[7] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
 28.1324 -      srb->ScsiStatus = 0;
 28.1325 -      srb->SrbStatus = SRB_STATUS_SUCCESS;
 28.1326 -      break;
 28.1327 -    case SCSIOP_READ_CAPACITY16:
 28.1328 -      if (dump_mode)
 28.1329 -        KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
 28.1330 -      //KdPrint((__DRIVER_NAME "       LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
 28.1331 -      //KdPrint((__DRIVER_NAME "       LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
 28.1332 -      //KdPrint((__DRIVER_NAME "       PMI = %d\n", srb->Cdb[8] & 1));
 28.1333 -      //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
 28.1334 -      data_buffer = srb->DataBuffer;
 28.1335 -      RtlZeroMemory(data_buffer, srb->DataTransferLength);
 28.1336 -      data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 56) & 0xff;
 28.1337 -      data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 48) & 0xff;
 28.1338 -      data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 40) & 0xff;
 28.1339 -      data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 32) & 0xff;
 28.1340 -      data_buffer[4] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
 28.1341 -      data_buffer[5] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
 28.1342 -      data_buffer[6] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
 28.1343 -      data_buffer[7] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
 28.1344 -      data_buffer[8] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
 28.1345 -      data_buffer[9] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
 28.1346 -      data_buffer[10] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
 28.1347 -      data_buffer[11] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
 28.1348 -      srb->ScsiStatus = 0;
 28.1349 -      srb->SrbStatus = SRB_STATUS_SUCCESS;
 28.1350 -      break;
 28.1351 -    case SCSIOP_MODE_SENSE:
 28.1352 -    case SCSIOP_MODE_SENSE10:
 28.1353 -      if (dump_mode)
 28.1354 -        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));
 28.1355 -      XenVbd_FillModePage(xvdd, srb);
 28.1356 -      break;
 28.1357 -    case SCSIOP_READ:
 28.1358 -    case SCSIOP_READ16:
 28.1359 -    case SCSIOP_WRITE:
 28.1360 -    case SCSIOP_WRITE16:
 28.1361 -      XenVbd_PutSrbOnList(xvdd, srb);
 28.1362 -      XenVbd_PutQueuedSrbsOnRing(xvdd);
 28.1363 -      break;
 28.1364 -    case SCSIOP_VERIFY:
 28.1365 -    case SCSIOP_VERIFY16:
 28.1366 -      // Should we do more here?
 28.1367 -      if (dump_mode)
 28.1368 -        KdPrint((__DRIVER_NAME "     Command = VERIFY\n"));
 28.1369 -      srb->SrbStatus = SRB_STATUS_SUCCESS;
 28.1370 -      break;
 28.1371 -    case SCSIOP_REPORT_LUNS:
 28.1372 -      if (dump_mode)
 28.1373 -        KdPrint((__DRIVER_NAME "     Command = REPORT_LUNS\n"));
 28.1374 -      srb->SrbStatus = SRB_STATUS_SUCCESS;;
 28.1375 -      break;
 28.1376 -    case SCSIOP_REQUEST_SENSE:
 28.1377 -      if (dump_mode)
 28.1378 -        KdPrint((__DRIVER_NAME "     Command = REQUEST_SENSE\n"));
 28.1379 -      XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
 28.1380 -      srb->SrbStatus = SRB_STATUS_SUCCESS;
 28.1381 -      break;      
 28.1382 -    case SCSIOP_READ_TOC:
 28.1383 -      if (dump_mode)
 28.1384 -        KdPrint((__DRIVER_NAME "     Command = READ_TOC\n"));
 28.1385 -      //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
 28.1386 -      data_buffer = srb->DataBuffer;
 28.1387 -//      DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
 28.1388 -/*
 28.1389 -#define READ_TOC_FORMAT_TOC         0x00
 28.1390 -#define READ_TOC_FORMAT_SESSION     0x01
 28.1391 -#define READ_TOC_FORMAT_FULL_TOC    0x02
 28.1392 -#define READ_TOC_FORMAT_PMA         0x03
 28.1393 -#define READ_TOC_FORMAT_ATIP        0x04
 28.1394 -*/
 28.1395 -//      KdPrint((__DRIVER_NAME "     Msf = %d\n", cdb->READ_TOC.Msf));
 28.1396 -//      KdPrint((__DRIVER_NAME "     LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
 28.1397 -//      KdPrint((__DRIVER_NAME "     Format2 = %d\n", cdb->READ_TOC.Format2));
 28.1398 -//      KdPrint((__DRIVER_NAME "     StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
 28.1399 -//      KdPrint((__DRIVER_NAME "     AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
 28.1400 -//      KdPrint((__DRIVER_NAME "     Control = %d\n", cdb->READ_TOC.Control));
 28.1401 -//      KdPrint((__DRIVER_NAME "     Format = %d\n", cdb->READ_TOC.Format));
 28.1402 -      switch (cdb->READ_TOC.Format2)
 28.1403 -      {
 28.1404 -      case READ_TOC_FORMAT_TOC:
 28.1405 -        data_buffer[0] = 0; // length MSB
 28.1406 -        data_buffer[1] = 10; // length LSB
 28.1407 -        data_buffer[2] = 1; // First Track
 28.1408 -        data_buffer[3] = 1; // Last Track
 28.1409 -        data_buffer[4] = 0; // Reserved
 28.1410 -        data_buffer[5] = 0x14; // current position data + uninterrupted data
 28.1411 -        data_buffer[6] = 1; // last complete track
 28.1412 -        data_buffer[7] = 0; // reserved
 28.1413 -        data_buffer[8] = 0; // MSB Block
 28.1414 -        data_buffer[9] = 0;
 28.1415 -        data_buffer[10] = 0;
 28.1416 -        data_buffer[11] = 0; // LSB Block
 28.1417 -        srb->SrbStatus = SRB_STATUS_SUCCESS;
 28.1418 -        break;
 28.1419 -      case READ_TOC_FORMAT_SESSION:
 28.1420 -      case READ_TOC_FORMAT_FULL_TOC:
 28.1421 -      case READ_TOC_FORMAT_PMA:
 28.1422 -      case READ_TOC_FORMAT_ATIP:
 28.1423 -        srb->SrbStatus = SRB_STATUS_ERROR;
 28.1424 -        break;
 28.1425 -      }
 28.1426 -      break;
 28.1427 -    case SCSIOP_START_STOP_UNIT:
 28.1428 -      KdPrint((__DRIVER_NAME "     Command = SCSIOP_START_STOP_UNIT\n"));
 28.1429 -      srb->SrbStatus = SRB_STATUS_SUCCESS;
 28.1430 -      break;
 28.1431 -    case SCSIOP_RESERVE_UNIT:
 28.1432 -      KdPrint((__DRIVER_NAME "     Command = SCSIOP_RESERVE_UNIT\n"));
 28.1433 -      srb->SrbStatus = SRB_STATUS_SUCCESS;
 28.1434 -      break;
 28.1435 -    case SCSIOP_RELEASE_UNIT:
 28.1436 -      KdPrint((__DRIVER_NAME "     Command = SCSIOP_RELEASE_UNIT\n"));
 28.1437 -      srb->SrbStatus = SRB_STATUS_SUCCESS;
 28.1438 -      break;
 28.1439 -    default:
 28.1440 -      KdPrint((__DRIVER_NAME "     Unhandled EXECUTE_SCSI Command = %02X\n", srb->Cdb[0]));
 28.1441 -      srb->SrbStatus = SRB_STATUS_ERROR;
 28.1442 -      break;
 28.1443 -    }
 28.1444 -    if (srb->SrbStatus == SRB_STATUS_ERROR)
 28.1445 -    {
 28.1446 -      KdPrint((__DRIVER_NAME "     EXECUTE_SCSI Command = %02X returned error %02x\n", srb->Cdb[0], xvdd->last_sense_key));
 28.1447 -      if (xvdd->last_sense_key == SCSI_SENSE_NO_SENSE)
 28.1448 -      {
 28.1449 -        xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
 28.1450 -        xvdd->last_additional_sense_code = SCSI_ADSENSE_INVALID_CDB;
 28.1451 -      }
 28.1452 -      srb->ScsiStatus = 0x02;
 28.1453 -      XenVbd_MakeAutoSense(xvdd, srb);
 28.1454 -      ScsiPortNotification(RequestComplete, DeviceExtension, srb);
 28.1455 -      if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
 28.1456 -      {
 28.1457 -        ScsiPortNotification(NextRequest, DeviceExtension);
 28.1458 -      }
 28.1459 -    }
 28.1460 -    else if (srb->SrbStatus != SRB_STATUS_PENDING)
 28.1461 -    {
 28.1462 -      if (srb->SrbStatus == SRB_STATUS_SUCCESS && data_transfer_length < srb->DataTransferLength)
 28.1463 -      {
 28.1464 -        srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
 28.1465 -        srb->DataTransferLength = data_transfer_length;
 28.1466 -      }
 28.1467 -      xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
 28.1468 -      xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
 28.1469 -      ScsiPortNotification(RequestComplete, DeviceExtension, srb);
 28.1470 -      if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
 28.1471 -      {
 28.1472 -        ScsiPortNotification(NextRequest, DeviceExtension);
 28.1473 -      }
 28.1474 -    }
 28.1475 -    break;
 28.1476 -  case SRB_FUNCTION_IO_CONTROL:
 28.1477 -    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_IO_CONTROL\n"));
 28.1478 -    srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 28.1479 -    ScsiPortNotification(RequestComplete, DeviceExtension, srb);
 28.1480 -    if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
 28.1481 -    {
 28.1482 -      ScsiPortNotification(NextRequest, DeviceExtension);
 28.1483 -    }
 28.1484 -    break;
 28.1485 -  case SRB_FUNCTION_FLUSH:
 28.1486 -    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
 28.1487 -    srb->SrbStatus = SRB_STATUS_SUCCESS;
 28.1488 -    ScsiPortNotification(RequestComplete, DeviceExtension, srb);
 28.1489 -    if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
 28.1490 -    {
 28.1491 -      ScsiPortNotification(NextRequest, DeviceExtension);
 28.1492 -    }
 28.1493 -    break;
 28.1494 -  case SRB_FUNCTION_SHUTDOWN:
 28.1495 -    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_SHUTDOWN %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
 28.1496 -    srb->SrbStatus = SRB_STATUS_SUCCESS;
 28.1497 -    ScsiPortNotification(RequestComplete, DeviceExtension, srb);
 28.1498 -    if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
 28.1499 -    {
 28.1500 -      ScsiPortNotification(NextRequest, DeviceExtension);
 28.1501 -    }
 28.1502 -    break;
 28.1503 -  default:
 28.1504 -    KdPrint((__DRIVER_NAME "     Unhandled srb->Function = %08X\n", srb->Function));
 28.1505 -    srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 28.1506 -    ScsiPortNotification(RequestComplete, DeviceExtension, srb);
 28.1507 -    if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
 28.1508 -    {
 28.1509 -      ScsiPortNotification(NextRequest, DeviceExtension);
 28.1510 -    }
 28.1511 -    break;
 28.1512 -  }
 28.1513 -
 28.1514 -  //FUNCTION_EXIT();
 28.1515 -  return TRUE;
 28.1516 -}
 28.1517 -
 28.1518 -static BOOLEAN
 28.1519 -XenVbd_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId)
 28.1520 -{
 28.1521 -  PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
 28.1522 -  srb_list_entry_t *srb_entry;
 28.1523 -  PSCSI_REQUEST_BLOCK srb;
 28.1524 -  int i;
 28.1525 -
 28.1526 -  UNREFERENCED_PARAMETER(DeviceExtension);
 28.1527 -  UNREFERENCED_PARAMETER(PathId);
 28.1528 -
 28.1529 -  FUNCTION_ENTER();
 28.1530 -
 28.1531 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 28.1532 -  xvdd->aligned_buffer_in_use = FALSE;
 28.1533 -
 28.1534 -  if (xvdd->ring_detect_state == RING_DETECT_STATE_COMPLETE && xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
 28.1535 -  {
 28.1536 -    while((srb_entry = (srb_list_entry_t *)RemoveHeadList(&xvdd->srb_list)) != (srb_list_entry_t *)&xvdd->srb_list)
 28.1537 -    {
 28.1538 -      srb = srb_entry->srb;
 28.1539 -      srb->SrbStatus = SRB_STATUS_BUS_RESET;
 28.1540 -      KdPrint((__DRIVER_NAME "     completing queued SRB %p with status SRB_STATUS_BUS_RESET\n", srb));
 28.1541 -      ScsiPortNotification(RequestComplete, xvdd, srb);
 28.1542 -    }
 28.1543 -    
 28.1544 -    for (i = 0; i < MAX_SHADOW_ENTRIES; i++)
 28.1545 -    {
 28.1546 -      if (xvdd->shadows[i].srb)
 28.1547 -      {
 28.1548 -        //KdPrint((__DRIVER_NAME "     Completing in-flight srb %p with status SRB_STATUS_BUS_RESET\n", xvdd->shadows[i].srb));
 28.1549 -        /* set reset here so that the interrupt will return it with SRB_STATUS_BUS_RESET */
 28.1550 -        xvdd->shadows[i].reset = TRUE;
 28.1551 -      }
 28.1552 -    }
 28.1553 -
 28.1554 -    /* send a notify to Dom0 just in case it was missed for some reason (which should _never_ happen) */
 28.1555 -    xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
 28.1556 -  
 28.1557 -    ScsiPortNotification(NextRequest, DeviceExtension);
 28.1558 -  }
 28.1559 -
 28.1560 -  FUNCTION_EXIT();
 28.1561 -
 28.1562 -  return TRUE;
 28.1563 -}
 28.1564 -
 28.1565 -static BOOLEAN
 28.1566 -XenVbd_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState)
 28.1567 -{
 28.1568 -  UNREFERENCED_PARAMETER(DeviceExtension);
 28.1569 -  UNREFERENCED_PARAMETER(Context);
 28.1570 -  UNREFERENCED_PARAMETER(SaveState);
 28.1571 -
 28.1572 -  FUNCTION_ENTER();
 28.1573 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 28.1574 -
 28.1575 -  FUNCTION_EXIT();
 28.1576 -
 28.1577 -  return TRUE;
 28.1578 -}
 28.1579 -
 28.1580 -static SCSI_ADAPTER_CONTROL_STATUS
 28.1581 -XenVbd_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
 28.1582 -{
 28.1583 -  PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
 28.1584 -  SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
 28.1585 -  PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
 28.1586 -  //KIRQL OldIrql;
 28.1587 -
 28.1588 -  FUNCTION_ENTER();
 28.1589 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 28.1590 -  KdPrint((__DRIVER_NAME "     xvdd = %p\n", xvdd));
 28.1591 -
 28.1592 -  switch (ControlType)
 28.1593 -  {
 28.1594 -  case ScsiQuerySupportedControlTypes:
 28.1595 -    SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
 28.1596 -    KdPrint((__DRIVER_NAME "     ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
 28.1597 -    SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
 28.1598 -    SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
 28.1599 -    SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
 28.1600 -    break;
 28.1601 -  case ScsiStopAdapter:
 28.1602 -    KdPrint((__DRIVER_NAME "     ScsiStopAdapter\n"));
 28.1603 -    /* I don't think we actually have to do anything here... xenpci cleans up all the xenbus stuff for us */
 28.1604 -    break;
 28.1605 -  case ScsiRestartAdapter:
 28.1606 -    KdPrint((__DRIVER_NAME "     ScsiRestartAdapter\n"));
 28.1607 -    if (!xvdd->inactive)
 28.1608 -    {
 28.1609 -      if (XenVbd_InitFromConfig(xvdd) != SP_RETURN_FOUND) {
 28.1610 -        #pragma warning(suppress:28159)
 28.1611 -        KeBugCheckEx(DATA_COHERENCY_EXCEPTION, 0, (ULONG_PTR) xvdd, 0, 0);
 28.1612 -      }
 28.1613 -      xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED;
 28.1614 -    }
 28.1615 -    break;
 28.1616 -  case ScsiSetBootConfig:
 28.1617 -    KdPrint((__DRIVER_NAME "     ScsiSetBootConfig\n"));
 28.1618 -    break;
 28.1619 -  case ScsiSetRunningConfig:
 28.1620 -    KdPrint((__DRIVER_NAME "     ScsiSetRunningConfig\n"));
 28.1621 -    break;
 28.1622 -  default:
 28.1623 -    KdPrint((__DRIVER_NAME "     UNKNOWN\n"));
 28.1624 -    break;
 28.1625 -  }
 28.1626 -
 28.1627 -  FUNCTION_EXIT();
 28.1628 -  
 28.1629 -  return Status;
 28.1630 -}
 28.1631 -
 28.1632 -NTSTATUS
 28.1633 -DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
 28.1634 -{
 28.1635 -  ULONG status;
 28.1636 -  HW_INITIALIZATION_DATA HwInitializationData;
 28.1637 -  PVOID driver_extension;
 28.1638 -  PUCHAR ptr;
 28.1639 -  OBJECT_ATTRIBUTES oa;
 28.1640 -  HANDLE service_handle;
 28.1641 -  UNICODE_STRING param_name;
 28.1642 -  HANDLE param_handle;
 28.1643 -  UNICODE_STRING value_name;
 28.1644 -  CHAR buf[256];
 28.1645 -  ULONG buf_len;
 28.1646 -  PKEY_VALUE_PARTIAL_INFORMATION kpv;
 28.1647 -  
 28.1648 -  FUNCTION_ENTER();
 28.1649 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 28.1650 -  KdPrint((__DRIVER_NAME "     DriverObject = %p, RegistryPath = %p\n", DriverObject, RegistryPath));
 28.1651 -
 28.1652 -  /* RegistryPath == NULL when we are invoked as a crash dump driver */
 28.1653 -  if (!RegistryPath)
 28.1654 -  {
 28.1655 -    dump_mode = TRUE;
 28.1656 -  }
 28.1657 -  
 28.1658 -  if (!dump_mode)
 28.1659 -  {
 28.1660 -    IoAllocateDriverObjectExtension(DriverObject, UlongToPtr(XEN_INIT_DRIVER_EXTENSION_MAGIC), PAGE_SIZE, &driver_extension);
 28.1661 -    ptr = driver_extension;
 28.1662 -    //ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL, NULL);
 28.1663 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "ring-ref", NULL, NULL);
 28.1664 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_IRQ, "event-channel", NULL, NULL);
 28.1665 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_FRONT, "device-type", NULL, NULL);
 28.1666 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "mode", NULL, NULL);
 28.1667 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sectors", NULL, NULL);
 28.1668 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sector-size", NULL, NULL);
 28.1669 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_PRE_CONNECT, NULL, NULL, NULL);
 28.1670 -    __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
 28.1671 -    __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
 28.1672 -    __ADD_XEN_INIT_UCHAR(&ptr, 20);
 28.1673 -    __ADD_XEN_INIT_UCHAR(&ptr, 0);
 28.1674 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_POST_CONNECT, NULL, NULL, NULL);
 28.1675 -    //__ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
 28.1676 -    //__ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
 28.1677 -    //__ADD_XEN_INIT_UCHAR(&ptr, 20);
 28.1678 -    __ADD_XEN_INIT_UCHAR(&ptr, 0);
 28.1679 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_SHUTDOWN, NULL, NULL, NULL);
 28.1680 -    __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
 28.1681 -    __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
 28.1682 -    __ADD_XEN_INIT_UCHAR(&ptr, 50);
 28.1683 -    __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
 28.1684 -    __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
 28.1685 -    __ADD_XEN_INIT_UCHAR(&ptr, 50);
 28.1686 -    __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitialising);
 28.1687 -    __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitWait);
 28.1688 -    __ADD_XEN_INIT_UCHAR(&ptr, 50);
 28.1689 -    __ADD_XEN_INIT_UCHAR(&ptr, 0);
 28.1690 -    
 28.1691 -    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
 28.1692 -
 28.1693 -    InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
 28.1694 -    status = ZwOpenKey(&service_handle, KEY_READ, &oa);
 28.1695 -    if(!NT_SUCCESS(status))
 28.1696 -    {
 28.1697 -      KdPrint((__DRIVER_NAME "     ZwOpenKey(Service) returned %08x\n", status));
 28.1698 -    }
 28.1699 -    else
 28.1700 -    {
 28.1701 -      RtlInitUnicodeString(&param_name, L"Parameters");
 28.1702 -      InitializeObjectAttributes(&oa, &param_name, OBJ_CASE_INSENSITIVE, service_handle, NULL);
 28.1703 -      status = ZwOpenKey(&param_handle, KEY_READ, &oa);
 28.1704 -      if(!NT_SUCCESS(status))
 28.1705 -      {
 28.1706 -        KdPrint((__DRIVER_NAME "     ZwOpenKey(Parameters) returned %08x\n", status));
 28.1707 -      }
 28.1708 -      else
 28.1709 -      {
 28.1710 -        kpv = (PKEY_VALUE_PARTIAL_INFORMATION)buf;
 28.1711 -        RtlFillMemory(scsi_device_manufacturer, 8, ' ');
 28.1712 -        RtlFillMemory(scsi_disk_model, 16, ' ');
 28.1713 -        RtlFillMemory(scsi_cdrom_model, 16, ' ');
 28.1714 -
 28.1715 -        RtlInitUnicodeString(&value_name, L"Manufacturer");
 28.1716 -        buf_len = 256;
 28.1717 -        status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
 28.1718 -        if(NT_SUCCESS(status))
 28.1719 -          wcstombs(scsi_device_manufacturer, (PWCHAR)kpv->Data, min(kpv->DataLength, 8));
 28.1720 -        else
 28.1721 -          RtlStringCbCopyA(scsi_device_manufacturer, 8, "XEN     ");
 28.1722 -
 28.1723 -        RtlInitUnicodeString(&value_name, L"Disk_Model");
 28.1724 -        buf_len = 256;
 28.1725 -        status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
 28.1726 -        if(NT_SUCCESS(status))
 28.1727 -          wcstombs(scsi_disk_model, (PWCHAR)kpv->Data, min(kpv->DataLength, 16));
 28.1728 -        else
 28.1729 -          RtlStringCbCopyA(scsi_disk_model, 16, "PV DISK          ");
 28.1730 -
 28.1731 -        RtlInitUnicodeString(&value_name, L"CDROM_Model");
 28.1732 -        buf_len = 256;
 28.1733 -        status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
 28.1734 -        if(NT_SUCCESS(status))
 28.1735 -          wcstombs(scsi_cdrom_model, (PWCHAR)kpv->Data, min(kpv->DataLength, 16));
 28.1736 -        else
 28.1737 -          RtlStringCbCopyA(scsi_cdrom_model, 16, "PV CDROM        ");
 28.1738 -        ZwClose(param_handle);
 28.1739 -      }
 28.1740 -      ZwClose(service_handle);
 28.1741 -    }
 28.1742 -  }
 28.1743 -  
 28.1744 -  RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
 28.1745 -
 28.1746 -  HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
 28.1747 -  HwInitializationData.AdapterInterfaceType = PNPBus;
 28.1748 -  if (!dump_mode)
 28.1749 -    HwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE;
 28.1750 -  else
 28.1751 -    HwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE;
 28.1752 -  HwInitializationData.SpecificLuExtensionSize = 0;
 28.1753 -  HwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
 28.1754 -  HwInitializationData.NumberOfAccessRanges = 1;
 28.1755 -  HwInitializationData.MapBuffers = TRUE;
 28.1756 -  HwInitializationData.NeedPhysicalAddresses = FALSE;
 28.1757 -  HwInitializationData.TaggedQueuing = TRUE;
 28.1758 -  HwInitializationData.AutoRequestSense = TRUE;
 28.1759 -  HwInitializationData.MultipleRequestPerLu = TRUE;
 28.1760 -  HwInitializationData.ReceiveEvent = FALSE;
 28.1761 -  HwInitializationData.VendorIdLength = 0;
 28.1762 -  HwInitializationData.VendorId = NULL;
 28.1763 -  HwInitializationData.DeviceIdLength = 0;
 28.1764 -  HwInitializationData.DeviceId = NULL;
 28.1765 -
 28.1766 -  HwInitializationData.HwInitialize = XenVbd_HwScsiInitialize;
 28.1767 -  HwInitializationData.HwStartIo = XenVbd_HwScsiStartIo;
 28.1768 -  HwInitializationData.HwInterrupt = XenVbd_HwScsiInterrupt;
 28.1769 -  HwInitializationData.HwFindAdapter = XenVbd_HwScsiFindAdapter;
 28.1770 -  HwInitializationData.HwResetBus = XenVbd_HwScsiResetBus;
 28.1771 -  HwInitializationData.HwDmaStarted = NULL;
 28.1772 -  HwInitializationData.HwAdapterState = NULL; //XenVbd_HwScsiAdapterState;
 28.1773 -  HwInitializationData.HwAdapterControl = XenVbd_HwScsiAdapterControl;
 28.1774 -
 28.1775 -  status = ScsiPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
 28.1776 -  
 28.1777 -  if(!NT_SUCCESS(status))
 28.1778 -  {
 28.1779 -    KdPrint((__DRIVER_NAME " ScsiPortInitialize failed with status 0x%08x\n", status));
 28.1780 -  }
 28.1781 -
 28.1782 -  FUNCTION_EXIT();
 28.1783 -
 28.1784 -  return status;
 28.1785 -}
    29.1 --- a/xenvbd/xenvbd_scsiport.h	Sun Jan 06 14:08:22 2013 +1100
    29.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.3 @@ -1,172 +0,0 @@
    29.4 -/*
    29.5 -PV Drivers for Windows Xen HVM Domains
    29.6 -Copyright (C) 2007 James Harper
    29.7 -
    29.8 -This program is free software; you can redistribute it and/or
    29.9 -modify it under the terms of the GNU General Public License
   29.10 -as published by the Free Software Foundation; either version 2
   29.11 -of the License, or (at your option) any later version.
   29.12 -
   29.13 -This program is distributed in the hope that it will be useful,
   29.14 -but WITHOUT ANY WARRANTY; without even the implied warranty of
   29.15 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   29.16 -GNU General Public License for more details.
   29.17 -
   29.18 -You should have received a copy of the GNU General Public License
   29.19 -along with this program; if not, write to the Free Software
   29.20 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   29.21 -*/
   29.22 -
   29.23 -#if !defined(_XENVBD_H_)
   29.24 -#define _XENVBD_H_
   29.25 -
   29.26 -#define DDKAPI
   29.27 -
   29.28 -//#include <ntifs.h>
   29.29 -#include <ntddk.h>
   29.30 -#include <wdm.h>
   29.31 -#include <initguid.h>
   29.32 -#define NTSTRSAFE_LIB
   29.33 -#include <ntstrsafe.h>
   29.34 -
   29.35 -#include <ntdddisk.h>
   29.36 -#if (NTDDI_VERSION < NTDDI_WINXP) /* srb.h causes warnings under 2K for some reason */
   29.37 -#pragma warning(disable:4201) /* nameless struct/union */
   29.38 -#pragma warning(disable:4214) /* bit field types other than int */
   29.39 -#endif
   29.40 -#include <srb.h>
   29.41 -
   29.42 -#define __DRIVER_NAME "XenVbd"
   29.43 -
   29.44 -#include <xen_windows.h>
   29.45 -#include <memory.h>
   29.46 -//#include <grant_table.h>
   29.47 -#include <event_channel.h>
   29.48 -#include <hvm/params.h>
   29.49 -#include <hvm/hvm_op.h>
   29.50 -#include <xen_public.h>
   29.51 -#include <io/ring.h>
   29.52 -#include <io/blkif.h>
   29.53 -#include <io/xenbus.h>
   29.54 -
   29.55 -#define XENVBD_POOL_TAG (ULONG) 'XVBD'
   29.56 -
   29.57 -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
   29.58 -#define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
   29.59 -#define BLK_OTHER_RING_SIZE __RING_SIZE((blkif_other_sring_t *)0, PAGE_SIZE)
   29.60 -
   29.61 -#if defined(__x86_64__)
   29.62 -#pragma pack(push, 4)
   29.63 -#endif
   29.64 -struct blkif_other_request {
   29.65 -  uint8_t operation;
   29.66 -  uint8_t nr_segments;
   29.67 -  blkif_vdev_t handle;
   29.68 -  uint64_t id;
   29.69 -  blkif_sector_t sector_number;
   29.70 -  struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
   29.71 -};
   29.72 -struct blkif_other_response {
   29.73 -  uint64_t id;
   29.74 -  uint8_t operation;
   29.75 -  int16_t status;
   29.76 -};
   29.77 -#if defined(__x86_64__)
   29.78 -#pragma pack(pop)
   29.79 -#endif
   29.80 -
   29.81 -typedef struct blkif_other_request blkif_other_request_t;
   29.82 -typedef struct blkif_other_response blkif_other_response_t;
   29.83 -DEFINE_RING_TYPES(blkif_other, struct blkif_other_request, struct blkif_other_response);
   29.84 -
   29.85 -typedef struct {
   29.86 -  LIST_ENTRY list_entry;
   29.87 -  PSCSI_REQUEST_BLOCK srb;
   29.88 -} srb_list_entry_t;
   29.89 -
   29.90 -typedef struct {
   29.91 -  blkif_request_t req;
   29.92 -  PSCSI_REQUEST_BLOCK srb;
   29.93 -  BOOLEAN aligned_buffer_in_use;
   29.94 -  BOOLEAN reset;
   29.95 -  #if DBG && NTDDI_VERSION >= NTDDI_WINXP
   29.96 -  LARGE_INTEGER ring_submit_time;
   29.97 -  #endif
   29.98 -} blkif_shadow_t;
   29.99 -
  29.100 -#define MAX_SHADOW_ENTRIES  64
  29.101 -#define SHADOW_ID_ID_MASK   0x03FF /* maximum of 1024 requests - currently use a maximum of 64 though */
  29.102 -#define SHADOW_ID_DUMP_FLAG 0x8000 /* indicates the request was generated by dump mode */
  29.103 -
  29.104 -#define SHADOW_ENTRIES min(MAX_SHADOW_ENTRIES, min(BLK_RING_SIZE, BLK_OTHER_RING_SIZE))
  29.105 -
  29.106 -typedef enum {
  29.107 -  XENVBD_DEVICETYPE_UNKNOWN,
  29.108 -  XENVBD_DEVICETYPE_DISK,
  29.109 -  XENVBD_DEVICETYPE_CDROM,
  29.110 -  XENVBD_DEVICETYPE_CONTROLLER // Not yet used
  29.111 -} XENVBD_DEVICETYPE;
  29.112 -
  29.113 -typedef enum {
  29.114 -  XENVBD_DEVICEMODE_UNKNOWN,
  29.115 -  XENVBD_DEVICEMODE_READ,
  29.116 -  XENVBD_DEVICEMODE_WRITE
  29.117 -} XENVBD_DEVICEMODE;
  29.118 -
  29.119 -#define RING_DETECT_STATE_NOT_STARTED  0
  29.120 -#define RING_DETECT_STATE_DETECT1      1
  29.121 -#define RING_DETECT_STATE_DETECT2      2
  29.122 -#define RING_DETECT_STATE_COMPLETE     3
  29.123 -
  29.124 -struct
  29.125 -{
  29.126 -  BOOLEAN inactive;
  29.127 -  
  29.128 -  blkif_shadow_t shadows[MAX_SHADOW_ENTRIES];
  29.129 -  USHORT shadow_free_list[MAX_SHADOW_ENTRIES];
  29.130 -  USHORT shadow_free;
  29.131 -  USHORT shadow_min_free;
  29.132 -
  29.133 -  PUCHAR device_base;
  29.134 -
  29.135 -  blkif_sring_t *sring;
  29.136 -  evtchn_port_t event_channel;
  29.137 -  ULONG *event_channel_ptr;
  29.138 -  union {
  29.139 -    blkif_front_ring_t ring;
  29.140 -    blkif_other_front_ring_t other_ring;
  29.141 -  };
  29.142 -  int ring_detect_state;
  29.143 -  BOOLEAN use_other;
  29.144 -  BOOLEAN cached_use_other;
  29.145 -  BOOLEAN cached_use_other_valid;
  29.146 -  UCHAR last_sense_key;
  29.147 -  UCHAR last_additional_sense_code;
  29.148 -  blkif_response_t tmp_rep;
  29.149 -  XENVBD_DEVICETYPE device_type;
  29.150 -  XENVBD_DEVICEMODE device_mode;
  29.151 -  ULONG bytes_per_sector;
  29.152 -  ULONGLONG total_sectors;
  29.153 -  XENPCI_VECTORS vectors;
  29.154 -  PXENPCI_DEVICE_STATE device_state;
  29.155 -  LIST_ENTRY srb_list;
  29.156 -  grant_ref_t dump_grant_refs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
  29.157 -  BOOLEAN aligned_buffer_in_use;
  29.158 -  PVOID aligned_buffer;
  29.159 -/*  
  29.160 -  ULONGLONG interrupts;
  29.161 -  ULONGLONG aligned_requests;
  29.162 -  ULONGLONG aligned_bytes;
  29.163 -  ULONGLONG unaligned_requests;
  29.164 -  ULONGLONG unaligned_bytes;
  29.165 -*/
  29.166 -  #define BLKIF_MAX_SEGMENTS_PER_REQUEST_DUMP_MODE 1
  29.167 -  #define UNALIGNED_BUFFER_DATA_SIZE ((BLKIF_MAX_SEGMENTS_PER_REQUEST + 1) * PAGE_SIZE - 1)
  29.168 -  #define UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE ((BLKIF_MAX_SEGMENTS_PER_REQUEST_DUMP_MODE + 1) * PAGE_SIZE - 1)
  29.169 -  /* this has to be right at the end of DeviceExtension */
  29.170 -  /* can't allocate too much data in dump mode so size DeviceExtensionSize accordingly */
  29.171 -  UCHAR aligned_buffer_data[1];
  29.172 -} typedef XENVBD_DEVICE_DATA, *PXENVBD_DEVICE_DATA;
  29.173 -
  29.174 -#endif
  29.175 -
    30.1 --- a/xenvbd/xenvbd_storport.c	Sun Jan 06 14:08:22 2013 +1100
    30.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.3 @@ -1,2149 +0,0 @@
    30.4 -/*
    30.5 -PV Drivers for Windows Xen HVM Domains
    30.6 -Copyright (C) 2007 James Harper
    30.7 -
    30.8 -This program is free software; you can redistribute it and/or
    30.9 -modify it under the terms of the GNU General Public License
   30.10 -as published by the Free Software Foundation; either version 2
   30.11 -of the License, or (at your option) any later version.
   30.12 -
   30.13 -This program is distributed in the hope that it will be useful,
   30.14 -but WITHOUT ANY WARRANTY; without even the implied warranty of
   30.15 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   30.16 -GNU General Public License for more details.
   30.17 -
   30.18 -You should have received a copy of the GNU General Public License
   30.19 -along with this program; if not, write to the Free Software
   30.20 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   30.21 -*/
   30.22 -
   30.23 -#define INITGUID
   30.24 -#include "xenvbd_storport.h"
   30.25 -
   30.26 -#pragma warning(disable: 4127)
   30.27 -
   30.28 -#if defined(__x86_64__)
   30.29 -  #define LongLongToPtr(x) (PVOID)(x)
   30.30 -#else
   30.31 -  #define LongLongToPtr(x) UlongToPtr(x)
   30.32 -#endif
   30.33 -
   30.34 -#if defined(__x86_64__)
   30.35 -  #define ABI_PROTOCOL "x86_64-abi"
   30.36 -#else
   30.37 -  #define ABI_PROTOCOL "x86_32-abi"
   30.38 -#endif
   30.39 -
   30.40 -/* Not really necessary but keeps PREfast happy */
   30.41 -DRIVER_INITIALIZE DriverEntry;
   30.42 -static VOID XenVbd_HandleEventDpc(PSTOR_DPC dpc, PVOID DeviceExtension, PVOID arg1, PVOID arg2);
   30.43 -static VOID XenVbd_HandleEventDIRQL(PVOID DeviceExtension);
   30.44 -static VOID XenVbd_ProcessSrbList(PXENVBD_DEVICE_DATA xvdd);
   30.45 -
   30.46 -static BOOLEAN dump_mode = FALSE;
   30.47 -#define DUMP_MODE_ERROR_LIMIT 64
   30.48 -static ULONG dump_mode_errors = 0;
   30.49 -
   30.50 -CHAR scsi_device_manufacturer[8];
   30.51 -CHAR scsi_disk_model[16];
   30.52 -CHAR scsi_cdrom_model[16];
   30.53 -
   30.54 -ULONGLONG parse_numeric_string(PCHAR string)
   30.55 -{
   30.56 -  ULONGLONG val = 0;
   30.57 -  while (*string != 0)
   30.58 -  {
   30.59 -    val = val * 10 + (*string - '0');
   30.60 -    string++;
   30.61 -  }
   30.62 -  return val;
   30.63 -}
   30.64 -
   30.65 -/* called with StartIoLock held */
   30.66 -static blkif_shadow_t *
   30.67 -get_shadow_from_freelist(PXENVBD_DEVICE_DATA xvdd)
   30.68 -{
   30.69 -  if (xvdd->shadow_free == 0) {
   30.70 -    KdPrint((__DRIVER_NAME "     No more shadow entries\n"));
   30.71 -    return NULL;
   30.72 -  }
   30.73 -  xvdd->shadow_free--;
   30.74 -  if (xvdd->shadow_free < xvdd->shadow_min_free)
   30.75 -    xvdd->shadow_min_free = xvdd->shadow_free;
   30.76 -  return &xvdd->shadows[xvdd->shadow_free_list[xvdd->shadow_free]];
   30.77 -}
   30.78 -
   30.79 -/* called with StartIoLock held */
   30.80 -static VOID
   30.81 -put_shadow_on_freelist(PXENVBD_DEVICE_DATA xvdd, blkif_shadow_t *shadow)
   30.82 -{
   30.83 -  xvdd->shadow_free_list[xvdd->shadow_free] = (USHORT)(shadow->req.id & SHADOW_ID_ID_MASK);
   30.84 -  shadow->srb = NULL;
   30.85 -  shadow->reset = FALSE;
   30.86 -  shadow->aligned_buffer_in_use = FALSE;
   30.87 -  xvdd->shadow_free++;
   30.88 -}
   30.89 -
   30.90 -static blkif_response_t *
   30.91 -XenVbd_GetResponse(PXENVBD_DEVICE_DATA xvdd, int i) {
   30.92 -  return RING_GET_RESPONSE(&xvdd->ring, i);
   30.93 -}
   30.94 -
   30.95 -static VOID
   30.96 -XenVbd_PutRequest(PXENVBD_DEVICE_DATA xvdd, blkif_request_t *req) {
   30.97 -  //FUNCTION_ENTER();
   30.98 -  *RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt) = *req;
   30.99 -  xvdd->ring.req_prod_pvt++;
  30.100 -  //FUNCTION_EXIT();
  30.101 -}
  30.102 -
  30.103 -#if 0
  30.104 -static ULONG
  30.105 -XenVbd_InitConfig(PXENVBD_DEVICE_DATA xvdd)
  30.106 -{
  30.107 -  ULONG status;
  30.108 -  PUCHAR ptr;
  30.109 -  USHORT type;
  30.110 -  PCHAR setting, value, value2;
  30.111 -
  30.112 -  FUNCTION_ENTER();
  30.113 -  /* first read the default config items */
  30.114 -  ptr = xvdd->device_base;
  30.115 -  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
  30.116 -  {
  30.117 -    switch(type)
  30.118 -    {
  30.119 -    case XEN_INIT_TYPE_VECTORS:
  30.120 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
  30.121 -      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
  30.122 -        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
  30.123 -      {
  30.124 -        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
  30.125 -          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
  30.126 -        KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  30.127 -        return SP_RETURN_BAD_CONFIG;
  30.128 -      }
  30.129 -      else
  30.130 -        memcpy(&xvdd->vectors, value, sizeof(XENPCI_VECTORS));
  30.131 -      break;
  30.132 -    default:
  30.133 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
  30.134 -      break;
  30.135 -    }
  30.136 -  }
  30.137 -
  30.138 -  /* then set up all the configuration requests */
  30.139 -  ptr = xvdd->device_base;
  30.140 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "ring-ref", NULL, NULL);
  30.141 -  #pragma warning(suppress:4054)
  30.142 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_DPC, "event-channel", (PVOID)XenVbd_HandleEvent, xvdd);
  30.143 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_FRONT, "device-type", NULL, NULL);
  30.144 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "mode", NULL, NULL);
  30.145 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sectors", NULL, NULL);
  30.146 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sector-size", NULL, NULL);
  30.147 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_PRE_CONNECT, NULL, NULL, NULL);
  30.148 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitialised);
  30.149 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
  30.150 -  __ADD_XEN_INIT_UCHAR(&ptr, 20);
  30.151 -  __ADD_XEN_INIT_UCHAR(&ptr, 0);
  30.152 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_POST_CONNECT, NULL, NULL, NULL);
  30.153 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
  30.154 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
  30.155 -  __ADD_XEN_INIT_UCHAR(&ptr, 20);
  30.156 -  __ADD_XEN_INIT_UCHAR(&ptr, 0);
  30.157 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_SHUTDOWN, NULL, NULL, NULL);
  30.158 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
  30.159 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
  30.160 -  __ADD_XEN_INIT_UCHAR(&ptr, 50);
  30.161 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
  30.162 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
  30.163 -  __ADD_XEN_INIT_UCHAR(&ptr, 50);
  30.164 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitialising);
  30.165 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitWait);
  30.166 -  __ADD_XEN_INIT_UCHAR(&ptr, 50);
  30.167 -  __ADD_XEN_INIT_UCHAR(&ptr, 0);
  30.168 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
  30.169 -
  30.170 -  /* then configure */
  30.171 -  status = xvdd->vectors.XenPci_XenConfigDevice(xvdd->vectors.context);
  30.172 -  if (!NT_SUCCESS(status))
  30.173 -  {
  30.174 -    xvdd->vbd_status = VBD_STATUS_INACTIVE;
  30.175 -    KdPrint(("Failed to complete device configuration (%08x)\n", status));
  30.176 -    FUNCTION_EXIT();
  30.177 -    return SP_RETURN_BAD_CONFIG;
  30.178 -  }
  30.179 -  FUNCTION_EXIT();
  30.180 -  return SP_RETURN_FOUND;
  30.181 -}
  30.182 -
  30.183 -static ULONG
  30.184 -XenVbd_InitFromConfig(PXENVBD_DEVICE_DATA xvdd)
  30.185 -{
  30.186 -  ULONG i;
  30.187 -  PUCHAR ptr;
  30.188 -  USHORT type;
  30.189 -  PCHAR setting, value, value2;
  30.190 -  ULONG qemu_protocol_version = 0;
  30.191 -
  30.192 -  FUNCTION_ENTER();
  30.193 -  
  30.194 -  xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
  30.195 -  xvdd->sring = NULL;
  30.196 -  xvdd->event_channel = 0;
  30.197 -  
  30.198 -  //xvdd->inactive = TRUE;  
  30.199 -  
  30.200 -  ptr = xvdd->device_base;
  30.201 -  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
  30.202 -  {
  30.203 -    switch(type)
  30.204 -    {
  30.205 -    case XEN_INIT_TYPE_VECTORS:
  30.206 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
  30.207 -      if (dump_mode)
  30.208 -      {
  30.209 -        if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
  30.210 -          ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
  30.211 -        {
  30.212 -          KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
  30.213 -            ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
  30.214 -          KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  30.215 -          return SP_RETURN_BAD_CONFIG;
  30.216 -        }
  30.217 -        else
  30.218 -          memcpy(&xvdd->vectors, value, sizeof(XENPCI_VECTORS));
  30.219 -      }
  30.220 -      break;
  30.221 -    case XEN_INIT_TYPE_RING: /* frontend ring */
  30.222 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
  30.223 -      if (strcmp(setting, "ring-ref") == 0)
  30.224 -      {
  30.225 -        xvdd->sring = (blkif_sring_t *)value;
  30.226 -        FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE);
  30.227 -        /* this bit is for when we have to take over an existing ring on a crash dump */
  30.228 -        xvdd->ring.req_prod_pvt = xvdd->sring->req_prod;
  30.229 -        xvdd->ring.rsp_cons = xvdd->ring.req_prod_pvt;
  30.230 -      }
  30.231 -      break;
  30.232 -    case XEN_INIT_TYPE_EVENT_CHANNEL_DPC: /* frontend event channel */
  30.233 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d (%08x)\n", setting, PtrToUlong(value) & 0x3FFFFFFF, PtrToUlong(value)));
  30.234 -      if (strcmp(setting, "event-channel") == 0)
  30.235 -      {
  30.236 -        /* cheat here - save the state of the ring in the topmost bits of the event-channel */
  30.237 -        xvdd->event_channel_ptr = (ULONG *)(((PCHAR)ptr) - sizeof(ULONG));
  30.238 -        xvdd->event_channel = PtrToUlong(value) & 0x3FFFFFFF;
  30.239 -      }
  30.240 -      break;
  30.241 -    case XEN_INIT_TYPE_READ_STRING_BACK:
  30.242 -    case XEN_INIT_TYPE_READ_STRING_FRONT:
  30.243 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
  30.244 -      if (strcmp(setting, "sectors") == 0)
  30.245 -        xvdd->total_sectors = parse_numeric_string(value);
  30.246 -      else if (strcmp(setting, "sector-size") == 0)
  30.247 -        xvdd->hw_bytes_per_sector = (ULONG)parse_numeric_string(value);
  30.248 -      else if (strcmp(setting, "device-type") == 0)
  30.249 -      {
  30.250 -        if (strcmp(value, "disk") == 0)
  30.251 -        {
  30.252 -          KdPrint((__DRIVER_NAME "     device-type = Disk\n"));    
  30.253 -          xvdd->device_type = XENVBD_DEVICETYPE_DISK;
  30.254 -        }
  30.255 -        else if (strcmp(value, "cdrom") == 0)
  30.256 -        {
  30.257 -          KdPrint((__DRIVER_NAME "     device-type = CDROM\n"));    
  30.258 -          xvdd->device_type = XENVBD_DEVICETYPE_CDROM;
  30.259 -        }
  30.260 -        else
  30.261 -        {
  30.262 -          KdPrint((__DRIVER_NAME "     device-type = %s (This probably won't work!)\n", value));
  30.263 -          xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
  30.264 -        }
  30.265 -      }
  30.266 -      else if (strcmp(setting, "mode") == 0)
  30.267 -      {
  30.268 -        if (strncmp(value, "r", 1) == 0)
  30.269 -        {
  30.270 -          KdPrint((__DRIVER_NAME "     mode = r\n"));    
  30.271 -          xvdd->device_mode = XENVBD_DEVICEMODE_READ;
  30.272 -        }
  30.273 -        else if (strncmp(value, "w", 1) == 0)
  30.274 -        {
  30.275 -          KdPrint((__DRIVER_NAME "     mode = w\n"));    
  30.276 -          xvdd->device_mode = XENVBD_DEVICEMODE_WRITE;
  30.277 -        }
  30.278 -        else
  30.279 -        {
  30.280 -          KdPrint((__DRIVER_NAME "     mode = unknown\n"));
  30.281 -          xvdd->device_mode = XENVBD_DEVICEMODE_UNKNOWN;
  30.282 -        }
  30.283 -      }
  30.284 -      break;
  30.285 -    case XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION:
  30.286 -      qemu_protocol_version = PtrToUlong(value);
  30.287 -      break;
  30.288 -    case XEN_INIT_TYPE_QEMU_HIDE_FLAGS:
  30.289 -      qemu_hide_flags_value = PtrToUlong(value);
  30.290 -      KdPrint((__DRIVER_NAME "     qemu_hide_flags_value = %d\n", qemu_hide_flags_value));
  30.291 -      break;
  30.292 -    case XEN_INIT_TYPE_QEMU_HIDE_FILTER:
  30.293 -      qemu_hide_filter = TRUE;
  30.294 -      KdPrint((__DRIVER_NAME "     qemu_hide_filter = TRUE\n"));
  30.295 -      break;
  30.296 -    case XEN_INIT_TYPE_STATE_PTR:
  30.297 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
  30.298 -      xvdd->device_state = (PXENPCI_DEVICE_STATE)value;
  30.299 -      break;
  30.300 -    default:
  30.301 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
  30.302 -      break;
  30.303 -    }
  30.304 -  }
  30.305 -
  30.306 -  if (((qemu_hide_flags_value & QEMU_UNPLUG_ALL_IDE_DISKS) && xvdd->device_type != XENVBD_DEVICETYPE_CDROM) || qemu_hide_filter)
  30.307 -    xvdd->inactive = FALSE;
  30.308 -  
  30.309 -  if (!xvdd->inactive && (xvdd->device_type == XENVBD_DEVICETYPE_UNKNOWN
  30.310 -      || xvdd->sring == NULL
  30.311 -      || xvdd->event_channel == 0
  30.312 -      || xvdd->total_sectors == 0
  30.313 -      || xvdd->hw_bytes_per_sector == 0))
  30.314 -  {
  30.315 -    KdPrint((__DRIVER_NAME "     Missing settings\n"));
  30.316 -    FUNCTION_EXIT();
  30.317 -    return SP_RETURN_BAD_CONFIG;
  30.318 -  }
  30.319 -
  30.320 -  if (xvdd->inactive) {
  30.321 -    KdPrint((__DRIVER_NAME "     Device is inactive\n"));
  30.322 -  } else {
  30.323 -    if (xvdd->device_type == XENVBD_DEVICETYPE_CDROM) {
  30.324 -      /* CD/DVD drives must have bytes_per_sector = 2048. */
  30.325 -      xvdd->bytes_per_sector = 2048;
  30.326 -      xvdd->hw_bytes_per_sector = 2048;
  30.327 -    } else {
  30.328 -      xvdd->bytes_per_sector = 512;
  30.329 -    }
  30.330 -    /* for some reason total_sectors is measured in 512 byte sectors always, so correct this to be in bytes_per_sectors */
  30.331 -    xvdd->total_sectors /= xvdd->bytes_per_sector / 512;
  30.332 -
  30.333 -    xvdd->shadow_free = 0;
  30.334 -    memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
  30.335 -    for (i = 0; i < SHADOW_ENTRIES; i++) {
  30.336 -      xvdd->shadows[i].req.id = i;
  30.337 -      /* make sure leftover real requests's are never confused with dump mode requests */
  30.338 -      if (dump_mode)
  30.339 -        xvdd->shadows[i].req.id |= SHADOW_ID_DUMP_FLAG;
  30.340 -      put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
  30.341 -    }
  30.342 -  }
  30.343 -
  30.344 -  FUNCTION_EXIT();
  30.345 -  return SP_RETURN_FOUND;
  30.346 -}
  30.347 -#endif
  30.348 -
  30.349 -static __inline ULONG
  30.350 -decode_cdb_length(PSCSI_REQUEST_BLOCK srb)
  30.351 -{
  30.352 -  switch (srb->Cdb[0])
  30.353 -  {
  30.354 -  case SCSIOP_READ:
  30.355 -  case SCSIOP_WRITE:
  30.356 -    return ((ULONG)(UCHAR)srb->Cdb[7] << 8) | (ULONG)(UCHAR)srb->Cdb[8];
  30.357 -  case SCSIOP_READ16:
  30.358 -  case SCSIOP_WRITE16:
  30.359 -    return ((ULONG)(UCHAR)srb->Cdb[10] << 24) | ((ULONG)(UCHAR)srb->Cdb[11] << 16) | ((ULONG)(UCHAR)srb->Cdb[12] << 8) | (ULONG)(UCHAR)srb->Cdb[13];    
  30.360 -  default:
  30.361 -    return 0;
  30.362 -  }
  30.363 -}
  30.364 -
  30.365 -static __inline ULONGLONG
  30.366 -decode_cdb_sector(PSCSI_REQUEST_BLOCK srb)
  30.367 -{
  30.368 -  ULONGLONG sector;
  30.369 -  
  30.370 -  switch (srb->Cdb[0])
  30.371 -  {
  30.372 -  case SCSIOP_READ:
  30.373 -  case SCSIOP_WRITE:
  30.374 -    sector = ((ULONG)(UCHAR)srb->Cdb[2] << 24) | ((ULONG)(UCHAR)srb->Cdb[3] << 16) | ((ULONG)(UCHAR)srb->Cdb[4] << 8) | (ULONG)(UCHAR)srb->Cdb[5];
  30.375 -    break;
  30.376 -  case SCSIOP_READ16:
  30.377 -  case SCSIOP_WRITE16:
  30.378 -    sector = ((ULONGLONG)(UCHAR)srb->Cdb[2] << 56) | ((ULONGLONG)(UCHAR)srb->Cdb[3] << 48)
  30.379 -           | ((ULONGLONG)(UCHAR)srb->Cdb[4] << 40) | ((ULONGLONG)(UCHAR)srb->Cdb[5] << 32)
  30.380 -           | ((ULONGLONG)(UCHAR)srb->Cdb[6] << 24) | ((ULONGLONG)(UCHAR)srb->Cdb[7] << 16)
  30.381 -           | ((ULONGLONG)(UCHAR)srb->Cdb[8] << 8) | ((ULONGLONG)(UCHAR)srb->Cdb[9]);
  30.382 -    //KdPrint((__DRIVER_NAME "     sector_number = %d (high) %d (low)\n", (ULONG)(sector >> 32), (ULONG)sector));
  30.383 -    break;
  30.384 -  default:
  30.385 -    sector = 0;
  30.386 -    break;
  30.387 -  }
  30.388 -  return sector;
  30.389 -}
  30.390 -
  30.391 -static __inline BOOLEAN
  30.392 -decode_cdb_is_read(PSCSI_REQUEST_BLOCK srb)
  30.393 -{
  30.394 -  switch (srb->Cdb[0])
  30.395 -  {
  30.396 -  case SCSIOP_READ:
  30.397 -  case SCSIOP_READ16:
  30.398 -    return TRUE;
  30.399 -  case SCSIOP_WRITE:
  30.400 -  case SCSIOP_WRITE16:
  30.401 -    return FALSE;
  30.402 -  default:
  30.403 -    return FALSE;
  30.404 -  }
  30.405 -}
  30.406 -
  30.407 -static VOID
  30.408 -XenVbd_PutSrbOnList(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb) {
  30.409 -  srb_list_entry_t *srb_entry = srb->SrbExtension;
  30.410 -  srb_entry->srb = srb;
  30.411 -  srb_entry->outstanding_requests = 0;
  30.412 -  srb_entry->length = srb->DataTransferLength;
  30.413 -  srb_entry->offset = 0;
  30.414 -  srb_entry->error = FALSE;
  30.415 -  InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
  30.416 -}
  30.417 -
  30.418 -/* called with StartIoLock held */
  30.419 -/* returns TRUE if something was put on the ring and notify might be required */
  30.420 -static BOOLEAN
  30.421 -XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
  30.422 -{
  30.423 -  srb_list_entry_t *srb_entry = srb->SrbExtension;
  30.424 -  /* sector_number and block_count are the adjusted-to-512-byte-sector values */
  30.425 -  ULONGLONG sector_number;
  30.426 -  ULONG block_count;
  30.427 -  blkif_shadow_t *shadow;
  30.428 -  ULONG remaining, offset, length;
  30.429 -  grant_ref_t gref;
  30.430 -  PUCHAR ptr;
  30.431 -  int i;
  30.432 -  PVOID system_address;
  30.433 -
  30.434 -  //if (dump_mode) FUNCTION_ENTER();
  30.435 -
  30.436 -  //FUNCTION_MSG("aligned_buffer_in_use = %d\n", xvdd->aligned_buffer_in_use);
  30.437 -  //FUNCTION_MSG("shadow_free = %d\n", xvdd->shadow_free);
  30.438 -  
  30.439 -  NT_ASSERT(srb);
  30.440 -
  30.441 -  if (!dump_mode) {
  30.442 -    if (StorPortGetSystemAddress(xvdd, srb, &system_address) != STOR_STATUS_SUCCESS) {
  30.443 -      FUNCTION_MSG("Failed to map DataBuffer\n");
  30.444 -      InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
  30.445 -      return FALSE;
  30.446 -    }
  30.447 -    system_address = (PUCHAR)system_address + srb_entry->offset;
  30.448 -  } else {
  30.449 -    //KdPrint((__DRIVER_NAME "     DataBuffer = %p\n", srb->DataBuffer));
  30.450 -    system_address = (PUCHAR)srb->DataBuffer + srb_entry->offset;
  30.451 -  }
  30.452 -  block_count = decode_cdb_length(srb);
  30.453 -  sector_number = decode_cdb_sector(srb);
  30.454 -  block_count *= xvdd->bytes_per_sector / 512;
  30.455 -  sector_number *= xvdd->bytes_per_sector / 512;
  30.456 -
  30.457 -  NT_ASSERT(block_count * 512 == srb->DataTransferLength);
  30.458 -  
  30.459 -  sector_number += srb_entry->offset / 512;
  30.460 -  block_count -= srb_entry->offset / 512;
  30.461 -
  30.462 -  NT_ASSERT(block_count > 0);
  30.463 -
  30.464 -  /* look for pending writes that overlap this one */
  30.465 -  /* we get warnings from drbd if we don't */
  30.466 -  if (srb_entry->offset == 0) {
  30.467 -    for (i = 0; i < MAX_SHADOW_ENTRIES; i++) {
  30.468 -      PSCSI_REQUEST_BLOCK srb2;
  30.469 -      ULONGLONG sector_number2;
  30.470 -      ULONG block_count2;
  30.471 -      
  30.472 -      srb2 = xvdd->shadows[i].srb;
  30.473 -      if (!srb2)
  30.474 -        continue;
  30.475 -      if (decode_cdb_is_read(srb2))
  30.476 -        continue;
  30.477 -      block_count2 = decode_cdb_length(srb2);;
  30.478 -      block_count2 *= xvdd->bytes_per_sector / 512;
  30.479 -      sector_number2 = decode_cdb_sector(srb2);
  30.480 -      sector_number2 *= xvdd->bytes_per_sector / 512;
  30.481 -      
  30.482 -      if (sector_number < sector_number2 && sector_number + block_count <= sector_number2)
  30.483 -        continue;
  30.484 -      if (sector_number2 < sector_number && sector_number2 + block_count2 <= sector_number)
  30.485 -        continue;
  30.486 -
  30.487 -      KdPrint((__DRIVER_NAME "     Concurrent outstanding write detected (%I64d, %d) (%I64d, %d)\n",
  30.488 -        sector_number, block_count, sector_number2, block_count2));
  30.489 -      break;
  30.490 -    }
  30.491 -    if (i != MAX_SHADOW_ENTRIES) {
  30.492 -      /* put the srb back at the start of the queue */
  30.493 -      InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
  30.494 -      return FALSE;
  30.495 -    }
  30.496 -  }
  30.497 -  
  30.498 -  shadow = get_shadow_from_freelist(xvdd);
  30.499 -  if (!shadow) {
  30.500 -    /* put the srb back at the start of the queue */
  30.501 -    InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
  30.502 -    return FALSE;
  30.503 -  }
  30.504 -  NT_ASSERT(!shadow->aligned_buffer_in_use);
  30.505 -  NT_ASSERT(!shadow->srb);
  30.506 -  shadow->req.sector_number = sector_number;
  30.507 -  shadow->req.handle = 0;
  30.508 -  shadow->req.operation = decode_cdb_is_read(srb)?BLKIF_OP_READ:BLKIF_OP_WRITE;
  30.509 -  shadow->req.nr_segments = 0;
  30.510 -  shadow->srb = srb;
  30.511 -  shadow->length = 0;
  30.512 -  shadow->system_address = system_address;
  30.513 -  shadow->reset = FALSE;
  30.514 -
  30.515 -  if (!dump_mode) {
  30.516 -    if ((ULONG_PTR)shadow->system_address & 511) {
  30.517 -      xvdd->aligned_buffer_in_use = TRUE;
  30.518 -      /* limit to aligned_buffer_size */
  30.519 -      block_count = min(block_count, xvdd->aligned_buffer_size / 512);
  30.520 -      ptr = (PUCHAR)xvdd->aligned_buffer;
  30.521 -      if (!decode_cdb_is_read(srb))
  30.522 -        memcpy(ptr, shadow->system_address, block_count * 512);
  30.523 -      shadow->aligned_buffer_in_use = TRUE;
  30.524 -    } else {
  30.525 -      ptr = (PUCHAR)shadow->system_address;
  30.526 -      shadow->aligned_buffer_in_use = FALSE;
  30.527 -    }
  30.528 -  } else {
  30.529 -    NT_ASSERT(!((ULONG_PTR)shadow->system_address & 511));
  30.530 -    ptr = shadow->system_address;
  30.531 -    shadow->aligned_buffer_in_use = FALSE;
  30.532 -  }
  30.533 -
  30.534 -  //KdPrint((__DRIVER_NAME "     sector_number = %d, block_count = %d\n", (ULONG)sector_number, block_count));
  30.535 -  //KdPrint((__DRIVER_NAME "     DataBuffer   = %p\n", srb->DataBuffer));
  30.536 -  //KdPrint((__DRIVER_NAME "     system_address   = %p\n", shadow->system_address));
  30.537 -  //KdPrint((__DRIVER_NAME "     offset   = %d, length = %d\n", srb_entry->offset, srb_entry->length));
  30.538 -  //KdPrint((__DRIVER_NAME "     ptr   = %p\n", ptr));
  30.539 -
  30.540 -  //KdPrint((__DRIVER_NAME "     handle = %d\n", shadow->req.handle));
  30.541 -  //KdPrint((__DRIVER_NAME "     operation = %d\n", shadow->req.operation));
  30.542 -  
  30.543 -  remaining = block_count * 512;
  30.544 -  while (remaining > 0 && shadow->req.nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST) {
  30.545 -    PHYSICAL_ADDRESS physical_address;
  30.546 -
  30.547 -    if (!dump_mode) {
  30.548 -      physical_address = MmGetPhysicalAddress(ptr);
  30.549 -    } else {
  30.550 -      ULONG length;       
  30.551 -      physical_address = StorPortGetPhysicalAddress(xvdd, srb, ptr, &length);
  30.552 -    }
  30.553 -    gref = XnGrantAccess(xvdd->handle,
  30.554 -           (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, xvdd->grant_tag);
  30.555 -    if (gref == INVALID_GRANT_REF) {
  30.556 -      ULONG i;
  30.557 -      for (i = 0; i < shadow->req.nr_segments; i++) {
  30.558 -        XnEndAccess(xvdd->handle,
  30.559 -          shadow->req.seg[i].gref, FALSE, xvdd->grant_tag);
  30.560 -      }
  30.561 -      if (shadow->aligned_buffer_in_use) {
  30.562 -        shadow->aligned_buffer_in_use = FALSE;
  30.563 -        xvdd->aligned_buffer_in_use = FALSE;
  30.564 -      }
  30.565 -      /* put the srb back at the start of the queue */
  30.566 -      InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
  30.567 -      put_shadow_on_freelist(xvdd, shadow);
  30.568 -      KdPrint((__DRIVER_NAME "     Out of gref's. Deferring\n"));
  30.569 -      /* TODO: what if there are no requests currently in progress to kick the queue again?? timer? */
  30.570 -      return FALSE;
  30.571 -    }
  30.572 -    offset = physical_address.LowPart & (PAGE_SIZE - 1);
  30.573 -    length = min(PAGE_SIZE - offset, remaining);
  30.574 -    NT_ASSERT((offset & 511) == 0);
  30.575 -    NT_ASSERT((length & 511) == 0);
  30.576 -    NT_ASSERT(offset + length <= PAGE_SIZE);
  30.577 -    shadow->req.seg[shadow->req.nr_segments].gref = gref;
  30.578 -    shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset / 512);
  30.579 -    shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) / 512) - 1);
  30.580 -    remaining -= length;
  30.581 -    ptr += length;
  30.582 -    shadow->length += length;
  30.583 -    shadow->req.nr_segments++;
  30.584 -  }
  30.585 -  srb_entry->offset += shadow->length;
  30.586 -  srb_entry->outstanding_requests++;
  30.587 -  if (srb_entry->offset < srb_entry->length) {
  30.588 -    if (dump_mode) KdPrint((__DRIVER_NAME "     inserting back into list\n"));
  30.589 -    /* put the srb back at the start of the queue to continue on the next request */
  30.590 -    InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
  30.591 -  }
  30.592 -  XenVbd_PutRequest(xvdd, &shadow->req);
  30.593 -  return TRUE;
  30.594 -  //FUNCTION_EXIT();
  30.595 -}
  30.596 -
  30.597 -static VOID
  30.598 -XenVbd_BackendStateCallback(PVOID context, ULONG state) {
  30.599 -  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)context;
  30.600 -  PCHAR mode;
  30.601 -  PCHAR device_type;
  30.602 -  PFN_NUMBER pfn;
  30.603 -  ULONG status;
  30.604 -  BOOLEAN active = FALSE;
  30.605 -  BOOLEAN qemu_hide_filter = FALSE;
  30.606 -  ULONG qemu_hide_flags_value = 0;
  30.607 -  STOR_LOCK_HANDLE lock_handle;
  30.608 - 
  30.609 -  FUNCTION_ENTER();
  30.610 -  if (state == xvdd->backend_state) {
  30.611 -    FUNCTION_MSG("same state %d\n", state);
  30.612 -    FUNCTION_EXIT();
  30.613 -  }
  30.614 -  FUNCTION_MSG("XenbusState = %d -> %d\n", xvdd->backend_state, state);
  30.615 -  
  30.616 -  switch (state) {
  30.617 -  case XenbusStateUnknown:
  30.618 -    break;
  30.619 -
  30.620 -  case XenbusStateInitialising:
  30.621 -  case XenbusStateInitWait:
  30.622 -  case XenbusStateInitialised:
  30.623 -    FUNCTION_MSG("XenbusState Initialising/InitWait/Initialised\n");
  30.624 -    if (xvdd->frontend_state != XenbusStateInitialised) {
  30.625 -      xvdd->frontend_state = XenbusStateInitialised;
  30.626 -      xvdd->event_channel = XnAllocateEvent(xvdd->handle);
  30.627 -      if (!xvdd->event_channel) {
  30.628 -        // !!PANIC!!
  30.629 -      }
  30.630 -      FUNCTION_MSG("event_channel = %d\n", xvdd->event_channel);
  30.631 -      status = XnBindEvent(xvdd->handle, xvdd->event_channel, XenVbd_HandleEventDIRQL, xvdd);
  30.632 -      status = XnWriteInt32(xvdd->handle, XN_BASE_FRONTEND, "event-channel", xvdd->event_channel);
  30.633 -      xvdd->sring = (blkif_sring_t *)ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENVBD_POOL_TAG);
  30.634 -      if (!xvdd->sring) {
  30.635 -        // !!PANIC!!
  30.636 -      }
  30.637 -      FUNCTION_MSG("sring = %p\n", xvdd->sring);
  30.638 -      SHARED_RING_INIT(xvdd->sring);
  30.639 -      FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE);
  30.640 -      pfn = MmGetPhysicalAddress(xvdd->sring).QuadPart >> PAGE_SHIFT;
  30.641 -      FUNCTION_MSG("sring pfn = %d\n", (ULONG)pfn);
  30.642 -      xvdd->sring_gref = XnGrantAccess(xvdd->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, xvdd->grant_tag);
  30.643 -      FUNCTION_MSG("sring_gref = %d\n", xvdd->sring_gref);
  30.644 -      status = XnWriteInt32(xvdd->handle, XN_BASE_FRONTEND, "ring-ref", xvdd->sring_gref);
  30.645 -      status = XnWriteString(xvdd->handle, XN_BASE_FRONTEND, "protocol", ABI_PROTOCOL);
  30.646 -      status = XnWriteInt32(xvdd->handle, XN_BASE_FRONTEND, "state", XenbusStateInitialised);
  30.647 -    }
  30.648 -    break;
  30.649 -
  30.650 -  case XenbusStateConnected:
  30.651 -    FUNCTION_MSG("XenbusState Connected\n");
  30.652 -    if (xvdd->frontend_state != XenbusStateConnected) {
  30.653 -      xvdd->frontend_state = XenbusStateConnected;
  30.654 -      status = XnReadInt64(xvdd->handle, XN_BASE_BACKEND, "sectors", &xvdd->total_sectors);
  30.655 -      status = XnReadInt32(xvdd->handle, XN_BASE_BACKEND, "sector-size", &xvdd->hw_bytes_per_sector);
  30.656 -      if (xvdd->device_type == XENVBD_DEVICETYPE_CDROM) {
  30.657 -        /* CD/DVD drives must have bytes_per_sector = 2048. */
  30.658 -        xvdd->bytes_per_sector = 2048;
  30.659 -        xvdd->hw_bytes_per_sector = 2048;
  30.660 -      } else {
  30.661 -        xvdd->bytes_per_sector = 512;
  30.662 -      }
  30.663 -      /* for some reason total_sectors is measured in 512 byte sectors always, so correct this to be in bytes_per_sectors */
  30.664 -      xvdd->total_sectors /= xvdd->bytes_per_sector / 512;
  30.665 -      status = XnReadInt32(xvdd->handle, XN_BASE_BACKEND, "feature-barrier", &xvdd->feature_barrier);
  30.666 -      status = XnReadInt32(xvdd->handle, XN_BASE_BACKEND, "feature-discard", &xvdd->feature_discard);
  30.667 -      status = XnReadInt32(xvdd->handle, XN_BASE_BACKEND, "feature-flush-cache", &xvdd->feature_flush_cache);
  30.668 -      status = XnReadString(xvdd->handle, XN_BASE_BACKEND, "mode", &mode);
  30.669 -      if (strncmp(mode, "r", 1) == 0) {
  30.670 -        FUNCTION_MSG("mode = r\n");
  30.671 -        xvdd->device_mode = XENVBD_DEVICEMODE_READ;
  30.672 -      } else if (strncmp(mode, "w", 1) == 0) {
  30.673 -        FUNCTION_MSG("mode = w\n");    
  30.674 -        xvdd->device_mode = XENVBD_DEVICEMODE_WRITE;
  30.675 -      } else {
  30.676 -        FUNCTION_MSG("mode = unknown\n");
  30.677 -        xvdd->device_mode = XENVBD_DEVICEMODE_UNKNOWN;
  30.678 -      }
  30.679 -      XnFreeMem(xvdd->handle, mode);
  30.680 -
  30.681 -      // read device-type
  30.682 -      status = XnReadString(xvdd->handle, XN_BASE_FRONTEND, "device-type", &device_type);
  30.683 -      if (strcmp(device_type, "disk") == 0) {
  30.684 -        FUNCTION_MSG("device-type = Disk\n");    
  30.685 -        xvdd->device_type = XENVBD_DEVICETYPE_DISK;
  30.686 -      } else if (strcmp(device_type, "cdrom") == 0) {
  30.687 -        FUNCTION_MSG("device-type = CDROM\n");    
  30.688 -        xvdd->device_type = XENVBD_DEVICETYPE_CDROM;
  30.689 -      } else {
  30.690 -        FUNCTION_MSG("device-type = %s (This probably won't work!)\n", device_type);
  30.691 -        xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
  30.692 -      }
  30.693 -      XnFreeMem(xvdd->handle, device_type);
  30.694 -      status = XnWriteInt32(xvdd->handle, XN_BASE_FRONTEND, "state", XenbusStateConnected);
  30.695 -      // check that everything is good
  30.696 -      XnGetValue(xvdd->handle, XN_VALUE_TYPE_QEMU_HIDE_FLAGS, &qemu_hide_flags_value);
  30.697 -      XnGetValue(xvdd->handle, XN_VALUE_TYPE_QEMU_FILTER, &qemu_hide_filter);
  30.698 -
  30.699 -      if (((qemu_hide_flags_value & QEMU_UNPLUG_ALL_IDE_DISKS) && xvdd->device_type != XENVBD_DEVICETYPE_CDROM) || qemu_hide_filter)
  30.700 -        active = TRUE;
  30.701 -
  30.702 -      if (active && (xvdd->device_type == XENVBD_DEVICETYPE_UNKNOWN
  30.703 -          || xvdd->sring == NULL
  30.704 -          || xvdd->event_channel == 0
  30.705 -          || xvdd->total_sectors == 0
  30.706 -          || xvdd->hw_bytes_per_sector == 0)) {
  30.707 -        FUNCTION_MSG("Missing settings\n");
  30.708 -        active = FALSE;
  30.709 -      }
  30.710 -
  30.711 -      if (active)
  30.712 -        xvdd->vbd_status = VBD_STATUS_ACTIVE;
  30.713 -      else
  30.714 -        xvdd->vbd_status = VBD_STATUS_INACTIVE;
  30.715 -      StorPortAcquireSpinLock(xvdd, StartIoLock, NULL, &lock_handle);
  30.716 -      XenVbd_ProcessSrbList(xvdd);
  30.717 -      StorPortReleaseSpinLock(xvdd, &lock_handle);
  30.718 -    }
  30.719 -    break;
  30.720 -
  30.721 -  case XenbusStateClosing:
  30.722 -    break;
  30.723 -
  30.724 -  case XenbusStateClosed:
  30.725 -    break;
  30.726 -  
  30.727 -  default:
  30.728 -    break;
  30.729 -  }
  30.730 -  xvdd->backend_state = state;
  30.731 -  FUNCTION_EXIT();
  30.732 -}
  30.733 -
  30.734 -/* called in non-dump mode */
  30.735 -static ULONG
  30.736 -XenVbd_VirtualHwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PVOID LowerDevice, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
  30.737 -{
  30.738 -  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
  30.739 -
  30.740 -  //UNREFERENCED_PARAMETER(HwContext);
  30.741 -  UNREFERENCED_PARAMETER(BusInformation);
  30.742 -  UNREFERENCED_PARAMETER(LowerDevice);
  30.743 -  UNREFERENCED_PARAMETER(ArgumentString);
  30.744 -
  30.745 -  FUNCTION_ENTER(); 
  30.746 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  30.747 -  KdPrint((__DRIVER_NAME "     xvdd = %p\n", xvdd));
  30.748 -
  30.749 -  if (XnGetVersion() != 1) {
  30.750 -    FUNCTION_MSG("Wrong XnGetVersion\n");
  30.751 -    FUNCTION_EXIT();
  30.752 -    return SP_RETURN_BAD_CONFIG;
  30.753 -  }
  30.754 -
  30.755 -  RtlZeroMemory(xvdd, sizeof(XENVBD_DEVICE_DATA));
  30.756 -  InitializeListHead(&xvdd->srb_list);
  30.757 -  xvdd->pdo = (PDEVICE_OBJECT)HwContext;
  30.758 -  /* this shouldn't race because nothing will be on the srb queue yet */
  30.759 -  if ((xvdd->handle = XnOpenDevice(xvdd->pdo, XenVbd_BackendStateCallback, xvdd)) == NULL) {
  30.760 -    return SP_RETURN_BAD_CONFIG;
  30.761 -  }
  30.762 -
  30.763 -  xvdd->aligned_buffer_in_use = FALSE;
  30.764 -  /* align the buffer to PAGE_SIZE */
  30.765 -  xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
  30.766 -  KdPrint((__DRIVER_NAME "     aligned_buffer_data = %p\n", xvdd->aligned_buffer_data));
  30.767 -  KdPrint((__DRIVER_NAME "     aligned_buffer = %p\n", xvdd->aligned_buffer));
  30.768 -
  30.769 -  ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
  30.770 -  ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
  30.771 -  FUNCTION_MSG("ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength);
  30.772 -  FUNCTION_MSG("ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks);
  30.773 -  if (!dump_mode) {
  30.774 -    ConfigInfo->VirtualDevice = TRUE;
  30.775 -    xvdd->aligned_buffer_size = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
  30.776 -  } else {
  30.777 -    ConfigInfo->VirtualDevice = FALSE;
  30.778 -    xvdd->aligned_buffer_size = DUMP_MODE_UNALIGNED_PAGES * PAGE_SIZE;
  30.779 -  }
  30.780 -  
  30.781 -  FUNCTION_MSG("ConfigInfo->VirtualDevice = %d\n", ConfigInfo->VirtualDevice);
  30.782 -  ConfigInfo->ScatterGather = TRUE;
  30.783 -  ConfigInfo->Master = TRUE;
  30.784 -  ConfigInfo->CachesData = FALSE;
  30.785 -  ConfigInfo->MapBuffers = STOR_MAP_ALL_BUFFERS;
  30.786 -  FUNCTION_MSG("ConfigInfo->NeedPhysicalAddresses = %d\n", ConfigInfo->NeedPhysicalAddresses);
  30.787 -  ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
  30.788 -  ConfigInfo->AlignmentMask = 0;
  30.789 -  ConfigInfo->NumberOfBuses = 1;
  30.790 -  ConfigInfo->InitiatorBusId[0] = 1;
  30.791 -  ConfigInfo->MaximumNumberOfLogicalUnits = 1;
  30.792 -  ConfigInfo->MaximumNumberOfTargets = 2;
  30.793 -  if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) {
  30.794 -    ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
  30.795 -    FUNCTION_MSG("Dma64BitAddresses supported\n");
  30.796 -  } else {
  30.797 -    FUNCTION_MSG("Dma64BitAddresses not supported\n");
  30.798 -  }
  30.799 -  *Again = FALSE;
  30.800 -
  30.801 -  FUNCTION_EXIT();
  30.802 -
  30.803 -  return SP_RETURN_FOUND;
  30.804 -}
  30.805 -
  30.806 -/* called in dump mode */
  30.807 -static ULONG
  30.808 -XenVbd_HwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
  30.809 -{
  30.810 -  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
  30.811 -
  30.812 -  UNREFERENCED_PARAMETER(HwContext);
  30.813 -  UNREFERENCED_PARAMETER(BusInformation);
  30.814 -  UNREFERENCED_PARAMETER(ArgumentString);
  30.815 -  
  30.816 -  FUNCTION_ENTER();
  30.817 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  30.818 -  KdPrint((__DRIVER_NAME "     xvdd = %p\n", xvdd));
  30.819 -
  30.820 -  memcpy(xvdd, ConfigInfo->Reserved, FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data));
  30.821 -  xvdd->aligned_buffer_in_use = FALSE;
  30.822 -  /* align the buffer to PAGE_SIZE */
  30.823 -  xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
  30.824 -  KdPrint((__DRIVER_NAME "     aligned_buffer_data = %p\n", xvdd->aligned_buffer_data));
  30.825 -  KdPrint((__DRIVER_NAME "     aligned_buffer = %p\n", xvdd->aligned_buffer));
  30.826 -
  30.827 -  ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024;
  30.828 -  ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT;
  30.829 -  FUNCTION_MSG("ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength);
  30.830 -  FUNCTION_MSG("ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks);
  30.831 -  ConfigInfo->VirtualDevice = FALSE;
  30.832 -  xvdd->aligned_buffer_size = DUMP_MODE_UNALIGNED_PAGES * PAGE_SIZE;
  30.833 -  ConfigInfo->ScatterGather = TRUE;
  30.834 -  ConfigInfo->Master = TRUE;
  30.835 -  ConfigInfo->CachesData = FALSE;
  30.836 -  ConfigInfo->MapBuffers = STOR_MAP_ALL_BUFFERS;
  30.837 -  FUNCTION_MSG("ConfigInfo->NeedPhysicalAddresses = %d\n", ConfigInfo->NeedPhysicalAddresses);
  30.838 -  ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
  30.839 -  ConfigInfo->AlignmentMask = 0;
  30.840 -  ConfigInfo->NumberOfBuses = 1;
  30.841 -  ConfigInfo->InitiatorBusId[0] = 1;
  30.842 -  ConfigInfo->MaximumNumberOfLogicalUnits = 1;
  30.843 -  ConfigInfo->MaximumNumberOfTargets = 2;
  30.844 -  if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) {
  30.845 -    ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
  30.846 -    FUNCTION_MSG("Dma64BitAddresses supported\n");
  30.847 -  } else {
  30.848 -    FUNCTION_MSG("Dma64BitAddresses not supported\n");
  30.849 -  }
  30.850 -  *Again = FALSE;
  30.851 -
  30.852 -  FUNCTION_EXIT();
  30.853 -
  30.854 -  return SP_RETURN_FOUND;
  30.855 -}
  30.856 -
  30.857 -/* Called at PASSIVE_LEVEL for non-dump mode */
  30.858 -static BOOLEAN
  30.859 -XenVbd_HwStorInitialize(PVOID DeviceExtension)
  30.860 -{
  30.861 -  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
  30.862 -  int i;
  30.863 -  
  30.864 -  FUNCTION_ENTER();
  30.865 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  30.866 -  KdPrint((__DRIVER_NAME "     dump_mode = %d\n", dump_mode));
  30.867 -  
  30.868 -  xvdd->shadow_free = 0;
  30.869 -  memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
  30.870 -  for (i = 0; i < SHADOW_ENTRIES; i++) {
  30.871 -    xvdd->shadows[i].req.id = i;
  30.872 -    /* make sure leftover real requests's are never confused with dump mode requests */
  30.873 -    if (dump_mode)
  30.874 -      xvdd->shadows[i].req.id |= SHADOW_ID_DUMP_FLAG;
  30.875 -    put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
  30.876 -  }
  30.877 -
  30.878 -  if (!dump_mode) {
  30.879 -    StorPortInitializeDpc(DeviceExtension, &xvdd->dpc, XenVbd_HandleEventDpc);
  30.880 -  } else {
  30.881 -    xvdd->grant_tag = (ULONG)'DUMP';
  30.882 -  }
  30.883 -  
  30.884 -  FUNCTION_EXIT();
  30.885 -
  30.886 -  return TRUE;
  30.887 -}
  30.888 -
  30.889 -static ULONG
  30.890 -XenVbd_FillModePage(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
  30.891 -{
  30.892 -  PMODE_PARAMETER_HEADER parameter_header = NULL;
  30.893 -  PMODE_PARAMETER_HEADER10 parameter_header10 = NULL;
  30.894 -  PMODE_PARAMETER_BLOCK param_block;
  30.895 -  PMODE_FORMAT_PAGE format_page;
  30.896 -  ULONG offset = 0;
  30.897 -  UCHAR buffer[1024];
  30.898 -  BOOLEAN valid_page = FALSE;
  30.899 -  BOOLEAN cdb_llbaa;
  30.900 -  BOOLEAN cdb_dbd;
  30.901 -  UCHAR cdb_page_code;
  30.902 -  USHORT cdb_allocation_length;
  30.903 -
  30.904 -  UNREFERENCED_PARAMETER(xvdd);
  30.905 -
  30.906 -  RtlZeroMemory(srb->DataBuffer, srb->DataTransferLength);
  30.907 -  RtlZeroMemory(buffer, ARRAY_SIZE(buffer));
  30.908 -  offset = 0;
  30.909 -
  30.910 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  30.911 -  
  30.912 -  switch (srb->Cdb[0])
  30.913 -  {
  30.914 -  case SCSIOP_MODE_SENSE:
  30.915 -    cdb_llbaa = FALSE;
  30.916 -    cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
  30.917 -    cdb_page_code = srb->Cdb[2] & 0x3f;
  30.918 -    cdb_allocation_length = srb->Cdb[4];
  30.919 -    KdPrint((__DRIVER_NAME "     SCSIOP_MODE_SENSE llbaa = %d, dbd = %d, page_code = %d, allocation_length = %d\n",
  30.920 -      cdb_llbaa, cdb_dbd, cdb_page_code, cdb_allocation_length));
  30.921 -    parameter_header = (PMODE_PARAMETER_HEADER)&buffer[offset];
  30.922 -    parameter_header->MediumType = 0;
  30.923 -    parameter_header->DeviceSpecificParameter = 0;
  30.924 -    if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
  30.925 -    {
  30.926 -      KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
  30.927 -      parameter_header->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT; 
  30.928 -    }
  30.929 -    offset += sizeof(MODE_PARAMETER_HEADER);
  30.930 -    break;
  30.931 -  case SCSIOP_MODE_SENSE10:
  30.932 -    cdb_llbaa = (BOOLEAN)!!(srb->Cdb[1] & 16);
  30.933 -    cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
  30.934 -    cdb_page_code = srb->Cdb[2] & 0x3f;
  30.935 -    cdb_allocation_length = (srb->Cdb[7] << 8) | srb->Cdb[8];
  30.936 -    KdPrint((__DRIVER_NAME "     SCSIOP_MODE_SENSE10 llbaa = %d, dbd = %d, page_code = %d, allocation_length = %d\n",
  30.937 -      cdb_llbaa, cdb_dbd, cdb_page_code, cdb_allocation_length));
  30.938 -    parameter_header10 = (PMODE_PARAMETER_HEADER10)&buffer[offset];
  30.939 -    parameter_header10->MediumType = 0;
  30.940 -    parameter_header10->DeviceSpecificParameter = 0;
  30.941 -    if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
  30.942 -    {
  30.943 -      KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
  30.944 -      parameter_header10->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT; 
  30.945 -    }
  30.946 -    offset += sizeof(MODE_PARAMETER_HEADER10);
  30.947 -    break;
  30.948 -  default:
  30.949 -    KdPrint((__DRIVER_NAME "     SCSIOP_MODE_SENSE_WTF (%02x)\n", (ULONG)srb->Cdb[0]));
  30.950 -    return FALSE;
  30.951 -  }  
  30.952 -  
  30.953 -  if (!cdb_dbd)
  30.954 -  {
  30.955 -    param_block = (PMODE_PARAMETER_BLOCK)&buffer[offset];
  30.956 -    if (xvdd->device_type == XENVBD_DEVICETYPE_DISK)
  30.957 -    {
  30.958 -      if (xvdd->total_sectors >> 32) 
  30.959 -      {
  30.960 -        param_block->DensityCode = 0xff;
  30.961 -        param_block->NumberOfBlocks[0] = 0xff;
  30.962 -        param_block->NumberOfBlocks[1] = 0xff;
  30.963 -        param_block->NumberOfBlocks[2] = 0xff;
  30.964 -      }
  30.965 -      else
  30.966 -      {
  30.967 -        param_block->DensityCode = (UCHAR)((xvdd->total_sectors >> 24) & 0xff);
  30.968 -        param_block->NumberOfBlocks[0] = (UCHAR)((xvdd->total_sectors >> 16) & 0xff);
  30.969 -        param_block->NumberOfBlocks[1] = (UCHAR)((xvdd->total_sectors >> 8) & 0xff);
  30.970 -        param_block->NumberOfBlocks[2] = (UCHAR)((xvdd->total_sectors >> 0) & 0xff);
  30.971 -      }
  30.972 -      param_block->BlockLength[0] = (UCHAR)((xvdd->bytes_per_sector >> 16) & 0xff);
  30.973 -      param_block->BlockLength[1] = (UCHAR)((xvdd->bytes_per_sector >> 8) & 0xff);
  30.974 -      param_block->BlockLength[2] = (UCHAR)((xvdd->bytes_per_sector >> 0) & 0xff);
  30.975 -    }
  30.976 -    offset += sizeof(MODE_PARAMETER_BLOCK);
  30.977 -  }
  30.978 -  switch (srb->Cdb[0])
  30.979 -  {
  30.980 -  case SCSIOP_MODE_SENSE:
  30.981 -    parameter_header->BlockDescriptorLength = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER));
  30.982 -    break;
  30.983 -  case SCSIOP_MODE_SENSE10:
  30.984 -    parameter_header10->BlockDescriptorLength[0] = (UCHAR)((offset - sizeof(MODE_PARAMETER_HEADER10)) >> 8);
  30.985 -    parameter_header10->BlockDescriptorLength[1] = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER10));
  30.986 -    break;
  30.987 -  }
  30.988 -  if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_FORMAT_DEVICE || cdb_page_code == MODE_SENSE_RETURN_ALL))
  30.989 -  {
  30.990 -    valid_page = TRUE;
  30.991 -    format_page = (PMODE_FORMAT_PAGE)&buffer[offset];
  30.992 -    format_page->PageCode = MODE_PAGE_FORMAT_DEVICE;
  30.993 -    format_page->PageLength = sizeof(MODE_FORMAT_PAGE) - FIELD_OFFSET(MODE_FORMAT_PAGE, PageLength);
  30.994 -    /* 256 sectors per track */
  30.995 -    format_page->SectorsPerTrack[0] = 0x01;
  30.996 -    format_page->SectorsPerTrack[1] = 0x00;
  30.997 -    /* xxx bytes per sector */
  30.998 -    format_page->BytesPerPhysicalSector[0] = (UCHAR)(xvdd->bytes_per_sector >> 8);
  30.999 -    format_page->BytesPerPhysicalSector[1] = (UCHAR)(xvdd->bytes_per_sector & 0xff);
 30.1000 -    format_page->HardSectorFormating = TRUE;
 30.1001 -    format_page->SoftSectorFormating = TRUE;
 30.1002 -    offset += sizeof(MODE_FORMAT_PAGE);
 30.1003 -  }
 30.1004 -  if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_CACHING || cdb_page_code == MODE_SENSE_RETURN_ALL))
 30.1005 -  {
 30.1006 -    PMODE_CACHING_PAGE caching_page;
 30.1007 -    valid_page = TRUE;
 30.1008 -    caching_page = (PMODE_CACHING_PAGE)&buffer[offset];
 30.1009 -    caching_page->PageCode = MODE_PAGE_CACHING;
 30.1010 -    caching_page->PageLength = sizeof(MODE_CACHING_PAGE) - FIELD_OFFSET(MODE_CACHING_PAGE, PageLength);
 30.1011 -    // caching_page-> // all zeros is just fine... maybe
 30.1012 -    offset += sizeof(MODE_CACHING_PAGE);
 30.1013 -  }
 30.1014 -  if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_MEDIUM_TYPES || cdb_page_code == MODE_SENSE_RETURN_ALL))
 30.1015 -  {
 30.1016 -    PUCHAR medium_types_page;
 30.1017 -    valid_page = TRUE;
 30.1018 -    medium_types_page = &buffer[offset];
 30.1019 -    medium_types_page[0] = MODE_PAGE_MEDIUM_TYPES;
 30.1020 -    medium_types_page[1] = 0x06;
 30.1021 -    medium_types_page[2] = 0;
 30.1022 -    medium_types_page[3] = 0;
 30.1023 -    medium_types_page[4] = 0;
 30.1024 -    medium_types_page[5] = 0;
 30.1025 -    medium_types_page[6] = 0;
 30.1026 -    medium_types_page[7] = 0;
 30.1027 -    offset += 8;
 30.1028 -  }
 30.1029 -  switch (srb->Cdb[0])
 30.1030 -  {
 30.1031 -  case SCSIOP_MODE_SENSE:
 30.1032 -    parameter_header->ModeDataLength = (UCHAR)(offset - 1);
 30.1033 -    break;
 30.1034 -  case SCSIOP_MODE_SENSE10:
 30.1035 -    parameter_header10->ModeDataLength[0] = (UCHAR)((offset - 2) >> 8);
 30.1036 -    parameter_header10->ModeDataLength[1] = (UCHAR)(offset - 2);
 30.1037 -    break;
 30.1038 -  }
 30.1039 -
 30.1040 -  if (!valid_page && cdb_page_code != MODE_SENSE_RETURN_ALL)
 30.1041 -  {
 30.1042 -    srb->SrbStatus = SRB_STATUS_ERROR;
 30.1043 -  }
 30.1044 -  else if(offset < srb->DataTransferLength)
 30.1045 -    srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
 30.1046 -  else
 30.1047 -    srb->SrbStatus = SRB_STATUS_SUCCESS;
 30.1048 -  srb->DataTransferLength = min(srb->DataTransferLength, offset);
 30.1049 -  srb->ScsiStatus = 0;
 30.1050 -  memcpy(srb->DataBuffer, buffer, srb->DataTransferLength);
 30.1051 -  
 30.1052 -  //FUNCTION_EXIT();
 30.1053 -
 30.1054 -  return TRUE;
 30.1055 -}
 30.1056 -
 30.1057 -static ULONG
 30.1058 -XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, UCHAR sense_key, UCHAR additional_sense_code)
 30.1059 -{
 30.1060 -  PSENSE_DATA sd = srb->SenseInfoBuffer;
 30.1061 - 
 30.1062 -  UNREFERENCED_PARAMETER(xvdd);
 30.1063 -  
 30.1064 -  if (!srb->SenseInfoBuffer)
 30.1065 -    return 0;
 30.1066 -  
 30.1067 -  sd->ErrorCode = 0x70;
 30.1068 -  sd->Valid = 1;
 30.1069 -  sd->SenseKey = sense_key;
 30.1070 -  sd->AdditionalSenseLength = sizeof(SENSE_DATA) - FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
 30.1071 -  sd->AdditionalSenseCode = additional_sense_code;
 30.1072 -  return sizeof(SENSE_DATA);
 30.1073 -}
 30.1074 -
 30.1075 -static VOID
 30.1076 -XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
 30.1077 -{
 30.1078 -  if (srb->SrbStatus == SRB_STATUS_SUCCESS || srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)
 30.1079 -    return;
 30.1080 -  XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
 30.1081 -  srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
 30.1082 -}
 30.1083 -
 30.1084 -/* called with StartIo lock held */
 30.1085 -static VOID
 30.1086 -XenVbd_HandleEvent(PVOID DeviceExtension)
 30.1087 -{
 30.1088 -  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
 30.1089 -  PSCSI_REQUEST_BLOCK srb;
 30.1090 -  RING_IDX i, rp;
 30.1091 -  ULONG j;
 30.1092 -  blkif_response_t *rep;
 30.1093 -  //int block_count;
 30.1094 -  int more_to_do = TRUE;
 30.1095 -  blkif_shadow_t *shadow;
 30.1096 -  //ULONG suspend_resume_state_pdo;
 30.1097 -  srb_list_entry_t *srb_entry;
 30.1098 -
 30.1099 -  //if (dump_mode) FUNCTION_ENTER();
 30.1100 -
 30.1101 -#if 0
 30.1102 -  suspend_resume_state_pdo = xvdd->device_state->suspend_resume_state_pdo;
 30.1103 -  KeMemoryBarrier();
 30.1104 -
 30.1105 -  if (suspend_resume_state_pdo != xvdd->device_state->suspend_resume_state_fdo)
 30.1106 -  {
 30.1107 -    //FUNCTION_ENTER();
 30.1108 -    switch (suspend_resume_state_pdo)
 30.1109 -    {
 30.1110 -      case SR_STATE_SUSPENDING:
 30.1111 -        KdPrint((__DRIVER_NAME "     New pdo state SR_STATE_SUSPENDING\n"));
 30.1112 -        break;
 30.1113 -      case SR_STATE_RESUMING:
 30.1114 -        KdPrint((__DRIVER_NAME "     New pdo state SR_STATE_RESUMING\n"));
 30.1115 -        XenVbd_InitFromConfig(xvdd);
 30.1116 -        xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
 30.1117 -        xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
 30.1118 -        break;
 30.1119 -      case SR_STATE_RUNNING:
 30.1120 -        KdPrint((__DRIVER_NAME "     New pdo state %d\n", suspend_resume_state_pdo));
 30.1121 -        xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
 30.1122 -        xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
 30.1123 -      default:
 30.1124 -        KdPrint((__DRIVER_NAME "     New pdo state %d\n", suspend_resume_state_pdo));
 30.1125 -        xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
 30.1126 -        xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
 30.1127 -        break;
 30.1128 -    }
 30.1129 -    KeMemoryBarrier();
 30.1130 -  }
 30.1131 -#endif
 30.1132 -
 30.1133 -#if 0
 30.1134 -  if (xvdd->device_state->suspend_resume_state_fdo != SR_STATE_RUNNING)
 30.1135 -  {
 30.1136 -    return TRUE;
 30.1137 -  }
 30.1138 -#endif
 30.1139 -
 30.1140 -  while (more_to_do)
 30.1141 -  {
 30.1142 -    rp = xvdd->ring.sring->rsp_prod;
 30.1143 -    KeMemoryBarrier();
 30.1144 -    for (i = xvdd->ring.rsp_cons; i != rp; i++)
 30.1145 -    {
 30.1146 -      rep = XenVbd_GetResponse(xvdd, i);
 30.1147 -      shadow = &xvdd->shadows[rep->id & SHADOW_ID_ID_MASK];
 30.1148 -      if (shadow->reset)
 30.1149 -      {
 30.1150 -        KdPrint((__DRIVER_NAME "     discarding reset shadow\n"));
 30.1151 -        for (j = 0; j < shadow->req.nr_segments; j++)
 30.1152 -        {
 30.1153 -          XnEndAccess(xvdd->handle,
 30.1154 -            shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
 30.1155 -        }
 30.1156 -      }
 30.1157 -      else if (dump_mode && !(rep->id & SHADOW_ID_DUMP_FLAG))
 30.1158 -      {
 30.1159 -        KdPrint((__DRIVER_NAME "     discarding stale (non-dump-mode) shadow\n"));
 30.1160 -      }
 30.1161 -      else
 30.1162 -      {
 30.1163 -        srb = shadow->srb;
 30.1164 -        NT_ASSERT(srb);
 30.1165 -        srb_entry = srb->SrbExtension;
 30.1166 -        NT_ASSERT(srb_entry);
 30.1167 -        /* a few errors occur in dump mode because Xen refuses to allow us to map pages we are using for other stuff. Just ignore them */
 30.1168 -        if (rep->status == BLKIF_RSP_OKAY || (dump_mode &&  dump_mode_errors++ < DUMP_MODE_ERROR_LIMIT))
 30.1169 -          srb->SrbStatus = SRB_STATUS_SUCCESS;
 30.1170 -        else
 30.1171 -        {
 30.1172 -          KdPrint((__DRIVER_NAME "     Xen Operation returned error\n"));
 30.1173 -          if (decode_cdb_is_read(srb))
 30.1174 -            KdPrint((__DRIVER_NAME "     Operation = Read\n"));
 30.1175 -          else
 30.1176 -            KdPrint((__DRIVER_NAME "     Operation = Write\n"));
 30.1177 -          srb_entry->error = TRUE;
 30.1178 -        }
 30.1179 -        if (shadow->aligned_buffer_in_use)
 30.1180 -        {
 30.1181 -          NT_ASSERT(xvdd->aligned_buffer_in_use);
 30.1182 -          xvdd->aligned_buffer_in_use = FALSE;
 30.1183 -          if (srb->SrbStatus == SRB_STATUS_SUCCESS && decode_cdb_is_read(srb))
 30.1184 -            memcpy((PUCHAR)shadow->system_address, xvdd->aligned_buffer, shadow->length);
 30.1185 -        }
 30.1186 -        for (j = 0; j < shadow->req.nr_segments; j++)
 30.1187 -        {
 30.1188 -          XnEndAccess(xvdd->handle, shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
 30.1189 -        }
 30.1190 -        srb_entry->outstanding_requests--;
 30.1191 -        if (!srb_entry->outstanding_requests && srb_entry->offset == srb_entry->length)
 30.1192 -        {
 30.1193 -          if (srb_entry->error)
 30.1194 -          {
 30.1195 -            srb->SrbStatus = SRB_STATUS_ERROR;
 30.1196 -            srb->ScsiStatus = 0x02;
 30.1197 -            xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
 30.1198 -            xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
 30.1199 -            XenVbd_MakeAutoSense(xvdd, srb);
 30.1200 -          }        
 30.1201 -          StorPortNotification(RequestComplete, xvdd, srb);
 30.1202 -        }
 30.1203 -      }
 30.1204 -      put_shadow_on_freelist(xvdd, shadow);
 30.1205 -    }
 30.1206 -
 30.1207 -    xvdd->ring.rsp_cons = i;
 30.1208 -    if (i != xvdd->ring.req_prod_pvt)
 30.1209 -    {
 30.1210 -      RING_FINAL_CHECK_FOR_RESPONSES(&xvdd->ring, more_to_do);
 30.1211 -    }
 30.1212 -    else
 30.1213 -    {
 30.1214 -      xvdd->ring.sring->rsp_event = i + 1;
 30.1215 -      more_to_do = FALSE;
 30.1216 -    }
 30.1217 -  }
 30.1218 -
 30.1219 -  XenVbd_ProcessSrbList(xvdd);
 30.1220 -#if 0
 30.1221 -  if (suspend_resume_state_pdo == SR_STATE_SUSPENDING)
 30.1222 -  {
 30.1223 -    if ((xvdd->vbd_status == VBD_STATUS_ACTIVE) || xvdd->shadow_free == SHADOW_ENTRIES)
 30.1224 -    {
 30.1225 -      /* all entries are purged from the list (or we are inactive). ready to suspend */
 30.1226 -      xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
 30.1227 -      KeMemoryBarrier();
 30.1228 -      KdPrint((__DRIVER_NAME "     Set fdo state SR_STATE_SUSPENDING\n"));
 30.1229 -      KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xvdd->device_state->pdo_event_channel));
 30.1230 -      xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
 30.1231 -    }
 30.1232 -  }
 30.1233 -  //if (dump_mode) FUNCTION_EXIT();
 30.1234 -#endif
 30.1235 -  return;
 30.1236 -}
 30.1237 -
 30.1238 -static VOID
 30.1239 -XenVbd_HandleEventDpc(PSTOR_DPC dpc, PVOID DeviceExtension, PVOID arg1, PVOID arg2) {
 30.1240 -  STOR_LOCK_HANDLE lock_handle;
 30.1241 -  UNREFERENCED_PARAMETER(dpc);
 30.1242 -  UNREFERENCED_PARAMETER(arg1);
 30.1243 -  UNREFERENCED_PARAMETER(arg2);
 30.1244 -  
 30.1245 -  StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
 30.1246 -  XenVbd_HandleEvent(DeviceExtension);
 30.1247 -  StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
 30.1248 -}
 30.1249 -
 30.1250 -static VOID
 30.1251 -XenVbd_HandleEventDIRQL(PVOID DeviceExtension) {
 30.1252 -  PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
 30.1253 -  //if (dump_mode) FUNCTION_ENTER();
 30.1254 -  StorPortIssueDpc(DeviceExtension, &xvdd->dpc, NULL, NULL);
 30.1255 -  //if (dump_mode) FUNCTION_EXIT();
 30.1256 -  return;
 30.1257 -}
 30.1258 -
 30.1259 -/* this is only used during hiber and dump */
 30.1260 -static BOOLEAN
 30.1261 -XenVbd_HwStorInterrupt(PVOID DeviceExtension)
 30.1262 -{
 30.1263 -  //FUNCTION_ENTER();
 30.1264 -  XenVbd_HandleEvent(DeviceExtension);
 30.1265 -  //FUNCTION_EXIT();
 30.1266 -  return TRUE;
 30.1267 -}
 30.1268 -
 30.1269 -static BOOLEAN
 30.1270 -XenVbd_HwStorResetBus(PVOID DeviceExtension, ULONG PathId)
 30.1271 -{
 30.1272 -  PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
 30.1273 -  //srb_list_entry_t *srb_entry;
 30.1274 -  int i;
 30.1275 -  /* need to make sure that each SRB is only reset once */
 30.1276 -  LIST_ENTRY srb_reset_list;
 30.1277 -  PLIST_ENTRY list_entry;
 30.1278 -  //STOR_LOCK_HANDLE lock_handle;
 30.1279 -
 30.1280 -  UNREFERENCED_PARAMETER(PathId);
 30.1281 -
 30.1282 -  FUNCTION_ENTER();
 30.1283 -  
 30.1284 -  if (dump_mode) {
 30.1285 -    FUNCTION_MSG("dump mode - doing nothing\n");
 30.1286 -    FUNCTION_EXIT();
 30.1287 -    return TRUE;
 30.1288 -  }
 30.1289 -
 30.1290 -  /* It appears that the StartIo spinlock is already held at this point */
 30.1291 -
 30.1292 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 30.1293 -
 30.1294 -//  if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
 30.1295 -//  {
 30.1296 -    xvdd->aligned_buffer_in_use = FALSE;
 30.1297 -    
 30.1298 -    InitializeListHead(&srb_reset_list);
 30.1299 -    
 30.1300 -    while((list_entry = RemoveHeadList(&xvdd->srb_list)) != &xvdd->srb_list) {
 30.1301 -      #if DBG
 30.1302 -      srb_list_entry_t *srb_entry = CONTAINING_RECORD(list_entry, srb_list_entry_t, list_entry);
 30.1303 -      KdPrint((__DRIVER_NAME "     adding queued SRB %p to reset list\n", srb_entry->srb));
 30.1304 -      #endif
 30.1305 -      InsertTailList(&srb_reset_list, list_entry);
 30.1306 -    }
 30.1307 -    
 30.1308 -    for (i = 0; i < MAX_SHADOW_ENTRIES; i++) {
 30.1309 -      if (xvdd->shadows[i].srb) {
 30.1310 -        srb_list_entry_t *srb_entry = xvdd->shadows[i].srb->SrbExtension;
 30.1311 -        for (list_entry = srb_reset_list.Flink; list_entry != &srb_reset_list; list_entry = list_entry->Flink) {
 30.1312 -          if (list_entry == &srb_entry->list_entry)
 30.1313 -            break;
 30.1314 -        }
 30.1315 -        if (list_entry == &srb_reset_list) {
 30.1316 -          KdPrint((__DRIVER_NAME "     adding in-flight SRB %p to reset list\n", srb_entry->srb));
 30.1317 -          InsertTailList(&srb_reset_list, &srb_entry->list_entry);
 30.1318 -        }
 30.1319 -        /* set reset here so that the interrupt won't do anything with the srb but will dispose of the shadow entry correctly */
 30.1320 -        xvdd->shadows[i].reset = TRUE;
 30.1321 -        xvdd->shadows[i].srb = NULL;
 30.1322 -        xvdd->shadows[i].aligned_buffer_in_use = FALSE;
 30.1323 -      }
 30.1324 -    }
 30.1325 -
 30.1326 -    while((list_entry = RemoveHeadList(&srb_reset_list)) != &srb_reset_list) {
 30.1327 -      srb_list_entry_t *srb_entry = CONTAINING_RECORD(list_entry, srb_list_entry_t, list_entry);
 30.1328 -      srb_entry->srb->SrbStatus = SRB_STATUS_BUS_RESET;
 30.1329 -      KdPrint((__DRIVER_NAME "     completing SRB %p with status SRB_STATUS_BUS_RESET\n", srb_entry->srb));
 30.1330 -      StorPortNotification(RequestComplete, xvdd, srb_entry->srb);
 30.1331 -    }
 30.1332 -
 30.1333 -    /* send a notify to Dom0 just in case it was missed for some reason (which should _never_ happen normally but could in dump mode) */
 30.1334 -    XnNotify(xvdd->handle, xvdd->event_channel);
 30.1335 -  
 30.1336 -    StorPortNotification(NextRequest, DeviceExtension);
 30.1337 -//  }
 30.1338 -
 30.1339 -  //StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
 30.1340 -
 30.1341 -  FUNCTION_EXIT();
 30.1342 -
 30.1343 -  return TRUE;
 30.1344 -}
 30.1345 -
 30.1346 -/* called with StartIo lock held */
 30.1347 -VOID
 30.1348 -XenVbd_ProcessSrbList(PXENVBD_DEVICE_DATA xvdd) {
 30.1349 -  PUCHAR data_buffer;
 30.1350 -  PSCSI_PNP_REQUEST_BLOCK sprb;
 30.1351 -  PSCSI_POWER_REQUEST_BLOCK spwrb;
 30.1352 -  PMINIPORT_DUMP_POINTERS dump_pointers;
 30.1353 -  PCDB cdb;
 30.1354 -  ULONG data_transfer_length;
 30.1355 -  UCHAR srb_status = SRB_STATUS_PENDING;
 30.1356 -  BOOLEAN notify = FALSE;
 30.1357 -  PSCSI_REQUEST_BLOCK srb;
 30.1358 -  srb_list_entry_t *srb_entry;
 30.1359 -
 30.1360 -  if (xvdd->vbd_status != VBD_STATUS_ACTIVE) {
 30.1361 -    FUNCTION_MSG("Not yet active\n");
 30.1362 -    return;
 30.1363 -  }
 30.1364 -
 30.1365 -  while(!xvdd->aligned_buffer_in_use && xvdd->shadow_free && (srb_entry = (srb_list_entry_t *)RemoveHeadList(&xvdd->srb_list)) != (srb_list_entry_t *)&xvdd->srb_list) {
 30.1366 -    srb = srb_entry->srb;
 30.1367 -
 30.1368 -    if (xvdd->vbd_status == VBD_STATUS_INACTIVE) {
 30.1369 -      /* need to check again as may have been initialising when this srb was put on the list */
 30.1370 -      FUNCTION_MSG("HwStorStartIo Inactive Device (in ProcessSrbList)\n");
 30.1371 -      srb->SrbStatus = SRB_STATUS_NO_DEVICE;
 30.1372 -      StorPortNotification(RequestComplete, xvdd, srb);
 30.1373 -      continue;
 30.1374 -    }
 30.1375 -
 30.1376 -    data_transfer_length = srb->DataTransferLength;
 30.1377 -    
 30.1378 -    switch (srb->Function)
 30.1379 -    {
 30.1380 -    case SRB_FUNCTION_EXECUTE_SCSI:
 30.1381 -      cdb = (PCDB)srb->Cdb;
 30.1382 -
 30.1383 -      switch(cdb->CDB6GENERIC.OperationCode)
 30.1384 -      {
 30.1385 -      case SCSIOP_TEST_UNIT_READY:
 30.1386 -        if (dump_mode)
 30.1387 -          KdPrint((__DRIVER_NAME "     Command = TEST_UNIT_READY\n"));
 30.1388 -        srb_status = SRB_STATUS_SUCCESS;
 30.1389 -        srb->ScsiStatus = 0;
 30.1390 -        break;
 30.1391 -      case SCSIOP_INQUIRY:
 30.1392 -        if (dump_mode)
 30.1393 -          KdPrint((__DRIVER_NAME "     Command = INQUIRY\n"));
 30.1394 -  //      KdPrint((__DRIVER_NAME "     (LUN = %d, EVPD = %d, Page Code = %02X)\n", srb->Cdb[1] >> 5, srb->Cdb[1] & 1, srb->Cdb[2]));
 30.1395 -  //      KdPrint((__DRIVER_NAME "     (Length = %d)\n", srb->DataTransferLength));
 30.1396 -        
 30.1397 -        data_buffer = srb->DataBuffer;
 30.1398 -        RtlZeroMemory(data_buffer, srb->DataTransferLength);
 30.1399 -        srb_status = SRB_STATUS_SUCCESS;
 30.1400 -        switch (xvdd->device_type)
 30.1401 -        {
 30.1402 -        case XENVBD_DEVICETYPE_DISK:
 30.1403 -          if ((srb->Cdb[1] & 1) == 0) {
 30.1404 -            if (srb->Cdb[2]) {
 30.1405 -              srb_status = SRB_STATUS_ERROR;
 30.1406 -            } else {
 30.1407 -              PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
 30.1408 -              id->DeviceType = DIRECT_ACCESS_DEVICE;
 30.1409 -              id->Versions = 5; /* SPC-3 */
 30.1410 -              id->ResponseDataFormat = 2; /* not sure about this but WHQL complains otherwise */
 30.1411 -              id->HiSupport = 1; /* WHQL test says we should set this */
 30.1412 -              //id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
 30.1413 -              id->AdditionalLength = sizeof(INQUIRYDATA) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength) - 1;
 30.1414 -              id->CommandQueue = 1;
 30.1415 -              memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
 30.1416 -              memcpy(id->ProductId, scsi_disk_model, 16); // product id
 30.1417 -              memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
 30.1418 -              data_transfer_length = FIELD_OFFSET(INQUIRYDATA, VendorSpecific);
 30.1419 -            }
 30.1420 -          } else {
 30.1421 -            switch (srb->Cdb[2]) {
 30.1422 -            case VPD_SUPPORTED_PAGES: /* list of pages we support */
 30.1423 -              FUNCTION_MSG("VPD_SUPPORTED_PAGES\n");
 30.1424 -              data_buffer[0] = DIRECT_ACCESS_DEVICE;
 30.1425 -              data_buffer[1] = VPD_SUPPORTED_PAGES;
 30.1426 -              data_buffer[2] = 0x00;
 30.1427 -              data_buffer[3] = 4;
 30.1428 -              data_buffer[4] = VPD_SUPPORTED_PAGES;
 30.1429 -              data_buffer[5] = VPD_SERIAL_NUMBER;
 30.1430 -              data_buffer[6] = VPD_DEVICE_IDENTIFIERS;
 30.1431 -              data_buffer[7] = VPD_BLOCK_LIMITS;
 30.1432 -              data_transfer_length = 8;
 30.1433 -              break;
 30.1434 -            case VPD_SERIAL_NUMBER: /* serial number */
 30.1435 -              FUNCTION_MSG("VPD_SERIAL_NUMBER\n");
 30.1436 -              data_buffer[0] = DIRECT_ACCESS_DEVICE;
 30.1437 -              data_buffer[1] = VPD_SERIAL_NUMBER;
 30.1438 -              data_buffer[2] = 0x00;
 30.1439 -              data_buffer[3] = 8;
 30.1440 -              memset(&data_buffer[4], ' ', 8);
 30.1441 -              data_transfer_length = 12;
 30.1442 -              break;
 30.1443 -            case VPD_DEVICE_IDENTIFIERS: /* identification - we don't support any so just return zero */
 30.1444 -              FUNCTION_MSG("VPD_DEVICE_IDENTIFIERS\n");
 30.1445 -              data_buffer[0] = DIRECT_ACCESS_DEVICE;
 30.1446 -              data_buffer[1] = VPD_DEVICE_IDENTIFIERS;
 30.1447 -              data_buffer[2] = 0x00;
 30.1448 -              //data_buffer[3] = 4 + (UCHAR)strlen(xvdd->vectors.path); /* length */
 30.1449 -              data_buffer[4] = 2; /* ASCII */
 30.1450 -              data_buffer[5] = 1; /* VendorId */
 30.1451 -              data_buffer[6] = 0;
 30.1452 -              //data_buffer[7] = (UCHAR)strlen(xvdd->vectors.path);
 30.1453 -              //memcpy(&data_buffer[8], xvdd->vectors.path, strlen(xvdd->vectors.path));
 30.1454 -              //data_transfer_length = (ULONG)(8 + strlen(xvdd->vectors.path));
 30.1455 -              break;
 30.1456 -            case VPD_BLOCK_LIMITS: /* to indicate support for UNMAP (TRIM/DISCARD) */
 30.1457 -              FUNCTION_MSG("VPD_BLOCK_LIMITS\n");
 30.1458 -              // max descriptors = 1
 30.1459 -              // max sectors = 0xFFFFFFFF
 30.1460 -              // granularity = from xenbus
 30.1461 -              // alignment = from xenbus(?)
 30.1462 -              srb_status = SRB_STATUS_ERROR;
 30.1463 -              break;
 30.1464 -            default:
 30.1465 -              FUNCTION_MSG("Unknown Page %02x requested\n", srb->Cdb[2]);
 30.1466 -              srb_status = SRB_STATUS_ERROR;
 30.1467 -              break;
 30.1468 -            }
 30.1469 -          }
 30.1470 -          break;
 30.1471 -        case XENVBD_DEVICETYPE_CDROM:
 30.1472 -          if ((srb->Cdb[1] & 1) == 0)
 30.1473 -          {
 30.1474 -            PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
 30.1475 -            id->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
 30.1476 -            id->RemovableMedia = 1;
 30.1477 -            id->Versions = 3;
 30.1478 -            id->ResponseDataFormat = 0;
 30.1479 -            id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
 30.1480 -            id->CommandQueue = 1;
 30.1481 -            memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
 30.1482 -            memcpy(id->ProductId, scsi_cdrom_model, 16); // product id
 30.1483 -            memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
 30.1484 -            data_transfer_length = sizeof(INQUIRYDATA);
 30.1485 -          }
 30.1486 -          else
 30.1487 -          {
 30.1488 -            switch (srb->Cdb[2])
 30.1489 -            {
 30.1490 -            case 0x00:
 30.1491 -              data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
 30.1492 -              data_buffer[1] = 0x00;
 30.1493 -              data_buffer[2] = 0x00;
 30.1494 -              data_buffer[3] = 2;
 30.1495 -              data_buffer[4] = 0x00;
 30.1496 -              data_buffer[5] = 0x80;
 30.1497 -              data_transfer_length = 6;
 30.1498 -              break;
 30.1499 -            case 0x80:
 30.1500 -              data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
 30.1501 -              data_buffer[1] = 0x80;
 30.1502 -              data_buffer[2] = 0x00;
 30.1503 -              data_buffer[3] = 8;
 30.1504 -              data_buffer[4] = 0x31;
 30.1505 -              data_buffer[5] = 0x32;
 30.1506 -              data_buffer[6] = 0x33;
 30.1507 -              data_buffer[7] = 0x34;
 30.1508 -              data_buffer[8] = 0x35;
 30.1509 -              data_buffer[9] = 0x36;
 30.1510 -              data_buffer[10] = 0x37;
 30.1511 -              data_buffer[11] = 0x38;
 30.1512 -              data_transfer_length = 12;
 30.1513 -              break;
 30.1514 -            default:
 30.1515 -              //KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", srb->Cdb[2]));
 30.1516 -              srb_status = SRB_STATUS_ERROR;
 30.1517 -              break;
 30.1518 -            }
 30.1519 -          }
 30.1520 -          break;
 30.1521 -        default:
 30.1522 -          //KdPrint((__DRIVER_NAME "     Unknown DeviceType %02x requested\n", xvdd->device_type));
 30.1523 -          srb_status = SRB_STATUS_ERROR;
 30.1524 -          break;
 30.1525 -        }
 30.1526 -        break;
 30.1527 -      case SCSIOP_READ_CAPACITY:
 30.1528 -        //if (dump_mode)
 30.1529 -          KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
 30.1530 -        //KdPrint((__DRIVER_NAME "       LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
 30.1531 -        //KdPrint((__DRIVER_NAME "       LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
 30.1532 -        //KdPrint((__DRIVER_NAME "       PMI = %d\n", srb->Cdb[8] & 1));
 30.1533 -        //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
 30.1534 -        data_buffer = srb->DataBuffer;
 30.1535 -        RtlZeroMemory(data_buffer, srb->DataTransferLength);
 30.1536 -        if ((xvdd->total_sectors - 1) >> 32)
 30.1537 -        {
 30.1538 -          data_buffer[0] = 0xff;
 30.1539 -          data_buffer[1] = 0xff;
 30.1540 -          data_buffer[2] = 0xff;
 30.1541 -          data_buffer[3] = 0xff;
 30.1542 -        }
 30.1543 -        else
 30.1544 -        {
 30.1545 -          data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
 30.1546 -          data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
 30.1547 -          data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
 30.1548 -          data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
 30.1549 -        }
 30.1550 -        data_buffer[4] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
 30.1551 -        data_buffer[5] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
 30.1552 -        data_buffer[6] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
 30.1553 -        data_buffer[7] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
 30.1554 -        data_transfer_length = 8;
 30.1555 -        srb->ScsiStatus = 0;
 30.1556 -        srb_status = SRB_STATUS_SUCCESS;
 30.1557 -        break;
 30.1558 -      case SCSIOP_READ_CAPACITY16:
 30.1559 -        //if (dump_mode)
 30.1560 -          KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY16\n"));
 30.1561 -        //KdPrint((__DRIVER_NAME "       LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
 30.1562 -        //KdPrint((__DRIVER_NAME "       LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
 30.1563 -        //KdPrint((__DRIVER_NAME "       PMI = %d\n", srb->Cdb[8] & 1));
 30.1564 -        data_buffer = srb->DataBuffer;
 30.1565 -        RtlZeroMemory(data_buffer, srb->DataTransferLength);
 30.1566 -        data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 56) & 0xff;
 30.1567 -        data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 48) & 0xff;
 30.1568 -        data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 40) & 0xff;
 30.1569 -        data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 32) & 0xff;
 30.1570 -        data_buffer[4] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
 30.1571 -        data_buffer[5] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
 30.1572 -        data_buffer[6] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
 30.1573 -        data_buffer[7] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
 30.1574 -        data_buffer[8] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
 30.1575 -        data_buffer[9] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
 30.1576 -        data_buffer[10] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
 30.1577 -        data_buffer[11] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
 30.1578 -        data_buffer[12] = 0;
 30.1579 -        switch (xvdd->hw_bytes_per_sector / xvdd->bytes_per_sector) {
 30.1580 -        case 1:
 30.1581 -          data_buffer[13] = 0; /* 512 byte hardware sectors */
 30.1582 -          break;
 30.1583 -        case 2:
 30.1584 -          data_buffer[13] = 1; /* 1024 byte hardware sectors */
 30.1585 -          break;
 30.1586 -        case 3:
 30.1587 -          data_buffer[13] = 2; /* 2048 byte hardware sectors */
 30.1588 -          break;
 30.1589 -        case 4:
 30.1590 -          data_buffer[13] = 3; /* 4096 byte hardware sectors */
 30.1591 -          break;
 30.1592 -        default:
 30.1593 -          data_buffer[13] = 0; /* 512 byte hardware sectors */
 30.1594 -          KdPrint((__DRIVER_NAME "     Unknown logical blocks per physical block %d (%d / %d)\n", xvdd->hw_bytes_per_sector / xvdd->bytes_per_sector, xvdd->hw_bytes_per_sector, xvdd->bytes_per_sector));
 30.1595 -          break;
 30.1596 -        }
 30.1597 -        data_buffer[14] = 0xC0; //0;
 30.1598 -        data_buffer[15] = 0;
 30.1599 -        data_transfer_length = 16;
 30.1600 -        srb->ScsiStatus = 0;
 30.1601 -        srb_status = SRB_STATUS_SUCCESS;
 30.1602 -        break;
 30.1603 -      case SCSIOP_MODE_SENSE:
 30.1604 -      case SCSIOP_MODE_SENSE10:
 30.1605 -        if (dump_mode)
 30.1606 -          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));
 30.1607 -        data_transfer_length = XenVbd_FillModePage(xvdd, srb);
 30.1608 -        srb_status = SRB_STATUS_SUCCESS;
 30.1609 -        break;
 30.1610 -      case SCSIOP_READ:
 30.1611 -      case SCSIOP_READ16:
 30.1612 -      case SCSIOP_WRITE:
 30.1613 -      case SCSIOP_WRITE16:
 30.1614 -        //FUNCTION_MSG("srb = %p\n", srb);
 30.1615 -        if (XenVbd_PutSrbOnRing(xvdd, srb)) {
 30.1616 -          notify = TRUE;
 30.1617 -        }
 30.1618 -        break;
 30.1619 -      case SCSIOP_WRITE_SAME:
 30.1620 -      case SCSIOP_WRITE_SAME16:
 30.1621 -        /* not yet supported */
 30.1622 -        FUNCTION_MSG("WRITE_SAME\n");
 30.1623 -        break;
 30.1624 -      case SCSIOP_UNMAP:
 30.1625 -        /* not yet supported */
 30.1626 -        FUNCTION_MSG("UNMAP\n");
 30.1627 -        break;
 30.1628 -      case SCSIOP_VERIFY:
 30.1629 -      case SCSIOP_VERIFY16:
 30.1630 -        // Should we do more here?
 30.1631 -        if (dump_mode)
 30.1632 -          KdPrint((__DRIVER_NAME "     Command = VERIFY\n"));
 30.1633 -        srb_status = SRB_STATUS_SUCCESS;
 30.1634 -        break;
 30.1635 -      case SCSIOP_REPORT_LUNS:
 30.1636 -        //if (dump_mode)
 30.1637 -          FUNCTION_MSG("Command = REPORT_LUNS\n");
 30.1638 -        switch (srb->Cdb[2]) {
 30.1639 -        case 1:
 30.1640 -          FUNCTION_MSG(" SELECT REPORT = %d\n", srb->Cdb[2] & 255);
 30.1641 -          break;
 30.1642 -        default:
 30.1643 -          FUNCTION_MSG(" SELECT REPORT = %d\n", srb->Cdb[2] & 255);
 30.1644 -          break;
 30.1645 -        }
 30.1646 -        FUNCTION_MSG(" ALLOCATION LENGTH = %d\n", (srb->Cdb[6] << 24)|(srb->Cdb[7] << 16)|(srb->Cdb[8] << 8)|(srb->Cdb[9]));
 30.1647 -        data_buffer = srb->DataBuffer;
 30.1648 -        RtlZeroMemory(data_buffer, srb->DataTransferLength);
 30.1649 -        data_buffer[3] = 8; /* 1 lun */
 30.1650 -        /* rest of the data is blank */
 30.1651 -        data_transfer_length = 16;
 30.1652 -        srb->ScsiStatus = 0;
 30.1653 -        srb_status = SRB_STATUS_SUCCESS;
 30.1654 -        break;
 30.1655 -      case SCSIOP_REQUEST_SENSE:
 30.1656 -        if (dump_mode)
 30.1657 -          KdPrint((__DRIVER_NAME "     Command = REQUEST_SENSE\n"));
 30.1658 -        data_transfer_length = XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
 30.1659 -        srb_status = SRB_STATUS_SUCCESS;
 30.1660 -        break;      
 30.1661 -      case SCSIOP_READ_TOC:
 30.1662 -        if (dump_mode)
 30.1663 -          KdPrint((__DRIVER_NAME "     Command = READ_TOC\n"));
 30.1664 -        data_buffer = srb->DataBuffer;
 30.1665 -  /*
 30.1666 -  #define READ_TOC_FORMAT_TOC         0x00
 30.1667 -  #define READ_TOC_FORMAT_SESSION     0x01
 30.1668 -  #define READ_TOC_FORMAT_FULL_TOC    0x02
 30.1669 -  #define READ_TOC_FORMAT_PMA         0x03
 30.1670 -  #define READ_TOC_FORMAT_ATIP        0x04
 30.1671 -  */
 30.1672 -  //      KdPrint((__DRIVER_NAME "     Msf = %d\n", cdb->READ_TOC.Msf));
 30.1673 -  //      KdPrint((__DRIVER_NAME "     LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
 30.1674 -  //      KdPrint((__DRIVER_NAME "     Format2 = %d\n", cdb->READ_TOC.Format2));
 30.1675 -  //      KdPrint((__DRIVER_NAME "     StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
 30.1676 -  //      KdPrint((__DRIVER_NAME "     AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
 30.1677 -  //      KdPrint((__DRIVER_NAME "     Control = %d\n", cdb->READ_TOC.Control));
 30.1678 -  //      KdPrint((__DRIVER_NAME "     Format = %d\n", cdb->READ_TOC.Format));
 30.1679 -        switch (cdb->READ_TOC.Format2)
 30.1680 -        {
 30.1681 -        case READ_TOC_FORMAT_TOC:
 30.1682 -          data_buffer[0] = 0; // length MSB
 30.1683 -          data_buffer[1] = 10; // length LSB
 30.1684 -          data_buffer[2] = 1; // First Track
 30.1685 -          data_buffer[3] = 1; // Last Track
 30.1686 -          data_buffer[4] = 0; // Reserved
 30.1687 -          data_buffer[5] = 0x14; // current position data + uninterrupted data
 30.1688 -          data_buffer[6] = 1; // last complete track
 30.1689 -          data_buffer[7] = 0; // reserved
 30.1690 -          data_buffer[8] = 0; // MSB Block
 30.1691 -          data_buffer[9] = 0;
 30.1692 -          data_buffer[10] = 0;
 30.1693 -          data_buffer[11] = 0; // LSB Block
 30.1694 -          data_transfer_length = 12;
 30.1695 -          srb_status = SRB_STATUS_SUCCESS;
 30.1696 -          break;
 30.1697 -        case READ_TOC_FORMAT_SESSION:
 30.1698 -        case READ_TOC_FORMAT_FULL_TOC:
 30.1699 -        case READ_TOC_FORMAT_PMA:
 30.1700 -        case READ_TOC_FORMAT_ATIP:
 30.1701 -          srb_status = SRB_STATUS_ERROR;
 30.1702 -          break;
 30.1703 -        default:
 30.1704 -          srb_status = SRB_STATUS_ERROR;
 30.1705 -          break;
 30.1706 -        }
 30.1707 -        break;
 30.1708 -      case SCSIOP_START_STOP_UNIT:
 30.1709 -        KdPrint((__DRIVER_NAME "     Command = SCSIOP_START_STOP_UNIT\n"));
 30.1710 -        srb_status = SRB_STATUS_SUCCESS;
 30.1711 -        break;
 30.1712 -      case SCSIOP_RESERVE_UNIT:
 30.1713 -        KdPrint((__DRIVER_NAME "     Command = SCSIOP_RESERVE_UNIT\n"));
 30.1714 -        srb_status = SRB_STATUS_SUCCESS;
 30.1715 -        break;
 30.1716 -      case SCSIOP_RELEASE_UNIT:
 30.1717 -        KdPrint((__DRIVER_NAME "     Command = SCSIOP_RELEASE_UNIT\n"));
 30.1718 -        srb_status = SRB_STATUS_SUCCESS;
 30.1719 -        break;
 30.1720 -      default:
 30.1721 -        KdPrint((__DRIVER_NAME "     Unhandled EXECUTE_SCSI Command = %02X\n", srb->Cdb[0]));
 30.1722 -        xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
 30.1723 -        srb_status = SRB_STATUS_ERROR;
 30.1724 -        break;
 30.1725 -      }
 30.1726 -      if (srb_status == SRB_STATUS_ERROR)
 30.1727 -      {
 30.1728 -        KdPrint((__DRIVER_NAME "     EXECUTE_SCSI Command = %02X returned error %02x\n", srb->Cdb[0], xvdd->last_sense_key));
 30.1729 -        if (xvdd->last_sense_key == SCSI_SENSE_NO_SENSE)
 30.1730 -        {
 30.1731 -          xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
 30.1732 -          xvdd->last_additional_sense_code = SCSI_ADSENSE_INVALID_CDB;
 30.1733 -        }
 30.1734 -        srb->SrbStatus = srb_status;
 30.1735 -        srb->ScsiStatus = 0x02;
 30.1736 -        XenVbd_MakeAutoSense(xvdd, srb);
 30.1737 -        StorPortNotification(RequestComplete, xvdd, srb);
 30.1738 -      }
 30.1739 -      else if (srb_status != SRB_STATUS_PENDING)
 30.1740 -      {
 30.1741 -        if (data_transfer_length > srb->DataTransferLength)
 30.1742 -          KdPrint((__DRIVER_NAME "     data_transfer_length too big - %d > %d\n", data_transfer_length, srb->DataTransferLength));
 30.1743 -        
 30.1744 -        if (srb_status == SRB_STATUS_SUCCESS && data_transfer_length < srb->DataTransferLength)
 30.1745 -        {
 30.1746 -          srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
 30.1747 -          srb->DataTransferLength = data_transfer_length;
 30.1748 -        }
 30.1749 -        else
 30.1750 -        {
 30.1751 -          srb->SrbStatus = srb_status;
 30.1752 -        }
 30.1753 -        xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
 30.1754 -        xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
 30.1755 -        StorPortNotification(RequestComplete, xvdd, srb);
 30.1756 -      }
 30.1757 -      break;
 30.1758 -    case SRB_FUNCTION_IO_CONTROL:
 30.1759 -      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_IO_CONTROL\n"));
 30.1760 -      srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 30.1761 -      StorPortNotification(RequestComplete, xvdd, srb);
 30.1762 -      break;
 30.1763 -    case SRB_FUNCTION_FLUSH:
 30.1764 -      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
 30.1765 -      srb->SrbStatus = SRB_STATUS_SUCCESS;
 30.1766 -      StorPortNotification(RequestComplete, xvdd, srb);
 30.1767 -      break;
 30.1768 -    case SRB_FUNCTION_PNP:
 30.1769 -      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_PNP\n"));
 30.1770 -      sprb = (PSCSI_PNP_REQUEST_BLOCK)srb;
 30.1771 -      switch (sprb->PnPAction)
 30.1772 -      {
 30.1773 -      case StorStartDevice:
 30.1774 -        KdPrint((__DRIVER_NAME "      StorStartDevice\n"));
 30.1775 -        break;
 30.1776 -      case StorRemoveDevice:
 30.1777 -        KdPrint((__DRIVER_NAME "      StorRemoveDevice\n"));
 30.1778 -        break;
 30.1779 -      case StorStopDevice:
 30.1780 -        KdPrint((__DRIVER_NAME "      StorStopDevice\n"));
 30.1781 -        break;
 30.1782 -      case StorQueryCapabilities:
 30.1783 -        KdPrint((__DRIVER_NAME "      StorQueryCapabilities\n"));
 30.1784 -        break;
 30.1785 -      case StorFilterResourceRequirements:
 30.1786 -        KdPrint((__DRIVER_NAME "      StorFilterResourceRequirements\n"));
 30.1787 -        break;
 30.1788 -      default:
 30.1789 -        KdPrint((__DRIVER_NAME "      Stor%d\n", sprb->PnPAction));
 30.1790 -        break;
 30.1791 -      }
 30.1792 -      KdPrint((__DRIVER_NAME "      SrbPnPFlags = %08x\n", sprb->SrbPnPFlags));
 30.1793 -      srb->SrbStatus = SRB_STATUS_SUCCESS;
 30.1794 -      StorPortNotification(RequestComplete, xvdd, srb);
 30.1795 -      break;
 30.1796 -      
 30.1797 -    case SRB_FUNCTION_POWER:
 30.1798 -      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_POWER\n"));
 30.1799 -      spwrb = (PSCSI_POWER_REQUEST_BLOCK)srb;
 30.1800 -      switch (spwrb->PowerAction)
 30.1801 -      {
 30.1802 -      case StorPowerActionNone:
 30.1803 -        KdPrint((__DRIVER_NAME "      StorPowerActionNone\n"));
 30.1804 -        break;
 30.1805 -      case StorPowerActionReserved:
 30.1806 -        KdPrint((__DRIVER_NAME "      StorPowerActionReserved\n"));
 30.1807 -        break;
 30.1808 -      case StorPowerActionSleep:
 30.1809 -        KdPrint((__DRIVER_NAME "      StorPowerActionSleep\n"));
 30.1810 -        break;
 30.1811 -      case StorPowerActionHibernate:
 30.1812 -        KdPrint((__DRIVER_NAME "      StorPowerActionHibernate\n"));
 30.1813 -        break;
 30.1814 -      case StorPowerActionShutdown:
 30.1815 -        KdPrint((__DRIVER_NAME "      StorPowerActionShutdown\n"));
 30.1816 -        break;
 30.1817 -      case StorPowerActionShutdownReset:
 30.1818 -        KdPrint((__DRIVER_NAME "      StorPowerActionShutdownReset\n"));
 30.1819 -        break;
 30.1820 -      case StorPowerActionShutdownOff:
 30.1821 -        KdPrint((__DRIVER_NAME "      StorPowerActionShutdownOff\n"));
 30.1822 -        break;
 30.1823 -      case StorPowerActionWarmEject:
 30.1824 -        KdPrint((__DRIVER_NAME "      StorPowerActionWarmEject\n"));
 30.1825 -        break;
 30.1826 -      default:
 30.1827 -        KdPrint((__DRIVER_NAME "      Stor%d\n", spwrb->PowerAction));
 30.1828 -        break;
 30.1829 -      }
 30.1830 -      srb->SrbStatus = SRB_STATUS_SUCCESS;
 30.1831 -      StorPortNotification(RequestComplete, xvdd, srb);
 30.1832 -      break;
 30.1833 -    case SRB_FUNCTION_DUMP_POINTERS:
 30.1834 -      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_DUMP_POINTERS\n"));
 30.1835 -      KdPrint((__DRIVER_NAME "     DataTransferLength = %d\n", srb->DataTransferLength));
 30.1836 -      dump_pointers = srb->DataBuffer;
 30.1837 -      KdPrint((__DRIVER_NAME "      Version = %d\n", dump_pointers->Version));
 30.1838 -      KdPrint((__DRIVER_NAME "      Size = %d\n", dump_pointers->Size));
 30.1839 -      KdPrint((__DRIVER_NAME "      DriverName = %S\n", dump_pointers->DriverName));
 30.1840 -      KdPrint((__DRIVER_NAME "      AdapterObject = %p\n", dump_pointers->AdapterObject));
 30.1841 -      KdPrint((__DRIVER_NAME "      MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
 30.1842 -      KdPrint((__DRIVER_NAME "      CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
 30.1843 -      KdPrint((__DRIVER_NAME "      MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
 30.1844 -      KdPrint((__DRIVER_NAME "      SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
 30.1845 -      KdPrint((__DRIVER_NAME "      AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
 30.1846 -      KdPrint((__DRIVER_NAME "      MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
 30.1847 -      KdPrint((__DRIVER_NAME "      NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
 30.1848 -      KdPrint((__DRIVER_NAME "      AlignmentMask = %d\n", dump_pointers->AlignmentMask));
 30.1849 -      KdPrint((__DRIVER_NAME "      NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
 30.1850 -      KdPrint((__DRIVER_NAME "      NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
 30.1851 -      KdPrint((__DRIVER_NAME "      Master = %d\n", dump_pointers->Master));
 30.1852 -      KdPrint((__DRIVER_NAME "      MapBuffers = %d\n", dump_pointers->MapBuffers));
 30.1853 -      KdPrint((__DRIVER_NAME "      MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
 30.1854 -
 30.1855 -      dump_pointers->Version = DUMP_MINIPORT_VERSION_1;
 30.1856 -      dump_pointers->Size = sizeof(MINIPORT_DUMP_POINTERS);
 30.1857 -      RtlStringCchCopyW(dump_pointers->DriverName, DUMP_MINIPORT_NAME_LENGTH, L"xenvbd.sys");
 30.1858 -      dump_pointers->AdapterObject = NULL;
 30.1859 -      dump_pointers->MappedRegisterBase = 0;
 30.1860 -      dump_pointers->CommonBufferSize = 0;
 30.1861 -      dump_pointers->MiniportPrivateDumpData = xvdd;
 30.1862 -      dump_pointers->AdapterInterfaceType = Internal;
 30.1863 -      dump_pointers->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;;
 30.1864 -      dump_pointers->NumberOfPhysicalBreaks = dump_pointers->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
 30.1865 -      dump_pointers->AlignmentMask = 0;
 30.1866 -      dump_pointers->NumberOfAccessRanges = 1;
 30.1867 -      dump_pointers->NumberOfBuses = 1;
 30.1868 -      dump_pointers->Master = TRUE;
 30.1869 -      dump_pointers->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
 30.1870 -      dump_pointers->MaximumNumberOfTargets = 2;
 30.1871 -
 30.1872 -      KdPrint((__DRIVER_NAME "      Version = %d\n", dump_pointers->Version));
 30.1873 -      KdPrint((__DRIVER_NAME "      Size = %d\n", dump_pointers->Size));
 30.1874 -      //KdPrint((__DRIVER_NAME "      DriverName = %S\n", dump_pointers->DriverName));
 30.1875 -      KdPrint((__DRIVER_NAME "      AdapterObject = %p\n", dump_pointers->AdapterObject));
 30.1876 -      KdPrint((__DRIVER_NAME "      MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
 30.1877 -      KdPrint((__DRIVER_NAME "      CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
 30.1878 -      KdPrint((__DRIVER_NAME "      MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
 30.1879 -      KdPrint((__DRIVER_NAME "      SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
 30.1880 -      KdPrint((__DRIVER_NAME "      AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
 30.1881 -      KdPrint((__DRIVER_NAME "      MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
 30.1882 -      KdPrint((__DRIVER_NAME "      NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
 30.1883 -      KdPrint((__DRIVER_NAME "      AlignmentMask = %d\n", dump_pointers->AlignmentMask));
 30.1884 -      KdPrint((__DRIVER_NAME "      NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
 30.1885 -      KdPrint((__DRIVER_NAME "      NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
 30.1886 -      KdPrint((__DRIVER_NAME "      Master = %d\n", dump_pointers->Master));
 30.1887 -      KdPrint((__DRIVER_NAME "      MapBuffers = %d\n", dump_pointers->MapBuffers));
 30.1888 -      KdPrint((__DRIVER_NAME "      MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
 30.1889 -
 30.1890 -      srb->SrbStatus = SRB_STATUS_SUCCESS;
 30.1891 -      StorPortNotification(RequestComplete, xvdd, srb);
 30.1892 -      break;
 30.1893 -    case SRB_FUNCTION_SHUTDOWN:
 30.1894 -      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_SHUTDOWN %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
 30.1895 -      srb->SrbStatus = SRB_STATUS_SUCCESS;
 30.1896 -      StorPortNotification(RequestComplete, xvdd, srb);
 30.1897 -      break;
 30.1898 -    case SRB_FUNCTION_RESET_BUS:
 30.1899 -    case SRB_FUNCTION_RESET_DEVICE:
 30.1900 -    case SRB_FUNCTION_RESET_LOGICAL_UNIT:
 30.1901 -      /* the path doesn't matter here - only ever one device*/
 30.1902 -      XenVbd_HwStorResetBus(xvdd, 0);
 30.1903 -      srb->SrbStatus = SRB_STATUS_SUCCESS;
 30.1904 -      StorPortNotification(RequestComplete, xvdd, srb);    
 30.1905 -      break;
 30.1906 -    case SRB_FUNCTION_WMI:
 30.1907 -      srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 30.1908 -      StorPortNotification(RequestComplete, xvdd, srb);
 30.1909 -      break;
 30.1910 -
 30.1911 -    default:
 30.1912 -      KdPrint((__DRIVER_NAME "     Unhandled srb->Function = %08X\n", srb->Function));
 30.1913 -      srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 30.1914 -      StorPortNotification(RequestComplete, xvdd, srb);
 30.1915 -      break;
 30.1916 -    }
 30.1917 -  }
 30.1918 -  if (notify) {
 30.1919 -    notify = FALSE;
 30.1920 -    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
 30.1921 -    if (notify) {
 30.1922 -      XnNotify(xvdd->handle, xvdd->event_channel);
 30.1923 -    }
 30.1924 -  }
 30.1925 -  return;
 30.1926 -}
 30.1927 -
 30.1928 -static BOOLEAN
 30.1929 -XenVbd_HwStorStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK srb)
 30.1930 -{
 30.1931 -  PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
 30.1932 -  STOR_LOCK_HANDLE lock_handle;
 30.1933 -
 30.1934 -  //if (dump_mode) FUNCTION_ENTER();
 30.1935 -  //if (dump_mode) KdPrint((__DRIVER_NAME "     srb = %p\n", srb));
 30.1936 -
 30.1937 -  StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
 30.1938 -
 30.1939 -  if (xvdd->vbd_status == VBD_STATUS_INACTIVE) {
 30.1940 -    FUNCTION_MSG("HwStorStartIo Inactive Device (in StartIo)\n");
 30.1941 -    srb->SrbStatus = SRB_STATUS_NO_DEVICE;
 30.1942 -    StorPortNotification(RequestComplete, DeviceExtension, srb);
 30.1943 -    StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
 30.1944 -    return TRUE;
 30.1945 -  }
 30.1946 -
 30.1947 -  if (srb->PathId != 0 || srb->TargetId != 0 || srb->Lun != 0)
 30.1948 -  {
 30.1949 -    FUNCTION_MSG("HwStorStartIo (Out of bounds - PathId = %d, TargetId = %d, Lun = %d)\n", srb->PathId, srb->TargetId, srb->Lun);
 30.1950 -    srb->SrbStatus = SRB_STATUS_NO_DEVICE;
 30.1951 -    StorPortNotification(RequestComplete, DeviceExtension, srb);
 30.1952 -    StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
 30.1953 -    return TRUE;
 30.1954 -  }
 30.1955 -
 30.1956 -  XenVbd_PutSrbOnList(xvdd, srb);
 30.1957 -  XenVbd_ProcessSrbList(xvdd);
 30.1958 -  StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
 30.1959 -  return TRUE;
 30.1960 -}
 30.1961 -
 30.1962 -static SCSI_ADAPTER_CONTROL_STATUS
 30.1963 -XenVbd_HwStorAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
 30.1964 -{
 30.1965 -  PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
 30.1966 -  SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
 30.1967 -  PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
 30.1968 -  //KIRQL OldIrql;
 30.1969 -
 30.1970 -  FUNCTION_ENTER();
 30.1971 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 30.1972 -  KdPrint((__DRIVER_NAME "     xvdd = %p\n", xvdd));
 30.1973 -
 30.1974 -  switch (ControlType)
 30.1975 -  {
 30.1976 -  case ScsiQuerySupportedControlTypes:
 30.1977 -    SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
 30.1978 -    KdPrint((__DRIVER_NAME "     ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
 30.1979 -    SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
 30.1980 -    SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
 30.1981 -    SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
 30.1982 -    break;
 30.1983 -  case ScsiStopAdapter:
 30.1984 -    KdPrint((__DRIVER_NAME "     ScsiStopAdapter\n"));
 30.1985 -    if (xvdd->vbd_status == VBD_STATUS_INACTIVE)
 30.1986 -    {
 30.1987 -      KdPrint((__DRIVER_NAME "     inactive - nothing to do\n"));
 30.1988 -      break;
 30.1989 -    }
 30.1990 -    NT_ASSERT(IsListEmpty(&xvdd->srb_list));
 30.1991 -    NT_ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
 30.1992 -    break;
 30.1993 -  case ScsiRestartAdapter:
 30.1994 -    KdPrint((__DRIVER_NAME "     ScsiRestartAdapter\n"));
 30.1995 -    if (xvdd->vbd_status == VBD_STATUS_INACTIVE)
 30.1996 -    {
 30.1997 -      KdPrint((__DRIVER_NAME "     inactive - nothing to do\n"));
 30.1998 -      break;
 30.1999 -    }
 30.2000 -    /* increase the tag every time we stop/start to track where the gref's came from */
 30.2001 -    xvdd->grant_tag++;
 30.2002 -#if 0
 30.2003 -    if (XenVbd_InitFromConfig(xvdd) != SP_RETURN_FOUND) {
 30.2004 -      #pragma warning(suppress:28159)
 30.2005 -      KeBugCheckEx(DATA_COHERENCY_EXCEPTION, 0, (ULONG_PTR)xvdd, 0, 0);
 30.2006 -    }
 30.2007 -#endif    
 30.2008 -    break;
 30.2009 -  case ScsiSetBootConfig:
 30.2010 -    KdPrint((__DRIVER_NAME "     ScsiSetBootConfig\n"));
 30.2011 -    break;
 30.2012 -  case ScsiSetRunningConfig:
 30.2013 -    KdPrint((__DRIVER_NAME "     ScsiSetRunningConfig\n"));
 30.2014 -    break;
 30.2015 -  default:
 30.2016 -    KdPrint((__DRIVER_NAME "     UNKNOWN\n"));
 30.2017 -    break;
 30.2018 -  }
 30.2019 -
 30.2020 -  FUNCTION_EXIT();
 30.2021 -  
 30.2022 -  return Status;
 30.2023 -}
 30.2024 -
 30.2025 -NTSTATUS
 30.2026 -DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
 30.2027 -{
 30.2028 -  ULONG status;
 30.2029 -  VIRTUAL_HW_INITIALIZATION_DATA VHwInitializationData;
 30.2030 -  HW_INITIALIZATION_DATA HwInitializationData;
 30.2031 -  OBJECT_ATTRIBUTES oa;
 30.2032 -  HANDLE service_handle;
 30.2033 -  UNICODE_STRING param_name;
 30.2034 -  HANDLE param_handle;
 30.2035 -  UNICODE_STRING value_name;
 30.2036 -  CHAR buf[256];
 30.2037 -  ULONG buf_len;
 30.2038 -  PKEY_VALUE_PARTIAL_INFORMATION kpv;
 30.2039 -  
 30.2040 -  FUNCTION_ENTER();
 30.2041 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 30.2042 -  KdPrint((__DRIVER_NAME "     DriverObject = %p, RegistryPath = %p\n", DriverObject, RegistryPath));
 30.2043 -
 30.2044 -  /* RegistryPath == NULL when we are invoked as a crash dump driver */
 30.2045 -  if (!RegistryPath)
 30.2046 -  {
 30.2047 -    dump_mode = TRUE;
 30.2048 -  }
 30.2049 -  
 30.2050 -  if (!dump_mode)
 30.2051 -  {
 30.2052 -    InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
 30.2053 -    status = ZwOpenKey(&service_handle, KEY_READ, &oa);
 30.2054 -    if(!NT_SUCCESS(status))
 30.2055 -    {
 30.2056 -      KdPrint((__DRIVER_NAME "     ZwOpenKey(Service) returned %08x\n", status));
 30.2057 -    }
 30.2058 -    else
 30.2059 -    {
 30.2060 -      RtlInitUnicodeString(&param_name, L"Parameters");
 30.2061 -      InitializeObjectAttributes(&oa, &param_name, OBJ_CASE_INSENSITIVE, service_handle, NULL);
 30.2062 -      status = ZwOpenKey(&param_handle, KEY_READ, &oa);
 30.2063 -      if(!NT_SUCCESS(status))
 30.2064 -      {
 30.2065 -        KdPrint((__DRIVER_NAME "     ZwOpenKey(Parameters) returned %08x\n", status));
 30.2066 -      }
 30.2067 -      else
 30.2068 -      {
 30.2069 -        kpv = (PKEY_VALUE_PARTIAL_INFORMATION)buf;
 30.2070 -        RtlFillMemory(scsi_device_manufacturer, 8, ' ');
 30.2071 -        RtlFillMemory(scsi_disk_model, 16, ' ');
 30.2072 -        RtlFillMemory(scsi_cdrom_model, 16, ' ');
 30.2073 -
 30.2074 -        RtlInitUnicodeString(&value_name, L"Manufacturer");
 30.2075 -        buf_len = 256;
 30.2076 -        status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
 30.2077 -        if(NT_SUCCESS(status))
 30.2078 -          wcstombs(scsi_device_manufacturer, (PWCHAR)kpv->Data, min(kpv->DataLength, 8));
 30.2079 -        else
 30.2080 -          RtlStringCbCopyA(scsi_device_manufacturer, 8, "XEN     ");
 30.2081 -
 30.2082 -        RtlInitUnicodeString(&value_name, L"Disk_Model");
 30.2083 -        buf_len = 256;
 30.2084 -        status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
 30.2085 -        if(NT_SUCCESS(status))
 30.2086 -          wcstombs(scsi_disk_model, (PWCHAR)kpv->Data, min(kpv->DataLength, 16));
 30.2087 -        else
 30.2088 -          RtlStringCbCopyA(scsi_disk_model, 16, "PV DISK          ");
 30.2089 -
 30.2090 -        RtlInitUnicodeString(&value_name, L"CDROM_Model");
 30.2091 -        buf_len = 256;
 30.2092 -        status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
 30.2093 -        if(NT_SUCCESS(status))
 30.2094 -          wcstombs(scsi_cdrom_model, (PWCHAR)kpv->Data, min(kpv->DataLength, 16));
 30.2095 -        else
 30.2096 -          RtlStringCbCopyA(scsi_cdrom_model, 16, "PV CDROM        ");
 30.2097 -        ZwClose(param_handle);
 30.2098 -      }
 30.2099 -      ZwClose(service_handle);
 30.2100 -    }  
 30.2101 -    RtlZeroMemory(&VHwInitializationData, sizeof(VIRTUAL_HW_INITIALIZATION_DATA));
 30.2102 -    VHwInitializationData.HwInitializationDataSize = sizeof(VIRTUAL_HW_INITIALIZATION_DATA);
 30.2103 -    VHwInitializationData.AdapterInterfaceType = Internal; //PNPBus; /* maybe should be internal? */
 30.2104 -    VHwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE;
 30.2105 -    VHwInitializationData.SpecificLuExtensionSize = 0;
 30.2106 -    VHwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
 30.2107 -    VHwInitializationData.NumberOfAccessRanges = 1;
 30.2108 -    VHwInitializationData.MapBuffers = STOR_MAP_ALL_BUFFERS;
 30.2109 -    //VHwInitializationData.NeedPhysicalAddresses  = TRUE;
 30.2110 -    VHwInitializationData.TaggedQueuing = TRUE;
 30.2111 -    VHwInitializationData.AutoRequestSense = TRUE;
 30.2112 -    VHwInitializationData.MultipleRequestPerLu = TRUE;
 30.2113 -    VHwInitializationData.ReceiveEvent = TRUE;
 30.2114 -    VHwInitializationData.PortVersionFlags = 0;
 30.2115 -    VHwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
 30.2116 -    VHwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
 30.2117 -    VHwInitializationData.HwFindAdapter = XenVbd_VirtualHwStorFindAdapter;
 30.2118 -    VHwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
 30.2119 -    VHwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
 30.2120 -    status = StorPortInitialize(DriverObject, RegistryPath, (PHW_INITIALIZATION_DATA)&VHwInitializationData, NULL);
 30.2121 -  }
 30.2122 -  else
 30.2123 -  {
 30.2124 -    RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
 30.2125 -    HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
 30.2126 -    HwInitializationData.AdapterInterfaceType = Internal; //PNPBus; /* not Internal */
 30.2127 -    HwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE;
 30.2128 -    HwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
 30.2129 -    HwInitializationData.NumberOfAccessRanges = 1;
 30.2130 -    HwInitializationData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
 30.2131 -    HwInitializationData.NeedPhysicalAddresses  = TRUE;
 30.2132 -    HwInitializationData.TaggedQueuing = FALSE;
 30.2133 -    HwInitializationData.AutoRequestSense = TRUE;
 30.2134 -    HwInitializationData.MultipleRequestPerLu = FALSE;
 30.2135 -    HwInitializationData.ReceiveEvent = TRUE;
 30.2136 -    HwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
 30.2137 -    HwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
 30.2138 -    HwInitializationData.HwFindAdapter = XenVbd_HwStorFindAdapter;
 30.2139 -    HwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
 30.2140 -    HwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
 30.2141 -    HwInitializationData.HwInterrupt = XenVbd_HwStorInterrupt;
 30.2142 -    status = StorPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
 30.2143 -  }
 30.2144 -  
 30.2145 -  if(!NT_SUCCESS(status)) {
 30.2146 -    FUNCTION_MSG("ScsiPortInitialize failed with status 0x%08x\n", status);
 30.2147 -  }
 30.2148 -
 30.2149 -  FUNCTION_EXIT();
 30.2150 -
 30.2151 -  return status;
 30.2152 -}
 30.2153 \ No newline at end of file
    31.1 --- a/xenvbd/xenvbd_storport.h	Sun Jan 06 14:08:22 2013 +1100
    31.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.3 @@ -1,180 +0,0 @@
    31.4 -/*
    31.5 -PV Drivers for Windows Xen HVM Domains
    31.6 -Copyright (C) 2007 James Harper
    31.7 -
    31.8 -This program is free software; you can redistribute it and/or
    31.9 -modify it under the terms of the GNU General Public License
   31.10 -as published by the Free Software Foundation; either version 2
   31.11 -of the License, or (at your option) any later version.
   31.12 -
   31.13 -This program is distributed in the hope that it will be useful,
   31.14 -but WITHOUT ANY WARRANTY; without even the implied warranty of
   31.15 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   31.16 -GNU General Public License for more details.
   31.17 -
   31.18 -You should have received a copy of the GNU General Public License
   31.19 -along with this program; if not, write to the Free Software
   31.20 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   31.21 -*/
   31.22 -
   31.23 -#if !defined(_XENVBD_H_)
   31.24 -#define _XENVBD_H_
   31.25 -
   31.26 -#include <ntddk.h>
   31.27 -#include <wdm.h>
   31.28 -#include <initguid.h>
   31.29 -#define NTSTRSAFE_LIB
   31.30 -#include <ntstrsafe.h>
   31.31 -#include <storport.h>
   31.32 -#include <ntddscsi.h>
   31.33 -#include <ntdddisk.h>
   31.34 -#include <stdlib.h>
   31.35 -
   31.36 -#define __DRIVER_NAME "XenVbd"
   31.37 -
   31.38 -#include <xen_windows.h>
   31.39 -#include <xen_public.h>
   31.40 -#include <io/protocols.h>
   31.41 -#include <memory.h>
   31.42 -#include <event_channel.h>
   31.43 -#include <hvm/params.h>
   31.44 -#include <hvm/hvm_op.h>
   31.45 -#include <io/ring.h>
   31.46 -#include <io/blkif.h>
   31.47 -#include <io/xenbus.h>
   31.48 -
   31.49 -#define XENVBD_POOL_TAG (ULONG) 'XVBD'
   31.50 -
   31.51 -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
   31.52 -#define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
   31.53 -#define BLK_OTHER_RING_SIZE __RING_SIZE((blkif_other_sring_t *)0, PAGE_SIZE)
   31.54 -
   31.55 -#define SCSIOP_UNMAP 0x42
   31.56 -
   31.57 -#define VPD_BLOCK_LIMITS 0xB0
   31.58 -
   31.59 -#if defined(__x86_64__)
   31.60 -#pragma pack(push, 4)
   31.61 -#endif
   31.62 -struct blkif_other_request {
   31.63 -  uint8_t operation;
   31.64 -  uint8_t nr_segments;
   31.65 -  blkif_vdev_t handle;
   31.66 -  uint64_t id;
   31.67 -  blkif_sector_t sector_number;
   31.68 -  struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
   31.69 -};
   31.70 -struct blkif_other_response {
   31.71 -  uint64_t id;
   31.72 -  uint8_t operation;
   31.73 -  int16_t status;
   31.74 -};
   31.75 -#if defined(__x86_64__)
   31.76 -#pragma pack(pop)
   31.77 -#endif
   31.78 -
   31.79 -typedef struct blkif_other_request blkif_other_request_t;
   31.80 -typedef struct blkif_other_response blkif_other_response_t;
   31.81 -DEFINE_RING_TYPES(blkif_other, struct blkif_other_request, struct blkif_other_response);
   31.82 -
   31.83 -typedef struct {
   31.84 -  LIST_ENTRY list_entry;
   31.85 -  PSCSI_REQUEST_BLOCK srb;
   31.86 -  ULONG length; /* cached srb length */
   31.87 -  ULONG offset; /* current srb offset */
   31.88 -  ULONG outstanding_requests; /* number of requests sent to xen for this srb */
   31.89 -  BOOLEAN error; /* true if any sub requests have returned an error */
   31.90 -} srb_list_entry_t;
   31.91 -
   31.92 -typedef struct {
   31.93 -  blkif_request_t req;
   31.94 -  srb_list_entry_t *srb_list_entry;
   31.95 -  PSCSI_REQUEST_BLOCK srb;
   31.96 -  PVOID system_address;
   31.97 -  ULONG length;
   31.98 -  BOOLEAN aligned_buffer_in_use;
   31.99 -  BOOLEAN reset;
  31.100 -  #if DBG && NTDDI_VERSION >= NTDDI_WINXP
  31.101 -  LARGE_INTEGER ring_submit_time;
  31.102 -  #endif
  31.103 -} blkif_shadow_t;
  31.104 -
  31.105 -#define MAX_SHADOW_ENTRIES  64
  31.106 -#define SHADOW_ID_ID_MASK   0x03FF /* maximum of 1024 requests - currently use a maximum of 64 though */
  31.107 -#define SHADOW_ID_DUMP_FLAG 0x8000 /* indicates the request was generated by dump mode */
  31.108 -
  31.109 -#define SHADOW_ENTRIES min(MAX_SHADOW_ENTRIES, min(BLK_RING_SIZE, BLK_OTHER_RING_SIZE))
  31.110 -
  31.111 -typedef enum {
  31.112 -  XENVBD_DEVICETYPE_UNKNOWN,
  31.113 -  XENVBD_DEVICETYPE_DISK,
  31.114 -  XENVBD_DEVICETYPE_CDROM,
  31.115 -  XENVBD_DEVICETYPE_CONTROLLER // Not yet used
  31.116 -} XENVBD_DEVICETYPE;
  31.117 -
  31.118 -typedef enum {
  31.119 -  XENVBD_DEVICEMODE_UNKNOWN,
  31.120 -  XENVBD_DEVICEMODE_READ,
  31.121 -  XENVBD_DEVICEMODE_WRITE
  31.122 -} XENVBD_DEVICEMODE;
  31.123 -
  31.124 -#define RING_DETECT_STATE_NOT_STARTED  0
  31.125 -#define RING_DETECT_STATE_DETECT1      1
  31.126 -#define RING_DETECT_STATE_DETECT2      2
  31.127 -#define RING_DETECT_STATE_COMPLETE     3
  31.128 -
  31.129 -/* if this is ever increased to more than 1 then we need a way of tracking it properly */
  31.130 -#define DUMP_MODE_UNALIGNED_PAGES 1 /* only for unaligned buffer use */
  31.131 -
  31.132 -#define VBD_STATUS_INITIALISING 0
  31.133 -#define VBD_STATUS_INACTIVE     1
  31.134 -#define VBD_STATUS_ACTIVE       2
  31.135 -
  31.136 -struct
  31.137 -{
  31.138 -  ULONG vbd_status;
  31.139 -  STOR_DPC dpc;
  31.140 -  blkif_shadow_t shadows[MAX_SHADOW_ENTRIES];
  31.141 -  USHORT shadow_free_list[MAX_SHADOW_ENTRIES];
  31.142 -  USHORT shadow_free;
  31.143 -  USHORT shadow_min_free;
  31.144 -  ULONG grant_tag;
  31.145 -  PDEVICE_OBJECT pdo;
  31.146 -  XN_HANDLE handle;
  31.147 -  evtchn_port_t event_channel;
  31.148 -  blkif_front_ring_t ring;
  31.149 -  blkif_sring_t *sring;
  31.150 -  grant_ref_t sring_gref; 
  31.151 -  ULONG backend_state;
  31.152 -  ULONG frontend_state;
  31.153 -  UCHAR last_sense_key;
  31.154 -  UCHAR last_additional_sense_code;
  31.155 -  blkif_response_t tmp_rep;
  31.156 -  XENVBD_DEVICETYPE device_type;
  31.157 -  XENVBD_DEVICEMODE device_mode;
  31.158 -  ULONG bytes_per_sector; /* 512 for disk, 2048 for CDROM) */
  31.159 -  ULONG hw_bytes_per_sector; /* underlying hardware format, eg 4K */
  31.160 -  ULONGLONG total_sectors;
  31.161 -  ULONG feature_flush_cache;
  31.162 -  ULONG feature_discard;
  31.163 -  ULONG feature_barrier;
  31.164 -  LIST_ENTRY srb_list;
  31.165 -  BOOLEAN aligned_buffer_in_use;
  31.166 -  ULONG aligned_buffer_size;
  31.167 -  PVOID aligned_buffer;
  31.168 -/*  
  31.169 -  ULONGLONG interrupts;
  31.170 -  ULONGLONG aligned_requests;
  31.171 -  ULONGLONG aligned_bytes;
  31.172 -  ULONGLONG unaligned_requests;
  31.173 -  ULONGLONG unaligned_bytes;
  31.174 -*/
  31.175 -  /* this is the size of the buffer to allocate at the end of DeviceExtenstion. It includes an extra PAGE_SIZE-1 bytes to assure that we can always align to PAGE_SIZE */
  31.176 -  #define UNALIGNED_BUFFER_DATA_SIZE ((BLKIF_MAX_SEGMENTS_PER_REQUEST + 1) * PAGE_SIZE - 1)
  31.177 -  #define UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE ((DUMP_MODE_UNALIGNED_PAGES + 1) * PAGE_SIZE - 1)
  31.178 -  /* this has to be right at the end of DeviceExtension */
  31.179 -  /* can't allocate too much data in dump mode so size DeviceExtensionSize accordingly */
  31.180 -  UCHAR aligned_buffer_data[1];
  31.181 -} typedef XENVBD_DEVICE_DATA, *PXENVBD_DEVICE_DATA;
  31.182 -
  31.183 -#endif
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/xenvbd_common/common.h	Sat Feb 02 18:51:07 2013 +1100
    32.3 @@ -0,0 +1,69 @@
    32.4 +/*
    32.5 +PV Drivers for Windows Xen HVM Domains
    32.6 +Copyright (C) 2013 James Harper
    32.7 +
    32.8 +This program is free software; you can redistribute it and/or
    32.9 +modify it under the terms of the GNU General Public License
   32.10 +as published by the Free Software Foundation; either version 2
   32.11 +of the License, or (at your option) any later version.
   32.12 +
   32.13 +This program is distributed in the hope that it will be useful,
   32.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   32.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   32.16 +GNU General Public License for more details.
   32.17 +
   32.18 +You should have received a copy of the GNU General Public License
   32.19 +along with this program; if not, write to the Free Software
   32.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   32.21 +*/
   32.22 +
   32.23 +#define SCSIOP_UNMAP 0x42
   32.24 +#define VPD_BLOCK_LIMITS 0xB0
   32.25 +
   32.26 +#define XENVBD_POOL_TAG (ULONG) 'XVBD'
   32.27 +
   32.28 +#define DEVICE_STATE_DISCONNECTED  0 /* -> INITIALISING */
   32.29 +#define DEVICE_STATE_INITIALISING  1 /* -> INACTIVE | ACTIVE */
   32.30 +#define DEVICE_STATE_INACTIVE      2
   32.31 +#define DEVICE_STATE_ACTIVE        3 /* -> DISCONNECTING */
   32.32 +#define DEVICE_STATE_DISCONNECTING 4 /* -> DISCONNECTED */
   32.33 +
   32.34 +#define SCSI_DEVICE_MANUFACTURER "XEN     "
   32.35 +#define SCSI_DISK_MODEL          "PV DISK          "
   32.36 +#define SCSI_CDROM_MODEL         "PV CDROM         "
   32.37 +
   32.38 +typedef enum {
   32.39 +  XENVBD_DEVICETYPE_UNKNOWN,
   32.40 +  XENVBD_DEVICETYPE_DISK,
   32.41 +  XENVBD_DEVICETYPE_CDROM,
   32.42 +  XENVBD_DEVICETYPE_CONTROLLER // Not yet used
   32.43 +} XENVBD_DEVICETYPE;
   32.44 +
   32.45 +typedef enum {
   32.46 +  XENVBD_DEVICEMODE_UNKNOWN,
   32.47 +  XENVBD_DEVICEMODE_READ,
   32.48 +  XENVBD_DEVICEMODE_WRITE
   32.49 +} XENVBD_DEVICEMODE;
   32.50 +
   32.51 +typedef struct {
   32.52 +  LIST_ENTRY list_entry;
   32.53 +  PSCSI_REQUEST_BLOCK srb;
   32.54 +  ULONG length; /* cached srb length */
   32.55 +  ULONG offset; /* current srb offset */
   32.56 +  ULONG outstanding_requests; /* number of requests sent to xen for this srb */
   32.57 +  BOOLEAN error; /* true if any sub requests have returned an error */
   32.58 +} srb_list_entry_t;
   32.59 +
   32.60 +typedef struct {
   32.61 +  blkif_request_t req;
   32.62 +  srb_list_entry_t *srb_list_entry;
   32.63 +  PSCSI_REQUEST_BLOCK srb;
   32.64 +  PVOID system_address;
   32.65 +  ULONG length;
   32.66 +  BOOLEAN aligned_buffer_in_use;
   32.67 +  BOOLEAN reset;
   32.68 +  #if DBG && NTDDI_VERSION >= NTDDI_WINXP
   32.69 +  LARGE_INTEGER ring_submit_time;
   32.70 +  #endif
   32.71 +} blkif_shadow_t;
   32.72 +
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/xenvbd_common/common_miniport.h	Sat Feb 02 18:51:07 2013 +1100
    33.3 @@ -0,0 +1,1268 @@
    33.4 +/*
    33.5 +PV Drivers for Windows Xen HVM Domains
    33.6 +Copyright (C) 2013 James Harper
    33.7 +
    33.8 +This program is free software; you can redistribute it and/or
    33.9 +modify it under the terms of the GNU General Public License
   33.10 +as published by the Free Software Foundation; either version 2
   33.11 +of the License, or (at your option) any later version.
   33.12 +
   33.13 +This program is distributed in the hope that it will be useful,
   33.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   33.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   33.16 +GNU General Public License for more details.
   33.17 +
   33.18 +You should have received a copy of the GNU General Public License
   33.19 +along with this program; if not, write to the Free Software
   33.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   33.21 +*/
   33.22 +
   33.23 +#if defined(__x86_64__)
   33.24 +  #define LongLongToPtr(x) (PVOID)(x)
   33.25 +#else
   33.26 +  #define LongLongToPtr(x) UlongToPtr(x)
   33.27 +#endif
   33.28 +
   33.29 +#if defined(__x86_64__)
   33.30 +  #define ABI_PROTOCOL "x86_64-abi"
   33.31 +#else
   33.32 +  #define ABI_PROTOCOL "x86_32-abi"
   33.33 +#endif
   33.34 +
   33.35 +ULONGLONG parse_numeric_string(PCHAR string) {
   33.36 +  ULONGLONG val = 0;
   33.37 +  while (*string != 0) {
   33.38 +    val = val * 10 + (*string - '0');
   33.39 +    string++;
   33.40 +  }
   33.41 +  return val;
   33.42 +}
   33.43 +
   33.44 +/* called with StartIoLock held */
   33.45 +static blkif_shadow_t *
   33.46 +get_shadow_from_freelist(PXENVBD_DEVICE_DATA xvdd)
   33.47 +{
   33.48 +  if (xvdd->shadow_free == 0) {
   33.49 +    KdPrint((__DRIVER_NAME "     No more shadow entries\n"));
   33.50 +    return NULL;
   33.51 +  }
   33.52 +  xvdd->shadow_free--;
   33.53 +  if (xvdd->shadow_free < xvdd->shadow_min_free)
   33.54 +    xvdd->shadow_min_free = xvdd->shadow_free;
   33.55 +  return &xvdd->shadows[xvdd->shadow_free_list[xvdd->shadow_free]];
   33.56 +}
   33.57 +
   33.58 +/* called with StartIoLock held */
   33.59 +static VOID
   33.60 +put_shadow_on_freelist(PXENVBD_DEVICE_DATA xvdd, blkif_shadow_t *shadow)
   33.61 +{
   33.62 +  xvdd->shadow_free_list[xvdd->shadow_free] = (USHORT)(shadow->req.id & SHADOW_ID_ID_MASK);
   33.63 +  shadow->srb = NULL;
   33.64 +  shadow->reset = FALSE;
   33.65 +  shadow->aligned_buffer_in_use = FALSE;
   33.66 +  xvdd->shadow_free++;
   33.67 +}
   33.68 +
   33.69 +static __inline ULONG
   33.70 +decode_cdb_length(PSCSI_REQUEST_BLOCK srb)
   33.71 +{
   33.72 +  switch (srb->Cdb[0])
   33.73 +  {
   33.74 +  case SCSIOP_READ:
   33.75 +  case SCSIOP_WRITE:
   33.76 +    return ((ULONG)(UCHAR)srb->Cdb[7] << 8) | (ULONG)(UCHAR)srb->Cdb[8];
   33.77 +  case SCSIOP_READ16:
   33.78 +  case SCSIOP_WRITE16:
   33.79 +    return ((ULONG)(UCHAR)srb->Cdb[10] << 24) | ((ULONG)(UCHAR)srb->Cdb[11] << 16) | ((ULONG)(UCHAR)srb->Cdb[12] << 8) | (ULONG)(UCHAR)srb->Cdb[13];    
   33.80 +  default:
   33.81 +    return 0;
   33.82 +  }
   33.83 +}
   33.84 +
   33.85 +static blkif_response_t *
   33.86 +XenVbd_GetResponse(PXENVBD_DEVICE_DATA xvdd, int i) {
   33.87 +  return RING_GET_RESPONSE(&xvdd->ring, i);
   33.88 +}
   33.89 +
   33.90 +static VOID
   33.91 +XenVbd_PutRequest(PXENVBD_DEVICE_DATA xvdd, blkif_request_t *req) {
   33.92 +  *RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt) = *req;
   33.93 +  xvdd->ring.req_prod_pvt++;
   33.94 +}
   33.95 +
   33.96 +static VOID
   33.97 +XenVbd_PutSrbOnList(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb) {
   33.98 +  srb_list_entry_t *srb_entry = srb->SrbExtension;
   33.99 +  srb_entry->srb = srb;
  33.100 +  srb_entry->outstanding_requests = 0;
  33.101 +  srb_entry->length = srb->DataTransferLength;
  33.102 +  srb_entry->offset = 0;
  33.103 +  srb_entry->error = FALSE;
  33.104 +  InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
  33.105 +}
  33.106 +
  33.107 +static __inline ULONGLONG
  33.108 +decode_cdb_sector(PSCSI_REQUEST_BLOCK srb)
  33.109 +{
  33.110 +  ULONGLONG sector;
  33.111 +  
  33.112 +  switch (srb->Cdb[0])
  33.113 +  {
  33.114 +  case SCSIOP_READ:
  33.115 +  case SCSIOP_WRITE:
  33.116 +    sector = ((ULONG)(UCHAR)srb->Cdb[2] << 24) | ((ULONG)(UCHAR)srb->Cdb[3] << 16) | ((ULONG)(UCHAR)srb->Cdb[4] << 8) | (ULONG)(UCHAR)srb->Cdb[5];
  33.117 +    break;
  33.118 +  case SCSIOP_READ16:
  33.119 +  case SCSIOP_WRITE16:
  33.120 +    sector = ((ULONGLONG)(UCHAR)srb->Cdb[2] << 56) | ((ULONGLONG)(UCHAR)srb->Cdb[3] << 48)
  33.121 +           | ((ULONGLONG)(UCHAR)srb->Cdb[4] << 40) | ((ULONGLONG)(UCHAR)srb->Cdb[5] << 32)
  33.122 +           | ((ULONGLONG)(UCHAR)srb->Cdb[6] << 24) | ((ULONGLONG)(UCHAR)srb->Cdb[7] << 16)
  33.123 +           | ((ULONGLONG)(UCHAR)srb->Cdb[8] << 8) | ((ULONGLONG)(UCHAR)srb->Cdb[9]);
  33.124 +    //KdPrint((__DRIVER_NAME "     sector_number = %d (high) %d (low)\n", (ULONG)(sector >> 32), (ULONG)sector));
  33.125 +    break;
  33.126 +  default:
  33.127 +    sector = 0;
  33.128 +    break;
  33.129 +  }
  33.130 +  return sector;
  33.131 +}
  33.132 +
  33.133 +static __inline BOOLEAN
  33.134 +decode_cdb_is_read(PSCSI_REQUEST_BLOCK srb)
  33.135 +{
  33.136 +  switch (srb->Cdb[0])
  33.137 +  {
  33.138 +  case SCSIOP_READ:
  33.139 +  case SCSIOP_READ16:
  33.140 +    return TRUE;
  33.141 +  case SCSIOP_WRITE:
  33.142 +  case SCSIOP_WRITE16:
  33.143 +    return FALSE;
  33.144 +  default:
  33.145 +    return FALSE;
  33.146 +  }
  33.147 +}
  33.148 +
  33.149 +static ULONG
  33.150 +XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, UCHAR sense_key, UCHAR additional_sense_code)
  33.151 +{
  33.152 +  PSENSE_DATA sd = srb->SenseInfoBuffer;
  33.153 + 
  33.154 +  UNREFERENCED_PARAMETER(xvdd);
  33.155 +  
  33.156 +  if (!srb->SenseInfoBuffer)
  33.157 +    return 0;
  33.158 +  
  33.159 +  sd->ErrorCode = 0x70;
  33.160 +  sd->Valid = 1;
  33.161 +  sd->SenseKey = sense_key;
  33.162 +  sd->AdditionalSenseLength = sizeof(SENSE_DATA) - FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
  33.163 +  sd->AdditionalSenseCode = additional_sense_code;
  33.164 +  return sizeof(SENSE_DATA);
  33.165 +}
  33.166 +
  33.167 +static VOID
  33.168 +XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
  33.169 +{
  33.170 +  if (srb->SrbStatus == SRB_STATUS_SUCCESS || srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)
  33.171 +    return;
  33.172 +  XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
  33.173 +  srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
  33.174 +}
  33.175 +
  33.176 +/* called with StartIo lock held */
  33.177 +static VOID
  33.178 +XenVbd_HandleEvent(PXENVBD_DEVICE_DATA xvdd)
  33.179 +{
  33.180 +  PSCSI_REQUEST_BLOCK srb;
  33.181 +  RING_IDX i, rp;
  33.182 +  ULONG j;
  33.183 +  blkif_response_t *rep;
  33.184 +  //int block_count;
  33.185 +  int more_to_do = TRUE;
  33.186 +  blkif_shadow_t *shadow;
  33.187 +  srb_list_entry_t *srb_entry;
  33.188 +
  33.189 +  //if (dump_mode)
  33.190 +  //FUNCTION_ENTER();
  33.191 +
  33.192 +  while (more_to_do) {
  33.193 +    rp = xvdd->ring.sring->rsp_prod;
  33.194 +    KeMemoryBarrier();
  33.195 +    for (i = xvdd->ring.rsp_cons; i != rp; i++) {
  33.196 +      rep = XenVbd_GetResponse(xvdd, i);
  33.197 +      shadow = &xvdd->shadows[rep->id & SHADOW_ID_ID_MASK];
  33.198 +      if (shadow->reset) {
  33.199 +        KdPrint((__DRIVER_NAME "     discarding reset shadow\n"));
  33.200 +        for (j = 0; j < shadow->req.nr_segments; j++) {
  33.201 +          XnEndAccess(xvdd->handle,
  33.202 +            shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
  33.203 +        }
  33.204 +      } else if (dump_mode && !(rep->id & SHADOW_ID_DUMP_FLAG)) {
  33.205 +        KdPrint((__DRIVER_NAME "     discarding stale (non-dump-mode) shadow\n"));
  33.206 +      } else {
  33.207 +        srb = shadow->srb;
  33.208 +        NT_ASSERT(srb);
  33.209 +        srb_entry = srb->SrbExtension;
  33.210 +        NT_ASSERT(srb_entry);
  33.211 +        /* a few errors occur in dump mode because Xen refuses to allow us to map pages we are using for other stuff. Just ignore them */
  33.212 +        if (rep->status == BLKIF_RSP_OKAY || (dump_mode &&  dump_mode_errors++ < DUMP_MODE_ERROR_LIMIT)) {
  33.213 +          srb->SrbStatus = SRB_STATUS_SUCCESS;
  33.214 +        } else {
  33.215 +          KdPrint((__DRIVER_NAME "     Xen Operation returned error\n"));
  33.216 +          if (decode_cdb_is_read(srb))
  33.217 +            KdPrint((__DRIVER_NAME "     Operation = Read\n"));
  33.218 +          else
  33.219 +            KdPrint((__DRIVER_NAME "     Operation = Write\n"));
  33.220 +          srb_entry->error = TRUE;
  33.221 +        }
  33.222 +        if (shadow->aligned_buffer_in_use) {
  33.223 +          NT_ASSERT(xvdd->aligned_buffer_in_use);
  33.224 +          xvdd->aligned_buffer_in_use = FALSE;
  33.225 +          if (srb->SrbStatus == SRB_STATUS_SUCCESS && decode_cdb_is_read(srb))
  33.226 +            memcpy((PUCHAR)shadow->system_address, xvdd->aligned_buffer, shadow->length);
  33.227 +        }
  33.228 +        for (j = 0; j < shadow->req.nr_segments; j++) {
  33.229 +          XnEndAccess(xvdd->handle, shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
  33.230 +        }
  33.231 +        srb_entry->outstanding_requests--;
  33.232 +        if (!srb_entry->outstanding_requests && srb_entry->offset == srb_entry->length) {
  33.233 +          if (srb_entry->error) {
  33.234 +            srb->SrbStatus = SRB_STATUS_ERROR;
  33.235 +            srb->ScsiStatus = 0x02;
  33.236 +            xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
  33.237 +            xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
  33.238 +            XenVbd_MakeAutoSense(xvdd, srb);
  33.239 +          }
  33.240 +          //FUNCTION_MSG("Completing Srb = %p\n", srb);
  33.241 +          SxxxPortNotification(RequestComplete, xvdd, srb);
  33.242 +          SxxxPortNotification(NextLuRequest, xvdd, 0, 0, 0);
  33.243 +        }
  33.244 +      }
  33.245 +      put_shadow_on_freelist(xvdd, shadow);
  33.246 +    }
  33.247 +
  33.248 +    xvdd->ring.rsp_cons = i;
  33.249 +    if (i != xvdd->ring.req_prod_pvt) {
  33.250 +      RING_FINAL_CHECK_FOR_RESPONSES(&xvdd->ring, more_to_do);
  33.251 +    } else {
  33.252 +      xvdd->ring.sring->rsp_event = i + 1;
  33.253 +      more_to_do = FALSE;
  33.254 +    }
  33.255 +  }
  33.256 +
  33.257 +  if (dump_mode || xvdd->device_state == DEVICE_STATE_ACTIVE) {
  33.258 +    XenVbd_ProcessSrbList(xvdd);
  33.259 +  } else if (xvdd->shadow_free == SHADOW_ENTRIES) {
  33.260 +    FUNCTION_MSG("ring now empty - scheduling workitem for disconnect\n");
  33.261 +    XenVbd_CompleteDisconnect(xvdd);
  33.262 +    //IoQueueWorkItem(xvdd->disconnect_workitem, XenVbd_DisconnectWorkItem, DelayedWorkQueue, xvdd);
  33.263 +  }
  33.264 +  //if (dump_mode)
  33.265 +  //FUNCTION_EXIT();
  33.266 +  return;
  33.267 +}
  33.268 +
  33.269 +/* called with StartIoLock held */
  33.270 +/* returns TRUE if something was put on the ring and notify might be required */
  33.271 +static BOOLEAN
  33.272 +XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
  33.273 +{
  33.274 +  srb_list_entry_t *srb_entry = srb->SrbExtension;
  33.275 +  /* sector_number and block_count are the adjusted-to-512-byte-sector values */
  33.276 +  ULONGLONG sector_number;
  33.277 +  ULONG block_count;
  33.278 +  blkif_shadow_t *shadow;
  33.279 +  ULONG remaining, offset, length;
  33.280 +  grant_ref_t gref;
  33.281 +  PUCHAR ptr;
  33.282 +  int i;
  33.283 +  PVOID system_address;
  33.284 +
  33.285 +  //if (dump_mode) FUNCTION_ENTER();
  33.286 +  //FUNCTION_MSG("Srb = %p\n", srb);
  33.287 +
  33.288 +  //FUNCTION_MSG("aligned_buffer_in_use = %d\n", xvdd->aligned_buffer_in_use);
  33.289 +  //FUNCTION_MSG("shadow_free = %d\n", xvdd->shadow_free);
  33.290 +  
  33.291 +  NT_ASSERT(srb);
  33.292 +
  33.293 +  if (!dump_mode) {
  33.294 +#if 0
  33.295 +    if (StorPortGetSystemAddress(xvdd, srb, &system_address) != STOR_STATUS_SUCCESS) {
  33.296 +      FUNCTION_MSG("Failed to map DataBuffer\n");
  33.297 +      InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
  33.298 +      //if (dump_mode) FUNCTION_EXIT();
  33.299 +      return FALSE;
  33.300 +    }
  33.301 +    system_address = (PUCHAR)system_address + srb_entry->offset;
  33.302 +#endif
  33.303 +    system_address = (PUCHAR)srb->DataBuffer + srb_entry->offset;
  33.304 +  } else {
  33.305 +    //FUNCTION_MSG("DataBuffer = %p\n", srb->DataBuffer);
  33.306 +    system_address = (PUCHAR)srb->DataBuffer + srb_entry->offset;
  33.307 +  }
  33.308 +  block_count = decode_cdb_length(srb);
  33.309 +  sector_number = decode_cdb_sector(srb);
  33.310 +  block_count *= xvdd->bytes_per_sector / 512;
  33.311 +  sector_number *= xvdd->bytes_per_sector / 512;
  33.312 +
  33.313 +  NT_ASSERT(block_count * 512 == srb->DataTransferLength);
  33.314 +  
  33.315 +  sector_number += srb_entry->offset / 512;
  33.316 +  block_count -= srb_entry->offset / 512;
  33.317 +
  33.318 +  NT_ASSERT(block_count > 0);
  33.319 +
  33.320 +  /* look for pending writes that overlap this one */
  33.321 +  /* we get warnings from drbd if we don't */
  33.322 +  if (srb_entry->offset == 0) {
  33.323 +    for (i = 0; i < MAX_SHADOW_ENTRIES; i++) {
  33.324 +      PSCSI_REQUEST_BLOCK srb2;
  33.325 +      ULONGLONG sector_number2;
  33.326 +      ULONG block_count2;
  33.327 +      
  33.328 +      srb2 = xvdd->shadows[i].srb;
  33.329 +      if (!srb2)
  33.330 +        continue;
  33.331 +      if (decode_cdb_is_read(srb2))
  33.332 +        continue;
  33.333 +      block_count2 = decode_cdb_length(srb2);;
  33.334 +      block_count2 *= xvdd->bytes_per_sector / 512;
  33.335 +      sector_number2 = decode_cdb_sector(srb2);
  33.336 +      sector_number2 *= xvdd->bytes_per_sector / 512;
  33.337 +      
  33.338 +      if (sector_number < sector_number2 && sector_number + block_count <= sector_number2)
  33.339 +        continue;
  33.340 +      if (sector_number2 < sector_number && sector_number2 + block_count2 <= sector_number)
  33.341 +        continue;
  33.342 +
  33.343 +      KdPrint((__DRIVER_NAME "     Concurrent outstanding write detected (%I64d, %d) (%I64d, %d)\n",
  33.344 +        sector_number, block_count, sector_number2, block_count2));
  33.345 +      break;
  33.346 +    }
  33.347 +    if (i != MAX_SHADOW_ENTRIES) {
  33.348 +      /* put the srb back at the start of the queue */
  33.349 +      InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
  33.350 +      //if (dump_mode) FUNCTION_EXIT();
  33.351 +      return FALSE;
  33.352 +    }
  33.353 +  }
  33.354 +  
  33.355 +  shadow = get_shadow_from_freelist(xvdd);
  33.356 +  if (!shadow) {
  33.357 +    /* put the srb back at the start of the queue */
  33.358 +    InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
  33.359 +    //if (dump_mode) FUNCTION_EXIT();
  33.360 +    return FALSE;
  33.361 +  }
  33.362 +  NT_ASSERT(!shadow->aligned_buffer_in_use);
  33.363 +  NT_ASSERT(!shadow->srb);
  33.364 +  shadow->req.sector_number = sector_number;
  33.365 +  shadow->req.handle = 0;
  33.366 +  shadow->req.operation = decode_cdb_is_read(srb)?BLKIF_OP_READ:BLKIF_OP_WRITE;
  33.367 +  shadow->req.nr_segments = 0;
  33.368 +  shadow->srb = srb;
  33.369 +  shadow->length = 0;
  33.370 +  shadow->system_address = system_address;
  33.371 +  shadow->reset = FALSE;
  33.372 +
  33.373 +  if (!dump_mode) {
  33.374 +    if ((ULONG_PTR)shadow->system_address & 511) {
  33.375 +      xvdd->aligned_buffer_in_use = TRUE;
  33.376 +      /* limit to aligned_buffer_size */
  33.377 +      block_count = min(block_count, xvdd->aligned_buffer_size / 512);
  33.378 +      ptr = (PUCHAR)xvdd->aligned_buffer;
  33.379 +      if (!decode_cdb_is_read(srb))
  33.380 +        memcpy(ptr, shadow->system_address, block_count * 512);
  33.381 +      shadow->aligned_buffer_in_use = TRUE;
  33.382 +    } else {
  33.383 +      ptr = (PUCHAR)shadow->system_address;
  33.384 +      shadow->aligned_buffer_in_use = FALSE;
  33.385 +    }
  33.386 +  } else {
  33.387 +    NT_ASSERT(!((ULONG_PTR)shadow->system_address & 511));
  33.388 +    ptr = shadow->system_address;
  33.389 +    shadow->aligned_buffer_in_use = FALSE;
  33.390 +  }
  33.391 +
  33.392 +  //KdPrint((__DRIVER_NAME "     sector_number = %d, block_count = %d\n", (ULONG)sector_number, block_count));
  33.393 +  //KdPrint((__DRIVER_NAME "     DataBuffer   = %p\n", srb->DataBuffer));
  33.394 +  //KdPrint((__DRIVER_NAME "     system_address   = %p\n", shadow->system_address));
  33.395 +  //KdPrint((__DRIVER_NAME "     offset   = %d, length = %d\n", srb_entry->offset, srb_entry->length));
  33.396 +  //KdPrint((__DRIVER_NAME "     ptr   = %p\n", ptr));
  33.397 +
  33.398 +  //KdPrint((__DRIVER_NAME "     handle = %d\n", shadow->req.handle));
  33.399 +  //KdPrint((__DRIVER_NAME "     operation = %d\n", shadow->req.operation));
  33.400 +  
  33.401 +  remaining = block_count * 512;
  33.402 +  while (remaining > 0 && shadow->req.nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST) {
  33.403 +    PHYSICAL_ADDRESS physical_address;
  33.404 +
  33.405 +    if (!dump_mode) {
  33.406 +      physical_address = MmGetPhysicalAddress(ptr);
  33.407 +    } else {
  33.408 +#if 0
  33.409 +      ULONG length;       
  33.410 +      physical_address = StorPortGetPhysicalAddress(xvdd, srb, ptr, &length);
  33.411 +#endif
  33.412 +      physical_address = MmGetPhysicalAddress(ptr);
  33.413 +    }
  33.414 +    gref = XnGrantAccess(xvdd->handle,
  33.415 +           (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, xvdd->grant_tag);
  33.416 +    if (gref == INVALID_GRANT_REF) {
  33.417 +      ULONG i;
  33.418 +      for (i = 0; i < shadow->req.nr_segments; i++) {
  33.419 +        XnEndAccess(xvdd->handle,
  33.420 +          shadow->req.seg[i].gref, FALSE, xvdd->grant_tag);
  33.421 +      }
  33.422 +      if (shadow->aligned_buffer_in_use) {
  33.423 +        shadow->aligned_buffer_in_use = FALSE;
  33.424 +        xvdd->aligned_buffer_in_use = FALSE;
  33.425 +      }
  33.426 +      /* put the srb back at the start of the queue */
  33.427 +      InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
  33.428 +      put_shadow_on_freelist(xvdd, shadow);
  33.429 +      KdPrint((__DRIVER_NAME "     Out of gref's. Deferring\n"));
  33.430 +      /* TODO: what if there are no requests currently in progress to kick the queue again?? timer? */
  33.431 +      return FALSE;
  33.432 +    }
  33.433 +    offset = physical_address.LowPart & (PAGE_SIZE - 1);
  33.434 +    length = min(PAGE_SIZE - offset, remaining);
  33.435 +    NT_ASSERT((offset & 511) == 0);
  33.436 +    NT_ASSERT((length & 511) == 0);
  33.437 +    NT_ASSERT(offset + length <= PAGE_SIZE);
  33.438 +    shadow->req.seg[shadow->req.nr_segments].gref = gref;
  33.439 +    shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset / 512);
  33.440 +    shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) / 512) - 1);
  33.441 +    remaining -= length;
  33.442 +    ptr += length;
  33.443 +    shadow->length += length;
  33.444 +    shadow->req.nr_segments++;
  33.445 +  }
  33.446 +  srb_entry->offset += shadow->length;
  33.447 +  srb_entry->outstanding_requests++;
  33.448 +  if (srb_entry->offset < srb_entry->length) {
  33.449 +    if (dump_mode) KdPrint((__DRIVER_NAME "     inserting back into list\n"));
  33.450 +    /* put the srb back at the start of the queue to continue on the next request */
  33.451 +    InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
  33.452 +  }
  33.453 +  XenVbd_PutRequest(xvdd, &shadow->req);
  33.454 +  //if (dump_mode)
  33.455 +  //FUNCTION_EXIT();
  33.456 +  return TRUE;
  33.457 +}
  33.458 +
  33.459 +
  33.460 +static ULONG
  33.461 +XenVbd_FillModePage(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
  33.462 +{
  33.463 +  PMODE_PARAMETER_HEADER parameter_header = NULL;
  33.464 +  PMODE_PARAMETER_HEADER10 parameter_header10 = NULL;
  33.465 +  PMODE_PARAMETER_BLOCK param_block;
  33.466 +  PMODE_FORMAT_PAGE format_page;
  33.467 +  ULONG offset = 0;
  33.468 +  UCHAR buffer[1024];
  33.469 +  BOOLEAN valid_page = FALSE;
  33.470 +  BOOLEAN cdb_llbaa;
  33.471 +  BOOLEAN cdb_dbd;
  33.472 +  UCHAR cdb_page_code;
  33.473 +  USHORT cdb_allocation_length;
  33.474 +
  33.475 +  UNREFERENCED_PARAMETER(xvdd);
  33.476 +
  33.477 +  RtlZeroMemory(srb->DataBuffer, srb->DataTransferLength);
  33.478 +  RtlZeroMemory(buffer, ARRAY_SIZE(buffer));
  33.479 +  offset = 0;
  33.480 +
  33.481 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  33.482 +  
  33.483 +  switch (srb->Cdb[0])
  33.484 +  {
  33.485 +  case SCSIOP_MODE_SENSE:
  33.486 +    cdb_llbaa = FALSE;
  33.487 +    cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
  33.488 +    cdb_page_code = srb->Cdb[2] & 0x3f;
  33.489 +    cdb_allocation_length = srb->Cdb[4];
  33.490 +    parameter_header = (PMODE_PARAMETER_HEADER)&buffer[offset];
  33.491 +    parameter_header->MediumType = 0;
  33.492 +    parameter_header->DeviceSpecificParameter = 0;
  33.493 +    if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
  33.494 +    {
  33.495 +      KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
  33.496 +      parameter_header->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT; 
  33.497 +    }
  33.498 +    offset += sizeof(MODE_PARAMETER_HEADER);
  33.499 +    break;
  33.500 +  case SCSIOP_MODE_SENSE10:
  33.501 +    cdb_llbaa = (BOOLEAN)!!(srb->Cdb[1] & 16);
  33.502 +    cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
  33.503 +    cdb_page_code = srb->Cdb[2] & 0x3f;
  33.504 +    cdb_allocation_length = (srb->Cdb[7] << 8) | srb->Cdb[8];
  33.505 +    parameter_header10 = (PMODE_PARAMETER_HEADER10)&buffer[offset];
  33.506 +    parameter_header10->MediumType = 0;
  33.507 +    parameter_header10->DeviceSpecificParameter = 0;
  33.508 +    if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
  33.509 +    {
  33.510 +      KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
  33.511 +      parameter_header10->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT; 
  33.512 +    }
  33.513 +    offset += sizeof(MODE_PARAMETER_HEADER10);
  33.514 +    break;
  33.515 +  default:
  33.516 +    KdPrint((__DRIVER_NAME "     SCSIOP_MODE_SENSE_WTF (%02x)\n", (ULONG)srb->Cdb[0]));
  33.517 +    return FALSE;
  33.518 +  }  
  33.519 +  
  33.520 +  if (!cdb_dbd)
  33.521 +  {
  33.522 +    param_block = (PMODE_PARAMETER_BLOCK)&buffer[offset];
  33.523 +    if (xvdd->device_type == XENVBD_DEVICETYPE_DISK)
  33.524 +    {
  33.525 +      if (xvdd->total_sectors >> 32) 
  33.526 +      {
  33.527 +        param_block->DensityCode = 0xff;
  33.528 +        param_block->NumberOfBlocks[0] = 0xff;
  33.529 +        param_block->NumberOfBlocks[1] = 0xff;
  33.530 +        param_block->NumberOfBlocks[2] = 0xff;
  33.531 +      }
  33.532 +      else
  33.533 +      {
  33.534 +        param_block->DensityCode = (UCHAR)((xvdd->total_sectors >> 24) & 0xff);
  33.535 +        param_block->NumberOfBlocks[0] = (UCHAR)((xvdd->total_sectors >> 16) & 0xff);
  33.536 +        param_block->NumberOfBlocks[1] = (UCHAR)((xvdd->total_sectors >> 8) & 0xff);
  33.537 +        param_block->NumberOfBlocks[2] = (UCHAR)((xvdd->total_sectors >> 0) & 0xff);
  33.538 +      }
  33.539 +      param_block->BlockLength[0] = (UCHAR)((xvdd->bytes_per_sector >> 16) & 0xff);
  33.540 +      param_block->BlockLength[1] = (UCHAR)((xvdd->bytes_per_sector >> 8) & 0xff);
  33.541 +      param_block->BlockLength[2] = (UCHAR)((xvdd->bytes_per_sector >> 0) & 0xff);
  33.542 +    }
  33.543 +    offset += sizeof(MODE_PARAMETER_BLOCK);
  33.544 +  }
  33.545 +  switch (srb->Cdb[0])
  33.546 +  {
  33.547 +  case SCSIOP_MODE_SENSE:
  33.548 +    parameter_header->BlockDescriptorLength = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER));
  33.549 +    break;
  33.550 +  case SCSIOP_MODE_SENSE10:
  33.551 +    parameter_header10->BlockDescriptorLength[0] = (UCHAR)((offset - sizeof(MODE_PARAMETER_HEADER10)) >> 8);