win-pvdrivers

changeset 1004:a5d1d333e0e2

Start of major changes to xenpci interface. Now using xenpci as export driver. storport and xennet6 drivers working but not suspend/resume or dump mode
author James Harper <james.harper@bendigoit.com.au>
date Sun Jan 06 14:08:22 2013 +1100 (2013-01-06)
parents f9248a3eac32
children 4f7d5a8636bd
files common/include/xen_windows.h dirs xennet/xennet6.c xennet/xennet6.h xennet/xennet6_rx.c xennet/xennet6_tx.c xenpci/evtchn.c xenpci/sources xenpci/xenbus.c xenpci/xenpci.def xenpci/xenpci.h xenpci/xenpci_dbgprint.c xenpci/xenpci_export.c xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c xenvbd/sources xenvbd/xenvbd_storport.c xenvbd/xenvbd_storport.h
line diff
     1.1 --- a/common/include/xen_windows.h	Fri Dec 14 21:44:03 2012 +1100
     1.2 +++ b/common/include/xen_windows.h	Sun Jan 06 14:08:22 2013 +1100
     1.3 @@ -213,11 +213,124 @@ the wrong width is used with the wrong d
     1.4  
     1.5  #define INVALID_GRANT_REF 0xFFFFFFFF
     1.6  
     1.7 +#define XN_BASE_FRONTEND 1 /* path is relative to frontend device */
     1.8 +#define XN_BASE_BACKEND  2 /* path is relative to backend device */
     1.9 +#define XN_BASE_GLOBAL   3 /* path is relative to root of xenstore */
    1.10 +
    1.11 +
    1.12 +typedef PVOID XN_HANDLE;
    1.13 +
    1.14 +/* get a handle given a PDO */
    1.15 +typedef XN_HANDLE
    1.16 +(*PXN_GET_HANDLE)(PDEVICE_OBJECT pdo);
    1.17 +
    1.18 +typedef VOID
    1.19 +(*PXN_WATCH_CALLBACK)(PVOID context, char *path);
    1.20 +
    1.21 +typedef VOID
    1.22 +(*PXN_EVENT_CALLBACK)(PVOID context);
    1.23 +
    1.24 +typedef VOID
    1.25 +(*PXN_BACKEND_STATE_CALLBACK)(PVOID context, ULONG state);
    1.26 +
    1.27 +ULONG
    1.28 +XnGetVersion();
    1.29 +
    1.30 +XN_HANDLE
    1.31 +XnOpenDevice(PDEVICE_OBJECT pdo, PXN_BACKEND_STATE_CALLBACK callback, PVOID context);
    1.32 +
    1.33 +VOID
    1.34 +XnCloseDevice(XN_HANDLE handle);
    1.35 +
    1.36 +#define XN_VALUE_TYPE_QEMU_HIDE_FLAGS 1
    1.37 +#define XN_VALUE_TYPE_QEMU_FILTER     2 /* true if qemu devices hidden by device filter, not by qemu */
    1.38 +VOID
    1.39 +XnGetValue(XN_HANDLE handle, ULONG value_type, PVOID value);
    1.40 +
    1.41 +#if 0
    1.42 +PCHAR
    1.43 +XnGetBackendPath(XN_HANDLE handle);
    1.44 +#endif
    1.45 +
    1.46 +#if 0
    1.47 +NTSTATUS
    1.48 +XnAddWatch(XN_HANDLE handle, ULONG base, char *path, PXN_WATCH_CALLBACK callback, PVOID context);
    1.49 +
    1.50 +NTSTATUS
    1.51 +XnRemoveWatch(XN_HANDLE handle, ULONG base, char *path, PXN_WATCH_CALLBACK callback, PVOID context);
    1.52 +#endif
    1.53 +
    1.54 +NTSTATUS
    1.55 +XnReadInt32(XN_HANDLE handle, ULONG base, PCHAR path, ULONG *value);
    1.56 +
    1.57 +NTSTATUS
    1.58 +XnWriteInt32(XN_HANDLE handle, ULONG base, PCHAR path, ULONG value);
    1.59 +
    1.60 +NTSTATUS
    1.61 +XnReadInt64(XN_HANDLE handle, ULONG base, PCHAR path, ULONGLONG *value);
    1.62 +
    1.63 +NTSTATUS
    1.64 +XnWriteInt64(XN_HANDLE handle, ULONG base, PCHAR path, ULONGLONG value);
    1.65 +
    1.66 +NTSTATUS
    1.67 +XnReadString(XN_HANDLE handle, ULONG base, PCHAR path, PCHAR *value);
    1.68 +
    1.69 +NTSTATUS
    1.70 +XnWriteString(XN_HANDLE handle, ULONG base, PCHAR path, PCHAR value);
    1.71 +
    1.72 +NTSTATUS
    1.73 +XnFreeString(XN_HANDLE handle, PCHAR string);
    1.74 +
    1.75 +NTSTATUS
    1.76 +XnNotify(XN_HANDLE handle, evtchn_port_t port);
    1.77 +
    1.78 +grant_ref_t
    1.79 +XnGrantAccess(XN_HANDLE handle, uint32_t frame, int readonly, grant_ref_t ref, ULONG tag);
    1.80 +
    1.81 +BOOLEAN
    1.82 +XnEndAccess(XN_HANDLE handle, grant_ref_t ref, BOOLEAN keepref, ULONG tag);
    1.83 +
    1.84 +grant_ref_t
    1.85 +XnAllocateGrant(XN_HANDLE handle, ULONG tag);
    1.86 +
    1.87 +VOID
    1.88 +XnFreeGrant(XN_HANDLE handle, grant_ref_t ref, ULONG tag);
    1.89 +
    1.90 +evtchn_port_t
    1.91 +XnAllocateEvent(XN_HANDLE handle);
    1.92 +
    1.93 +NTSTATUS
    1.94 +XnBindEvent(XN_HANDLE handle, evtchn_port_t port, PXN_EVENT_CALLBACK callback, PVOID context);
    1.95 +
    1.96 +NTSTATUS
    1.97 +XnUnBindEvent(XN_HANDLE handle, evtchn_port_t port);
    1.98 +
    1.99 +#ifndef XENPCI_POOL_TAG
   1.100 +#define XENPCI_POOL_TAG (ULONG) 'XenP'
   1.101 +#endif
   1.102 +
   1.103 +static __inline VOID
   1.104 +XnFreeMem(XN_HANDLE handle, PVOID Ptr) {
   1.105 +  UNREFERENCED_PARAMETER(handle);
   1.106 +  ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
   1.107 +}
   1.108 +
   1.109 +
   1.110 +
   1.111 +
   1.112 +
   1.113 +
   1.114 +
   1.115 +
   1.116 +#if 0
   1.117  typedef PHYSICAL_ADDRESS
   1.118  (*PXEN_ALLOCMMIO)(PVOID Context, ULONG Length);
   1.119  
   1.120  typedef void
   1.121  (*PXEN_FREEMEM)(PVOID Ptr);
   1.122 +#endif
   1.123 +
   1.124 +#if 0
   1.125  
   1.126  typedef VOID
   1.127  (*PXEN_EVTCHN_SERVICE_ROUTINE)(PVOID Context);
   1.128 @@ -295,16 +408,6 @@ typedef NTSTATUS
   1.129  typedef NTSTATUS
   1.130  (*PXEN_XENPCI_XEN_SHUTDOWN_DEVICE)(PVOID Context);
   1.131  
   1.132 -#ifndef XENPCI_POOL_TAG
   1.133 -#define XENPCI_POOL_TAG (ULONG) 'XenP'
   1.134 -#endif
   1.135 -
   1.136 -static __inline VOID
   1.137 -XenPci_FreeMem(PVOID Ptr)
   1.138 -{
   1.139 -  ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
   1.140 -}
   1.141 -
   1.142  #define XEN_DATA_MAGIC (ULONG)'XV02'
   1.143  
   1.144  typedef struct {
   1.145 @@ -690,3 +793,4 @@ typedef struct {
   1.146  } dma_driver_extension_t;
   1.147  
   1.148  #endif
   1.149 +#endif
   1.150 \ No newline at end of file
     2.1 --- a/dirs	Fri Dec 14 21:44:03 2012 +1100
     2.2 +++ b/dirs	Sun Jan 06 14:08:22 2013 +1100
     2.3 @@ -1,2 +1,4 @@
     2.4  
     2.5 -DIRS=liblfds.6 xenpci xenvbd xennet xenscsi xenusb copyconfig shutdownmon waitnopendinginstallevents
     2.6 +#DIRS=liblfds.6 xenpci xenvbd xennet xenscsi xenusb copyconfig shutdownmon waitnopendinginstallevents
     2.7 +
     2.8 +DIRS=liblfds.6 xenpci xenvbd xennet copyconfig shutdownmon waitnopendinginstallevents
     3.1 --- a/xennet/xennet6.c	Fri Dec 14 21:44:03 2012 +1100
     3.2 +++ b/xennet/xennet6.c	Sun Jan 06 14:08:22 2013 +1100
     3.3 @@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fi
     3.4  DRIVER_INITIALIZE DriverEntry;
     3.5  static IO_WORKITEM_ROUTINE XenNet_ResumeWorkItem;
     3.6  #if (VER_PRODUCTBUILD >= 7600)
     3.7 -static KDEFERRED_ROUTINE XenNet_SuspendResume;
     3.8 +//static KDEFERRED_ROUTINE XenNet_SuspendResume;
     3.9  static KDEFERRED_ROUTINE XenNet_RxTxDpc;
    3.10  #endif
    3.11  
    3.12 @@ -37,6 +37,7 @@ NDIS_HANDLE driver_handle = NULL;
    3.13  USHORT ndis_os_major_version = 0;
    3.14  USHORT ndis_os_minor_version = 0;
    3.15  
    3.16 +#if 0
    3.17  /* ----- BEGIN Other people's code --------- */
    3.18  /* from linux/include/linux/ctype.h, used under GPLv2 */
    3.19  #define _U      0x01    /* upper */
    3.20 @@ -131,7 +132,9 @@ unsigned long simple_strtoul(const char 
    3.21  }
    3.22  /* end vsprintf.c code */
    3.23  /* ----- END Other people's code --------- */
    3.24 +#endif
    3.25  
    3.26 +#if 0
    3.27  static NDIS_STATUS
    3.28  XenNet_ConnectBackend(struct xennet_info *xi)
    3.29  {
    3.30 @@ -173,7 +176,28 @@ XenNet_ConnectBackend(struct xennet_info
    3.31      case XEN_INIT_TYPE_READ_STRING_FRONT:
    3.32        break;
    3.33      case XEN_INIT_TYPE_READ_STRING_BACK:
    3.34 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
    3.35 +      state = 0;
    3.36 +      octet = 0;
    3.37 +      for (i = 0; i < strlen(value); i++) {
    3.38 +        if (octet >= 6)
    3.39 +          state = 4;
    3.40 +        switch(state) {
    3.41 +        case 0:
    3.42 +        case 1:
    3.43 +          if (value[i] >= 0 && value[i] <= 9) {
    3.44 +            xi->perm_mac_addr[octet] = (value[i] - '0') << ((1 - state) * 4);
    3.45 +            state++;
    3.46 +          } else if (value[i] >= 'A' && value[i] <= 'F') {
    3.47 +            xi->perm_mac_addr[octet] = (value[i] - 'A' + 10) << ((1 - state) * 4);
    3.48 +            state++;
    3.49 +          } else if (value[i] >= 'a' && value[i] <= 'f') {
    3.50 +            xi->perm_mac_addr[octet] = (value[i] - 'a' + 10) << ((1 - state) * 4);
    3.51 +            state++;
    3.52 +          } else {
    3.53 +            state = 4;
    3.54 +          }
    3.55 +          break;
    3.56 +            
    3.57        if (strcmp(setting, "mac") == 0)
    3.58        {
    3.59          char *s, *e;
    3.60 @@ -241,7 +265,9 @@ XenNet_ConnectBackend(struct xennet_info
    3.61    
    3.62    return NDIS_STATUS_SUCCESS;
    3.63  } /* XenNet_ConnectBackend */
    3.64 +#endif
    3.65  
    3.66 +#if 0
    3.67  static VOID
    3.68  XenNet_ResumeWorkItem(PDEVICE_OBJECT device_object, PVOID context)
    3.69  {
    3.70 @@ -271,7 +297,6 @@ XenNet_ResumeWorkItem(PDEVICE_OBJECT dev
    3.71    KeReleaseSpinLock(&xi->resume_lock, old_irql);
    3.72  
    3.73    FUNCTION_EXIT();
    3.74 -
    3.75  }
    3.76  
    3.77  static VOID
    3.78 @@ -326,6 +351,7 @@ XenNet_SuspendResume(PKDPC dpc, PVOID co
    3.79    
    3.80    FUNCTION_EXIT();
    3.81  }
    3.82 +#endif
    3.83  
    3.84  static VOID
    3.85  XenNet_RxTxDpc(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2)
    3.86 @@ -345,201 +371,147 @@ XenNet_RxTxDpc(PKDPC dpc, PVOID context,
    3.87  } 
    3.88  
    3.89  static BOOLEAN
    3.90 -XenNet_HandleEvent(PVOID context)
    3.91 +XenNet_HandleEvent_DIRQL(PVOID context)
    3.92  {
    3.93    struct xennet_info *xi = context;
    3.94 -  ULONG suspend_resume_state_pdo;
    3.95 +  //ULONG suspend_resume_state_pdo;
    3.96    
    3.97    //FUNCTION_ENTER();
    3.98 +#if 0
    3.99    suspend_resume_state_pdo = xi->device_state->suspend_resume_state_pdo;
   3.100    KeMemoryBarrier();
   3.101  
   3.102 -  if (!xi->shutting_down && suspend_resume_state_pdo != xi->device_state->suspend_resume_state_fdo)
   3.103 -  {
   3.104 +  if (!xi->shutting_down && suspend_resume_state_pdo != xi->device_state->suspend_resume_state_fdo) {
   3.105      KeInsertQueueDpc(&xi->suspend_dpc, NULL, NULL);
   3.106    }
   3.107 -  if (xi->connected && !xi->inactive && suspend_resume_state_pdo != SR_STATE_RESUMING)
   3.108 -  {
   3.109 +  if (xi->connected && !xi->inactive && suspend_resume_state_pdo != SR_STATE_RESUMING) {
   3.110 +#endif
   3.111 +  if (xi->connected && !xi->inactive) {
   3.112      KeInsertQueueDpc(&xi->rxtx_dpc, NULL, NULL);
   3.113    }
   3.114    //FUNCTION_EXIT();
   3.115    return TRUE;
   3.116  }
   3.117  
   3.118 -#if 0
   3.119 -VOID
   3.120 -XenNet_SetPower(PDEVICE_OBJECT device_object, PVOID context)
   3.121 -{
   3.122 -  NTSTATUS status = STATUS_SUCCESS;
   3.123 -  KIRQL old_irql;
   3.124 -  struct xennet_info *xi = context;
   3.125 -  
   3.126 -  FUNCTION_ENTER();
   3.127 -  UNREFERENCED_PARAMETER(device_object);
   3.128 -
   3.129 -  switch (xi->new_power_state)
   3.130 -  {
   3.131 -  case NdisDeviceStateD0:
   3.132 -    KdPrint(("       NdisDeviceStateD0\n"));
   3.133 -    status = XenNet_D0Entry(xi);
   3.134 -    break;
   3.135 -  case NdisDeviceStateD1:
   3.136 -    KdPrint(("       NdisDeviceStateD1\n"));
   3.137 -    if (xi->power_state == NdisDeviceStateD0)
   3.138 -      status = XenNet_D0Exit(xi);
   3.139 -    break;
   3.140 -  case NdisDeviceStateD2:
   3.141 -    KdPrint(("       NdisDeviceStateD2\n"));
   3.142 -    if (xi->power_state == NdisDeviceStateD0)
   3.143 -      status = XenNet_D0Exit(xi);
   3.144 -    break;
   3.145 -  case NdisDeviceStateD3:
   3.146 -    KdPrint(("       NdisDeviceStateD3\n"));
   3.147 -    if (xi->power_state == NdisDeviceStateD0)
   3.148 -      status = XenNet_D0Exit(xi);
   3.149 -    break;
   3.150 -  default:
   3.151 -    KdPrint(("       NdisDeviceState??\n"));
   3.152 -    status = NDIS_STATUS_NOT_SUPPORTED;
   3.153 -    break;
   3.154 -  }
   3.155 -  xi->power_state = xi->new_power_state;
   3.156 -
   3.157 -  old_irql = KeRaiseIrqlToDpcLevel();
   3.158 -  NdisMSetInformationComplete(xi->adapter_handle, status);
   3.159 -  KeLowerIrql(old_irql);
   3.160 -  
   3.161 -  FUNCTION_EXIT();
   3.162 -}
   3.163 -#endif
   3.164 -
   3.165 -NDIS_STATUS
   3.166 -XenNet_D0Entry(struct xennet_info *xi)
   3.167 -{
   3.168 -  NDIS_STATUS status;
   3.169 -  PUCHAR ptr;
   3.170 -  CHAR buf[128];
   3.171 +XenNet_BackendStateCallback(PVOID context, ULONG state) {
   3.172 +  struct xennet_info *xi = (struct xennet_info *)context;
   3.173    
   3.174    FUNCTION_ENTER();
   3.175 -
   3.176 -  xi->shutting_down = FALSE;
   3.177 -  
   3.178 -  ptr = xi->config_page;
   3.179 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "tx-ring-ref", NULL, NULL);
   3.180 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "rx-ring-ref", NULL, NULL);
   3.181 -  #pragma warning(suppress:4054)
   3.182 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL, "event-channel", (PVOID)XenNet_HandleEvent, xi);
   3.183 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "mac", NULL, NULL);
   3.184 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "feature-sg", NULL, NULL);
   3.185 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "feature-gso-tcpv4", NULL, NULL);
   3.186 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "request-rx-copy", "1", NULL);
   3.187 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-rx-notify", "1", NULL);
   3.188 -  RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "%d", !xi->frontend_csum_supported);
   3.189 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-no-csum-offload", buf, NULL);
   3.190 -  RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "%d", (int)xi->frontend_sg_supported);
   3.191 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-sg", buf, NULL);
   3.192 -  RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "%d", !!xi->frontend_gso_value);
   3.193 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-gso-tcpv4", buf, NULL);
   3.194 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_PRE_CONNECT, NULL, NULL, NULL);
   3.195 -  __ADD_XEN_INIT_UCHAR(&ptr, 0); /* no pre-connect required */
   3.196 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_POST_CONNECT, NULL, NULL, NULL);
   3.197 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
   3.198 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
   3.199 -  __ADD_XEN_INIT_UCHAR(&ptr, 20);
   3.200 -  __ADD_XEN_INIT_UCHAR(&ptr, 0);
   3.201 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_SHUTDOWN, NULL, NULL, NULL);
   3.202 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
   3.203 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
   3.204 -  __ADD_XEN_INIT_UCHAR(&ptr, 50);
   3.205 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
   3.206 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
   3.207 -  __ADD_XEN_INIT_UCHAR(&ptr, 50);
   3.208 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitialising);
   3.209 -  __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitWait);
   3.210 -  __ADD_XEN_INIT_UCHAR(&ptr, 50);
   3.211 -  __ADD_XEN_INIT_UCHAR(&ptr, 0);
   3.212 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
   3.213 -
   3.214 -  status = xi->vectors.XenPci_XenConfigDevice(xi->vectors.context);
   3.215 -  if (!NT_SUCCESS(status))
   3.216 -  {
   3.217 -    KdPrint(("Failed to complete device configuration (%08x)\n", status));
   3.218 -    return status;
   3.219 +  if (state == xi->backend_state) {
   3.220 +    FUNCTION_MSG("same state %d\n", state);
   3.221 +    FUNCTION_EXIT();
   3.222    }
   3.223 -
   3.224 -  status = XenNet_ConnectBackend(xi);
   3.225 -  
   3.226 -  if (!NT_SUCCESS(status))
   3.227 -  {
   3.228 -    KdPrint(("Failed to complete device configuration (%08x)\n", status));
   3.229 -    return status;
   3.230 -  }
   3.231 -
   3.232 -  XenNet_TxInit(xi);
   3.233 -  XenNet_RxInit(xi);
   3.234 -
   3.235 -  xi->connected = TRUE;
   3.236 -
   3.237 -  KeMemoryBarrier(); // packets could be received anytime after we set Frontent to Connected
   3.238 -
   3.239 +  FUNCTION_MSG("XenbusState = %d -> %d\n", xi->backend_state, state);
   3.240 +  xi->backend_state = state;
   3.241 +  NdisSetEvent(&xi->backend_event);
   3.242    FUNCTION_EXIT();
   3.243 -
   3.244 -  return status;
   3.245  }
   3.246  
   3.247 -// Called at <= DISPATCH_LEVEL
   3.248 +// Called at PASSIVE_LEVEL
   3.249  static NDIS_STATUS
   3.250  XenNet_Initialize(NDIS_HANDLE adapter_handle, NDIS_HANDLE driver_context, PNDIS_MINIPORT_INIT_PARAMETERS init_parameters)
   3.251  {
   3.252    NDIS_STATUS status;
   3.253    struct xennet_info *xi = NULL;
   3.254 -  PNDIS_RESOURCE_LIST nrl;
   3.255 -  PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
   3.256    NDIS_HANDLE config_handle;
   3.257    NDIS_STRING config_param_name;
   3.258    NDIS_CONFIGURATION_OBJECT config_object;
   3.259    PNDIS_CONFIGURATION_PARAMETER config_param;
   3.260    //PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapter_attributes;
   3.261    ULONG i;
   3.262 -  PUCHAR ptr;
   3.263 -  UCHAR type;
   3.264 -  PCHAR setting, value;
   3.265 +  PFN_NUMBER pfn;
   3.266    ULONG length;
   3.267 -  //CHAR buf[128];
   3.268    PVOID network_address;
   3.269    UINT network_address_length;
   3.270 -  BOOLEAN qemu_hide_filter = FALSE;
   3.271 -  ULONG qemu_hide_flags_value = 0;
   3.272 +  ULONG qemu_hide_filter;
   3.273 +  ULONG qemu_hide_flags_value;
   3.274    NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES registration_attributes;
   3.275    NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES general_attributes;
   3.276    NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES offload_attributes;
   3.277    NDIS_OFFLOAD df_offload, hw_offload;
   3.278    NDIS_TCP_CONNECTION_OFFLOAD df_conn_offload, hw_conn_offload;
   3.279    static NDIS_OID *supported_oids;
   3.280 +  ULONG state;
   3.281 +  ULONG octet;
   3.282 +  PCHAR tmp_string;
   3.283 +  ULONG tmp_ulong;
   3.284  
   3.285    UNREFERENCED_PARAMETER(driver_context);
   3.286 +  UNREFERENCED_PARAMETER(init_parameters);
   3.287  
   3.288    FUNCTION_ENTER();
   3.289  
   3.290    /* Alloc memory for adapter private info */
   3.291    status = NdisAllocateMemoryWithTag((PVOID)&xi, sizeof(*xi), XENNET_POOL_TAG);
   3.292 -  if (!NT_SUCCESS(status))
   3.293 -  {
   3.294 -    KdPrint(("NdisAllocateMemoryWithTag failed with 0x%x\n", status));
   3.295 +  if (!NT_SUCCESS(status))  {
   3.296 +    FUNCTION_MSG("NdisAllocateMemoryWithTag failed with 0x%x\n", status);
   3.297      status = NDIS_STATUS_RESOURCES;
   3.298      goto err;
   3.299    }
   3.300    RtlZeroMemory(xi, sizeof(*xi));
   3.301    xi->adapter_handle = adapter_handle;
   3.302 +  xi->inactive = TRUE;
   3.303 +  NdisMGetDeviceProperty(xi->adapter_handle, &xi->pdo, &xi->fdo,
   3.304 +    &xi->lower_do, NULL, NULL);
   3.305 +  NdisInitializeEvent(&xi->backend_event);
   3.306 +  xi->handle = XnOpenDevice(xi->pdo, XenNet_BackendStateCallback, xi);
   3.307 +  if (!xi->handle) {
   3.308 +    FUNCTION_MSG("Cannot open Xen device\n");
   3.309 +    status = NDIS_STATUS_RESOURCES;
   3.310 +    goto err;
   3.311 +  }
   3.312 +  for (i = 0; i <= 5 && xi->backend_state != XenbusStateInitialising && xi->backend_state != XenbusStateInitWait && xi->backend_state != XenbusStateInitialised; i++) {
   3.313 +    NdisWaitEvent(&xi->backend_event, 1000);
   3.314 +  }
   3.315 +  NdisResetEvent(&xi->backend_event);
   3.316 +  if (xi->backend_state != XenbusStateInitialising && xi->backend_state != XenbusStateInitWait && xi->backend_state != XenbusStateInitialised) {
   3.317 +    FUNCTION_MSG("Backend state timeout\n");
   3.318 +    status = NDIS_STATUS_RESOURCES;
   3.319 +    goto err;
   3.320 +  }
   3.321 +  xi->event_channel = XnAllocateEvent(xi->handle);
   3.322 +  if (!xi->event_channel) {
   3.323 +    FUNCTION_MSG("Cannot allocate event channel\n");
   3.324 +    status = NDIS_STATUS_RESOURCES;
   3.325 +    goto err;
   3.326 +  }
   3.327 +  FUNCTION_MSG("event_channel = %d\n", xi->event_channel);
   3.328 +  status = XnBindEvent(xi->handle, xi->event_channel, XenNet_HandleEvent_DIRQL, xi);
   3.329 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "event-channel", xi->event_channel);
   3.330 +  xi->tx_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENNET_POOL_TAG);
   3.331 +  if (!xi->tx_sring) {
   3.332 +    FUNCTION_MSG("Cannot allocate tx_sring\n");
   3.333 +    status = NDIS_STATUS_RESOURCES;
   3.334 +    goto err;
   3.335 +  }
   3.336 +  SHARED_RING_INIT(xi->tx_sring);
   3.337 +  FRONT_RING_INIT(&xi->tx_ring, xi->tx_sring, PAGE_SIZE);
   3.338 +  pfn = MmGetPhysicalAddress(xi->tx_sring).QuadPart >> PAGE_SHIFT;
   3.339 +  FUNCTION_MSG("tx sring pfn = %d\n", (ULONG)pfn);
   3.340 +  xi->tx_sring_gref = XnGrantAccess(xi->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENNET_POOL_TAG);
   3.341 +  FUNCTION_MSG("tx sring_gref = %d\n", xi->tx_sring_gref);
   3.342 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "tx-ring-ref", xi->tx_sring_gref);  
   3.343 +  xi->rx_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENNET_POOL_TAG);
   3.344 +  if (!xi->rx_sring) {
   3.345 +    FUNCTION_MSG("Cannot allocate rx_sring\n");
   3.346 +    status = NDIS_STATUS_RESOURCES;
   3.347 +    goto err;
   3.348 +  }
   3.349 +  SHARED_RING_INIT(xi->rx_sring);
   3.350 +  FRONT_RING_INIT(&xi->rx_ring, xi->rx_sring, PAGE_SIZE);
   3.351 +  pfn = MmGetPhysicalAddress(xi->rx_sring).QuadPart >> PAGE_SHIFT;
   3.352 +  FUNCTION_MSG("rx sring pfn = %d\n", (ULONG)pfn);
   3.353 +  xi->rx_sring_gref = XnGrantAccess(xi->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENNET_POOL_TAG);
   3.354 +  FUNCTION_MSG("rx sring_gref = %d\n", xi->rx_sring_gref);
   3.355 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "rx-ring-ref", xi->rx_sring_gref);  
   3.356 +
   3.357    xi->rx_target     = RX_DFL_MIN_TARGET;
   3.358    xi->rx_min_target = RX_DFL_MIN_TARGET;
   3.359    xi->rx_max_target = RX_MAX_TARGET;
   3.360 -  xi->inactive      = TRUE;
   3.361    
   3.362    xi->multicast_list_size = 0;
   3.363    xi->current_lookahead = MIN_LOOKAHEAD_LENGTH;
   3.364  
   3.365 -  xi->event_channel = 0;
   3.366    xi->stats.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
   3.367    xi->stats.Header.Revision = NDIS_STATISTICS_INFO_REVISION_1;
   3.368    xi->stats.Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
   3.369 @@ -567,102 +539,34 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   3.370      | NDIS_STATISTICS_RCV_DISCARDS_SUPPORTED
   3.371      | NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED
   3.372      | NDIS_STATISTICS_XMIT_DISCARDS_SUPPORTED;
   3.373 -  
   3.374 -  nrl = init_parameters->AllocatedResources;
   3.375 -  for (i = 0; i < nrl->Count; i++)
   3.376 -  {
   3.377 -    prd = &nrl->PartialDescriptors[i];
   3.378  
   3.379 -    switch(prd->Type)
   3.380 -    {
   3.381 -    case CmResourceTypeInterrupt:
   3.382 -      break;
   3.383 -    case CmResourceTypeMemory:
   3.384 -      if (xi->config_page)
   3.385 -      {
   3.386 -        KdPrint(("More than one memory range\n"));
   3.387 -        return NDIS_STATUS_RESOURCES;
   3.388 -      }
   3.389 -      else
   3.390 -      {
   3.391 -        status = NdisMMapIoSpace(&xi->config_page, xi->adapter_handle, prd->u.Memory.Start, prd->u.Memory.Length);
   3.392 -        if (!NT_SUCCESS(status))
   3.393 -        {
   3.394 -          KdPrint(("NdisMMapIoSpace failed with 0x%x\n", status));
   3.395 -          return NDIS_STATUS_RESOURCES;
   3.396 -        }
   3.397 -      }
   3.398 -      break;
   3.399 -    }
   3.400 -  }
   3.401 -  if (!xi->config_page)
   3.402 -  {
   3.403 -    KdPrint(("No config page given\n"));
   3.404 -    return NDIS_STATUS_RESOURCES;
   3.405 -  }
   3.406 -
   3.407 +#if 0    
   3.408    KeInitializeDpc(&xi->suspend_dpc, XenNet_SuspendResume, xi);
   3.409    KeInitializeSpinLock(&xi->resume_lock);
   3.410 +#endif
   3.411  
   3.412    KeInitializeDpc(&xi->rxtx_dpc, XenNet_RxTxDpc, xi);
   3.413    KeSetTargetProcessorDpc(&xi->rxtx_dpc, 0);
   3.414    KeSetImportanceDpc(&xi->rxtx_dpc, HighImportance);
   3.415  
   3.416 -  NdisMGetDeviceProperty(xi->adapter_handle, &xi->pdo, &xi->fdo,
   3.417 -    &xi->lower_do, NULL, NULL);
   3.418    xi->packet_filter = 0;
   3.419  
   3.420    status = IoGetDeviceProperty(xi->pdo, DevicePropertyDeviceDescription,
   3.421      NAME_SIZE, xi->dev_desc, &length);
   3.422 -  if (!NT_SUCCESS(status))
   3.423 -  {
   3.424 +  if (!NT_SUCCESS(status)) {
   3.425      KdPrint(("IoGetDeviceProperty failed with 0x%x\n", status));
   3.426      status = NDIS_STATUS_FAILURE;
   3.427      goto err;
   3.428    }
   3.429  
   3.430 -  ptr = xi->config_page;
   3.431 -  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value)) != XEN_INIT_TYPE_END)
   3.432 -  {
   3.433 -    switch(type)
   3.434 -    {
   3.435 -    case XEN_INIT_TYPE_VECTORS:
   3.436 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
   3.437 -      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
   3.438 -        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
   3.439 -      {
   3.440 -        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
   3.441 -          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
   3.442 -        FUNCTION_EXIT();
   3.443 -        return NDIS_STATUS_FAILURE;
   3.444 -      }
   3.445 -      else
   3.446 -        memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS));
   3.447 -      break;
   3.448 -    case XEN_INIT_TYPE_STATE_PTR:
   3.449 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
   3.450 -      xi->device_state = (PXENPCI_DEVICE_STATE)value;
   3.451 -      break;
   3.452 -    case XEN_INIT_TYPE_QEMU_HIDE_FLAGS:
   3.453 -      qemu_hide_flags_value = PtrToUlong(value);
   3.454 -      break;
   3.455 -    case XEN_INIT_TYPE_QEMU_HIDE_FILTER:
   3.456 -      qemu_hide_filter = TRUE;
   3.457 -      break;
   3.458 -    default:
   3.459 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
   3.460 -      break;
   3.461 -    }
   3.462 -  }
   3.463 -
   3.464 -  if ((qemu_hide_flags_value & QEMU_UNPLUG_ALL_IDE_DISKS) || qemu_hide_filter)
   3.465 +  XnGetValue(xi->handle, XN_VALUE_TYPE_QEMU_HIDE_FLAGS, &qemu_hide_flags_value);
   3.466 +  XnGetValue(xi->handle, XN_VALUE_TYPE_QEMU_FILTER, &qemu_hide_filter);
   3.467 +  if ((qemu_hide_flags_value & QEMU_UNPLUG_ALL_NICS) || qemu_hide_filter)
   3.468      xi->inactive = FALSE;
   3.469  
   3.470    xi->power_state = NdisDeviceStateD0;
   3.471    xi->power_workitem = IoAllocateWorkItem(xi->fdo);
   3.472  
   3.473 -  // now build config page
   3.474 -  
   3.475    config_object.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);
   3.476    config_object.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
   3.477    config_object.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
   3.478 @@ -670,9 +574,8 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   3.479    config_object.Flags = 0;
   3.480  
   3.481    status = NdisOpenConfigurationEx(&config_object, &config_handle);
   3.482 -  if (!NT_SUCCESS(status))
   3.483 -  {
   3.484 -    KdPrint(("Could not open config in registry (%08x)\n", status));
   3.485 +  if (!NT_SUCCESS(status)) {
   3.486 +    FUNCTION_MSG("Could not open config in registry (%08x)\n", status);
   3.487      status = NDIS_STATUS_RESOURCES;
   3.488      goto err;
   3.489    }
   3.490 @@ -681,12 +584,10 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   3.491    NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
   3.492    if (!NT_SUCCESS(status))
   3.493    {
   3.494 -    KdPrint(("Could not read ScatterGather value (%08x)\n", status));
   3.495 +    FUNCTION_MSG("Could not read ScatterGather value (%08x)\n", status);
   3.496      xi->frontend_sg_supported = TRUE;
   3.497 -  }
   3.498 -  else
   3.499 -  {
   3.500 -    KdPrint(("ScatterGather = %d\n", config_param->ParameterData.IntegerData));
   3.501 +  } else {
   3.502 +    FUNCTION_MSG("ScatterGather = %d\n", config_param->ParameterData.IntegerData);
   3.503      xi->frontend_sg_supported = !!config_param->ParameterData.IntegerData;
   3.504    }
   3.505    if (xi->frontend_sg_supported && ndis_os_minor_version < 1) {
   3.506 @@ -696,25 +597,20 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   3.507    
   3.508    NdisInitUnicodeString(&config_param_name, L"LargeSendOffload");
   3.509    NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
   3.510 -  if (!NT_SUCCESS(status))
   3.511 -  {
   3.512 -    KdPrint(("Could not read LargeSendOffload value (%08x)\n", status));
   3.513 +  if (!NT_SUCCESS(status)) {
   3.514 +    FUNCTION_MSG("Could not read LargeSendOffload value (%08x)\n", status);
   3.515      xi->frontend_gso_value = 0;
   3.516 -  }
   3.517 -  else
   3.518 -  {
   3.519 -    KdPrint(("LargeSendOffload = %d\n", config_param->ParameterData.IntegerData));
   3.520 +  } else {
   3.521 +    FUNCTION_MSG("LargeSendOffload = %d\n", config_param->ParameterData.IntegerData);
   3.522      xi->frontend_gso_value = config_param->ParameterData.IntegerData;
   3.523 -    if (xi->frontend_gso_value > 61440)
   3.524 -    {
   3.525 +    if (xi->frontend_gso_value > 61440) {
   3.526        xi->frontend_gso_value = 61440;
   3.527 -      KdPrint(("(clipped to %d)\n", xi->frontend_gso_value));
   3.528 +      FUNCTION_MSG("  (clipped to %d)\n", xi->frontend_gso_value);
   3.529      }
   3.530 -    if (!xi->frontend_sg_supported && xi->frontend_gso_value > PAGE_SIZE - MAX_PKT_HEADER_LENGTH)
   3.531 -    {
   3.532 +    if (!xi->frontend_sg_supported && xi->frontend_gso_value > PAGE_SIZE - MAX_PKT_HEADER_LENGTH) {
   3.533        /* without SG, GSO can be a maximum of PAGE_SIZE - MAX_PKT_HEADER_LENGTH */
   3.534        xi->frontend_gso_value = min(xi->frontend_gso_value, PAGE_SIZE - MAX_PKT_HEADER_LENGTH);
   3.535 -      KdPrint(("(clipped to %d with sg disabled)\n", xi->frontend_gso_value));
   3.536 +      FUNCTION_MSG("  (clipped to %d with sg disabled)\n", xi->frontend_gso_value);
   3.537      }
   3.538    }
   3.539    if (xi->frontend_sg_supported && ndis_os_minor_version < 1) {
   3.540 @@ -724,16 +620,12 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   3.541  
   3.542    NdisInitUnicodeString(&config_param_name, L"LargeSendOffloadRxSplitMTU");
   3.543    NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
   3.544 -  if (!NT_SUCCESS(status))
   3.545 -  {
   3.546 -    KdPrint(("Could not read LargeSendOffload value (%08x)\n", status));
   3.547 +  if (!NT_SUCCESS(status)) {
   3.548 +    FUNCTION_MSG("Could not read LargeSendOffload value (%08x)\n", status);
   3.549      xi->frontend_gso_rx_split_type = RX_LSO_SPLIT_HALF;
   3.550 -  }
   3.551 -  else
   3.552 -  {
   3.553 -    KdPrint(("LargeSendOffloadRxSplitMTU = %d\n", config_param->ParameterData.IntegerData));
   3.554 -    switch (config_param->ParameterData.IntegerData)
   3.555 -    {
   3.556 +  } else {
   3.557 +    FUNCTION_MSG("LargeSendOffloadRxSplitMTU = %d\n", config_param->ParameterData.IntegerData);
   3.558 +    switch (config_param->ParameterData.IntegerData) {
   3.559      case RX_LSO_SPLIT_MSS:
   3.560      case RX_LSO_SPLIT_HALF:
   3.561      case RX_LSO_SPLIT_NONE:
   3.562 @@ -747,53 +639,122 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   3.563  
   3.564    NdisInitUnicodeString(&config_param_name, L"ChecksumOffload");
   3.565    NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
   3.566 -  if (!NT_SUCCESS(status))
   3.567 -  {
   3.568 -    KdPrint(("Could not read ChecksumOffload value (%08x)\n", status));
   3.569 +  if (!NT_SUCCESS(status)) {
   3.570 +    FUNCTION_MSG("Could not read ChecksumOffload value (%08x)\n", status);
   3.571      xi->frontend_csum_supported = TRUE;
   3.572 -  }
   3.573 -  else
   3.574 -  {
   3.575 -    KdPrint(("ChecksumOffload = %d\n", config_param->ParameterData.IntegerData));
   3.576 +  } else {
   3.577 +    FUNCTION_MSG("ChecksumOffload = %d\n", config_param->ParameterData.IntegerData);
   3.578      xi->frontend_csum_supported = !!config_param->ParameterData.IntegerData;
   3.579    }
   3.580  
   3.581    NdisInitUnicodeString(&config_param_name, L"MTU");
   3.582    NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);  
   3.583 -  if (!NT_SUCCESS(status))
   3.584 -  {
   3.585 -    KdPrint(("Could not read MTU value (%08x)\n", status));
   3.586 +  if (!NT_SUCCESS(status)) {
   3.587 +    FUNCTION_MSG("Could not read MTU value (%08x)\n", status);
   3.588      xi->frontend_mtu_value = 1500;
   3.589 -  }
   3.590 -  else
   3.591 -  {
   3.592 -    KdPrint(("MTU = %d\n", config_param->ParameterData.IntegerData));
   3.593 +  } else {
   3.594 +    FUNCTION_MSG("MTU = %d\n", config_param->ParameterData.IntegerData);
   3.595      xi->frontend_mtu_value = config_param->ParameterData.IntegerData;
   3.596    }
   3.597    
   3.598    NdisReadNetworkAddress(&status, &network_address, &network_address_length, config_handle);
   3.599 -  if (!NT_SUCCESS(status) || network_address_length != ETH_ALEN || ((((PUCHAR)network_address)[0] & 0x03) != 0x02))
   3.600 -  {
   3.601 -    KdPrint(("Could not read NetworkAddress value (%08x) or value is invalid\n", status));
   3.602 +  if (!NT_SUCCESS(status) || network_address_length != ETH_ALEN || ((((PUCHAR)network_address)[0] & 0x03) != 0x02)) {
   3.603 +    FUNCTION_MSG("Could not read registry NetworkAddress value (%08x) or value is invalid\n", status);
   3.604      memset(xi->curr_mac_addr, 0, ETH_ALEN);
   3.605 -  }
   3.606 -  else
   3.607 -  {
   3.608 +  } else {
   3.609      memcpy(xi->curr_mac_addr, network_address, ETH_ALEN);
   3.610 -    KdPrint(("     Set MAC address from registry to %02X:%02X:%02X:%02X:%02X:%02X\n",
   3.611 +    FUNCTION_MSG("Set MAC address from registry to %02X:%02X:%02X:%02X:%02X:%02X\n",
   3.612        xi->curr_mac_addr[0], xi->curr_mac_addr[1], xi->curr_mac_addr[2], 
   3.613 -      xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5]));
   3.614 +      xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5]);
   3.615    }
   3.616  
   3.617    NdisCloseConfiguration(config_handle);
   3.618  
   3.619 -  status = XenNet_D0Entry(xi);
   3.620 -  if (!NT_SUCCESS(status))
   3.621 -  {
   3.622 -    KdPrint(("Failed to go to D0 (%08x)\n", status));
   3.623 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "request-rx-copy", 1);
   3.624 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "request-rx-notify", 1);
   3.625 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-no-csum-offload", !xi->frontend_csum_supported);
   3.626 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-sg", (int)xi->frontend_sg_supported);
   3.627 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-gso-tcpv4", !!xi->frontend_gso_value);
   3.628 +
   3.629 +  status = XnReadInt32(xi->handle, XN_BASE_BACKEND, "feature-sg", &tmp_ulong);
   3.630 +  if (tmp_ulong) {
   3.631 +    xi->backend_sg_supported = TRUE;
   3.632 +  }
   3.633 +  status = XnReadInt32(xi->handle, XN_BASE_BACKEND, "feature-gso-tcpv4", &tmp_ulong);
   3.634 +  if (tmp_ulong) {
   3.635 +    xi->backend_gso_value = xi->frontend_gso_value;
   3.636 +  }
   3.637 +
   3.638 +  status = XnReadString(xi->handle, XN_BASE_BACKEND, "mac", &tmp_string);
   3.639 +  state = 0;
   3.640 +  octet = 0;
   3.641 +  for (i = 0; state != 3 && i < strlen(tmp_string); i++) {
   3.642 +    if (octet == 6) {
   3.643 +FUNCTION_MSG("AAA - i = %d, state = %d, octet = %d\n", i, state, octet);
   3.644 +      state = 3;
   3.645 +      break;
   3.646 +    }
   3.647 +    switch(state) {
   3.648 +    case 0:
   3.649 +    case 1:
   3.650 +      if (tmp_string[i] >= '0' && tmp_string[i] <= '9') {
   3.651 +        xi->perm_mac_addr[octet] |= (tmp_string[i] - '0') << ((1 - state) * 4);
   3.652 +        state++;
   3.653 +      } else if (tmp_string[i] >= 'A' && tmp_string[i] <= 'F') {
   3.654 +        xi->perm_mac_addr[octet] |= (tmp_string[i] - 'A' + 10) << ((1 - state) * 4);
   3.655 +        state++;
   3.656 +      } else if (tmp_string[i] >= 'a' && tmp_string[i] <= 'f') {
   3.657 +        xi->perm_mac_addr[octet] |= (tmp_string[i] - 'a' + 10) << ((1 - state) * 4);
   3.658 +        state++;
   3.659 +      } else {
   3.660 +        state = 3;
   3.661 +      }
   3.662 +      break;
   3.663 +    case 2:
   3.664 +      if (tmp_string[i] == ':') {
   3.665 +        octet++;
   3.666 +        state = 0;
   3.667 +      } else {
   3.668 +        state = 3;
   3.669 +      }
   3.670 +      break;
   3.671 +    }
   3.672 +  }
   3.673 +  if (octet != 5 || state != 2) {
   3.674 +    FUNCTION_MSG("Failed to parse backend MAC address %s\n", tmp_string);
   3.675 +    XnFreeMem(xi->handle, tmp_string);
   3.676 +    status = NDIS_STATUS_FAILURE;
   3.677 +    goto err;
   3.678 +  } else if ((xi->curr_mac_addr[0] & 0x03) != 0x02) {
   3.679 +    /* only copy if curr_mac_addr is not a LUA */
   3.680 +    memcpy(xi->curr_mac_addr, xi->perm_mac_addr, ETH_ALEN);
   3.681 +  }
   3.682 +  XnFreeMem(xi->handle, tmp_string);
   3.683 +  FUNCTION_MSG("MAC address is %02X:%02X:%02X:%02X:%02X:%02X\n",
   3.684 +    xi->curr_mac_addr[0], xi->curr_mac_addr[1], xi->curr_mac_addr[2], 
   3.685 +    xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5]);
   3.686 +
   3.687 +  status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "state", XenbusStateConnected);
   3.688 +
   3.689 +  for (i = 0; i <= 5 && xi->backend_state != XenbusStateConnected; i++) {
   3.690 +    NdisWaitEvent(&xi->backend_event, 1000);
   3.691 +  }
   3.692 +  NdisResetEvent(&xi->backend_event);
   3.693 +  if (xi->backend_state != XenbusStateConnected) {
   3.694 +    FUNCTION_MSG("Backend state timeout\n");
   3.695 +    status = NDIS_STATUS_RESOURCES;
   3.696      goto err;
   3.697    }
   3.698  
   3.699 +  if (!xi->backend_sg_supported)
   3.700 +    xi->backend_gso_value = min(xi->backend_gso_value, PAGE_SIZE - MAX_PKT_HEADER_LENGTH);
   3.701 +
   3.702 +  xi->current_sg_supported = xi->frontend_sg_supported && xi->backend_sg_supported;
   3.703 +  xi->current_csum_supported = xi->frontend_csum_supported && xi->backend_csum_supported;
   3.704 +  xi->current_gso_value = min(xi->backend_gso_value, xi->backend_gso_value);
   3.705 +  xi->current_mtu_value = xi->frontend_mtu_value;
   3.706 +  xi->current_gso_rx_split_type = xi->frontend_gso_rx_split_type;
   3.707 +  
   3.708    xi->config_max_pkt_size = max(xi->current_mtu_value + XN_HDR_SIZE, xi->current_gso_value + XN_HDR_SIZE);
   3.709      
   3.710    registration_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
   3.711 @@ -806,9 +767,8 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   3.712    registration_attributes.CheckForHangTimeInSeconds = 0; /* use default */
   3.713    registration_attributes.InterfaceType = NdisInterfacePNPBus;
   3.714    status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&registration_attributes);
   3.715 -  if (!NT_SUCCESS(status))
   3.716 -  {
   3.717 -    KdPrint(("NdisMSetMiniportAttributes(registration) failed (%08x)\n", status));
   3.718 +  if (!NT_SUCCESS(status)) {
   3.719 +    FUNCTION_MSG("NdisMSetMiniportAttributes(registration) failed (%08x)\n", status);
   3.720      goto err;
   3.721    }
   3.722    
   3.723 @@ -849,15 +809,13 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   3.724    for (i = 0; xennet_oids[i].oid; i++);
   3.725    
   3.726    status = NdisAllocateMemoryWithTag((PVOID)&supported_oids, sizeof(NDIS_OID) * i, XENNET_POOL_TAG);
   3.727 -  if (!NT_SUCCESS(status))
   3.728 -  {
   3.729 -    KdPrint(("NdisAllocateMemoryWithTag failed with 0x%x\n", status));
   3.730 +  if (!NT_SUCCESS(status)) {
   3.731 +    FUNCTION_MSG("NdisAllocateMemoryWithTag failed with 0x%x\n", status);
   3.732      status = NDIS_STATUS_RESOURCES;
   3.733      goto err;
   3.734    }
   3.735  
   3.736 -  for (i = 0; xennet_oids[i].oid; i++)
   3.737 -  {
   3.738 +  for (i = 0; xennet_oids[i].oid; i++) {
   3.739      supported_oids[i] = xennet_oids[i].oid;
   3.740      FUNCTION_MSG("Supporting %08x (%s) %s %d bytes\n", xennet_oids[i].oid, xennet_oids[i].oid_name, (xennet_oids[i].query_routine?(xennet_oids[i].set_routine?"get/set":"get only"):(xennet_oids[i].set_routine?"set only":"none")), xennet_oids[i].min_length);
   3.741    }
   3.742 @@ -868,9 +826,8 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   3.743      | NDIS_LINK_STATE_DUPLEX_AUTO_NEGOTIATED;
   3.744    //general_attributes.PowerManagementCapabilitiesEx = NULL; // >= 6.20
   3.745    status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&general_attributes);
   3.746 -  if (!NT_SUCCESS(status))
   3.747 -  {
   3.748 -    KdPrint(("NdisMSetMiniportAttributes(general) failed (%08x)\n", status));
   3.749 +  if (!NT_SUCCESS(status)) {
   3.750 +    FUNCTION_MSG("NdisMSetMiniportAttributes(general) failed (%08x)\n", status);
   3.751      goto err;
   3.752    }
   3.753    NdisFreeMemory(supported_oids, 0, 0);
   3.754 @@ -962,9 +919,8 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   3.755    offload_attributes.DefaultTcpConnectionOffloadConfiguration = &df_conn_offload;
   3.756    offload_attributes.TcpConnectionOffloadHardwareCapabilities  = &hw_conn_offload;
   3.757    status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&offload_attributes);
   3.758 -  if (!NT_SUCCESS(status))
   3.759 -  {
   3.760 -    KdPrint(("NdisMSetMiniportAttributes(offload) failed (%08x)\n", status));
   3.761 +  if (!NT_SUCCESS(status)) {
   3.762 +    FUNCTION_MSG("NdisMSetMiniportAttributes(offload) failed (%08x)\n", status);
   3.763      goto err;
   3.764    }
   3.765    
   3.766 @@ -999,37 +955,21 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha
   3.767      //what about backfill here?
   3.768    }
   3.769    #endif
   3.770 +  XenNet_TxInit(xi);
   3.771 +  XenNet_RxInit(xi);
   3.772 +  xi->connected = TRUE;
   3.773 +  FUNCTION_EXIT();
   3.774    return NDIS_STATUS_SUCCESS;
   3.775    
   3.776  err:
   3.777 -  NdisFreeMemory(xi, 0, 0);
   3.778 +  if (xi) {
   3.779 +    NdisFreeMemory(xi, 0, 0);
   3.780 +  }
   3.781    FUNCTION_EXIT_STATUS(status);
   3.782  
   3.783    return status;
   3.784  }
   3.785  
   3.786 -NDIS_STATUS
   3.787 -XenNet_D0Exit(struct xennet_info *xi)
   3.788 -{
   3.789 -  FUNCTION_ENTER();
   3.790 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   3.791 -
   3.792 -  xi->shutting_down = TRUE;
   3.793 -  KeMemoryBarrier(); /* make sure everyone sees that we are now shutting down */
   3.794 -
   3.795 -  XenNet_TxShutdown(xi);
   3.796 -  XenNet_RxShutdown(xi);
   3.797 -
   3.798 -  xi->connected = FALSE;
   3.799 -  KeMemoryBarrier(); /* make sure everyone sees that we are now disconnected */
   3.800 -
   3.801 -  xi->vectors.XenPci_XenShutdownDevice(xi->vectors.context);
   3.802 -
   3.803 -  FUNCTION_EXIT();
   3.804 -  
   3.805 -  return STATUS_SUCCESS;
   3.806 -}
   3.807 -
   3.808  static VOID
   3.809  XenNet_DevicePnPEventNotify(NDIS_HANDLE adapter_context, PNET_DEVICE_PNP_EVENT pnp_event)
   3.810  {
   3.811 @@ -1039,13 +979,13 @@ XenNet_DevicePnPEventNotify(NDIS_HANDLE 
   3.812    switch (pnp_event->DevicePnPEvent)
   3.813    {
   3.814    case NdisDevicePnPEventSurpriseRemoved:
   3.815 -    KdPrint((__DRIVER_NAME "     NdisDevicePnPEventSurpriseRemoved\n"));
   3.816 +    FUNCTION_MSG("NdisDevicePnPEventSurpriseRemoved\n");
   3.817      break;
   3.818    case NdisDevicePnPEventPowerProfileChanged :
   3.819 -    KdPrint((__DRIVER_NAME "     NdisDevicePnPEventPowerProfileChanged\n"));
   3.820 +    FUNCTION_MSG("NdisDevicePnPEventPowerProfileChanged\n");
   3.821      break;
   3.822    default:
   3.823 -    KdPrint((__DRIVER_NAME "     NdisDevicePnPEvent%d\n", pnp_event->DevicePnPEvent));
   3.824 +    FUNCTION_MSG("NdisDevicePnPEvent%d\n", pnp_event->DevicePnPEvent);
   3.825      break;
   3.826    }
   3.827    FUNCTION_EXIT();
   3.828 @@ -1081,7 +1021,16 @@ XenNet_Halt(NDIS_HANDLE adapter_context,
   3.829  
   3.830    FUNCTION_ENTER();
   3.831    
   3.832 -  XenNet_D0Exit(xi);
   3.833 +  xi->shutting_down = TRUE;
   3.834 +  KeMemoryBarrier(); /* make sure everyone sees that we are now shutting down */
   3.835 +
   3.836 +  XenNet_TxShutdown(xi);
   3.837 +  XenNet_RxShutdown(xi);
   3.838 +
   3.839 +  xi->connected = FALSE;
   3.840 +  KeMemoryBarrier(); /* make sure everyone sees that we are now disconnected */
   3.841 +
   3.842 +  //xi->vectors.XenPci_XenShutdownDevice(xi->vectors.context);
   3.843  
   3.844    NdisFreeMemory(xi, 0, 0);
   3.845  
   3.846 @@ -1173,8 +1122,8 @@ DriverEntry(PDRIVER_OBJECT driver_object
   3.847    mini_chars.MajorDriverVersion = VENDOR_DRIVER_VERSION_MAJOR;
   3.848    mini_chars.MinorDriverVersion = VENDOR_DRIVER_VERSION_MINOR;
   3.849  
   3.850 -  KdPrint((__DRIVER_NAME "     Driver MajorNdisVersion = %d, Driver MinorNdisVersion = %d\n", NDIS_MINIPORT_MAJOR_VERSION, NDIS_MINIPORT_MINOR_VERSION));
   3.851 -  KdPrint((__DRIVER_NAME "     Windows MajorNdisVersion = %d, Windows MinorNdisVersion = %d\n", ndis_os_major_version, ndis_os_minor_version));
   3.852 +  FUNCTION_MSG("Driver MajorNdisVersion = %d, Driver MinorNdisVersion = %d\n", NDIS_MINIPORT_MAJOR_VERSION, NDIS_MINIPORT_MINOR_VERSION);
   3.853 +  FUNCTION_MSG("Windows MajorNdisVersion = %d, Windows MinorNdisVersion = %d\n", ndis_os_major_version, ndis_os_minor_version);
   3.854  
   3.855    mini_chars.Flags = NDIS_WDM_DRIVER;
   3.856    
   3.857 @@ -1204,7 +1153,7 @@ DriverEntry(PDRIVER_OBJECT driver_object
   3.858    status = NdisMRegisterMiniportDriver(driver_object, registry_path, NULL, &mini_chars, &driver_handle);
   3.859    if (!NT_SUCCESS(status))
   3.860    {
   3.861 -    KdPrint((__DRIVER_NAME "     NdisMRegisterMiniportDriver failed, status = 0x%x\n", status));
   3.862 +    FUNCTION_MSG("NdisMRegisterMiniportDriver failed, status = 0x%x\n", status);
   3.863      return status;
   3.864    }
   3.865  
     4.1 --- a/xennet/xennet6.h	Fri Dec 14 21:44:03 2012 +1100
     4.2 +++ b/xennet/xennet6.h	Sun Jan 06 14:08:22 2013 +1100
     4.3 @@ -286,13 +286,16 @@ struct xennet_info
     4.4    PIO_WORKITEM power_workitem;
     4.5  
     4.6    /* Misc. Xen vars */
     4.7 -  XENPCI_VECTORS vectors;
     4.8 -  PXENPCI_DEVICE_STATE device_state;
     4.9 +  XN_HANDLE handle;
    4.10 +  //XENPCI_VECTORS vectors;
    4.11 +  
    4.12 +  //PXENPCI_DEVICE_STATE device_state;
    4.13    evtchn_port_t event_channel;
    4.14 -  ULONG state;
    4.15 -  char backend_path[MAX_XENBUS_STR_LEN];
    4.16 +  //ULONG state;
    4.17 +  //char backend_path[MAX_XENBUS_STR_LEN];
    4.18    ULONG backend_state;
    4.19 -  PVOID config_page;
    4.20 +  NDIS_EVENT backend_event;
    4.21 +  //PVOID config_page;
    4.22    UCHAR multicast_list[MULTICAST_LIST_MAX_SIZE][6];
    4.23    ULONG multicast_list_size;
    4.24    KDPC suspend_dpc;
    4.25 @@ -303,7 +306,9 @@ struct xennet_info
    4.26    /* tx related - protected by tx_lock */
    4.27    KSPIN_LOCK tx_lock;
    4.28    LIST_ENTRY tx_waiting_pkt_list;
    4.29 -  struct netif_tx_front_ring tx;
    4.30 +  netif_tx_sring_t *tx_sring;
    4.31 +  grant_ref_t tx_sring_gref;
    4.32 +  struct netif_tx_front_ring tx_ring;
    4.33    ULONG tx_ring_free;
    4.34    tx_shadow_t tx_shadows[NET_TX_RING_SIZE];
    4.35    //NDIS_HANDLE tx_buffer_pool;
    4.36 @@ -318,7 +323,9 @@ struct xennet_info
    4.37  
    4.38    /* rx_related - protected by rx_lock */
    4.39    KSPIN_LOCK rx_lock;
    4.40 -  struct netif_rx_front_ring rx;
    4.41 +  netif_rx_sring_t *rx_sring;
    4.42 +  grant_ref_t rx_sring_gref;
    4.43 +  struct netif_rx_front_ring rx_ring;
    4.44    ULONG rx_id_free;
    4.45    packet_info_t *rxpi;
    4.46    KEVENT packet_returned_event;
     5.1 --- a/xennet/xennet6_rx.c	Fri Dec 14 21:44:03 2012 +1100
     5.2 +++ b/xennet/xennet6_rx.c	Sun Jan 06 14:08:22 2013 +1100
     5.3 @@ -54,7 +54,7 @@ get_pb_from_freelist(struct xennet_info 
     5.4      NdisFreeMemory(pb, sizeof(shared_buffer_t), 0);
     5.5      return NULL;
     5.6    }
     5.7 -  pb->gref = (grant_ref_t)xi->vectors.GntTbl_GrantAccess(xi->vectors.context,
     5.8 +  pb->gref = (grant_ref_t)XnGrantAccess(xi->handle,
     5.9              (ULONG)(MmGetPhysicalAddress(pb->virtual).QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, (ULONG)'XNRX');
    5.10    if (pb->gref == INVALID_GRANT_REF)
    5.11    {
    5.12 @@ -84,7 +84,7 @@ put_pb_on_freelist(struct xennet_info *x
    5.13      //NDIS_BUFFER_LINKAGE(pb->buffer) = NULL;
    5.14      if (xi->rx_pb_free > RX_MAX_PB_FREELIST)
    5.15      {
    5.16 -      xi->vectors.GntTbl_EndAccess(xi->vectors.context, pb->gref, FALSE, (ULONG)'XNRX');
    5.17 +      XnEndAccess(xi->handle, pb->gref, FALSE, (ULONG)'XNRX');
    5.18        IoFreeMdl(pb->mdl);
    5.19        NdisFreeMemory(pb->virtual, PAGE_SIZE, 0);
    5.20        NdisFreeMemory(pb, sizeof(shared_buffer_t), 0);
    5.21 @@ -148,12 +148,12 @@ XenNet_FillRing(struct xennet_info *xi)
    5.22    shared_buffer_t *page_buf;
    5.23    ULONG i, notify;
    5.24    ULONG batch_target;
    5.25 -  RING_IDX req_prod = xi->rx.req_prod_pvt;
    5.26 +  RING_IDX req_prod = xi->rx_ring.req_prod_pvt;
    5.27    netif_rx_request_t *req;
    5.28  
    5.29    //FUNCTION_ENTER();
    5.30  
    5.31 -  batch_target = xi->rx_target - (req_prod - xi->rx.rsp_cons);
    5.32 +  batch_target = xi->rx_target - (req_prod - xi->rx_ring.rsp_cons);
    5.33  
    5.34    if (batch_target < (xi->rx_target >> 2))
    5.35    {
    5.36 @@ -175,17 +175,17 @@ XenNet_FillRing(struct xennet_info *xi)
    5.37      id = (USHORT)((req_prod + i) & (NET_RX_RING_SIZE - 1));
    5.38      NT_ASSERT(xi->rx_ring_pbs[id] == NULL);
    5.39      xi->rx_ring_pbs[id] = page_buf;
    5.40 -    req = RING_GET_REQUEST(&xi->rx, req_prod + i);
    5.41 +    req = RING_GET_REQUEST(&xi->rx_ring, req_prod + i);
    5.42      req->id = id;
    5.43      req->gref = page_buf->gref;
    5.44      NT_ASSERT(req->gref != INVALID_GRANT_REF);
    5.45    }
    5.46    KeMemoryBarrier();
    5.47 -  xi->rx.req_prod_pvt = req_prod + i;
    5.48 -  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xi->rx, notify);
    5.49 +  xi->rx_ring.req_prod_pvt = req_prod + i;
    5.50 +  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xi->rx_ring, notify);
    5.51    if (notify)
    5.52    {
    5.53 -    xi->vectors.EvtChn_Notify(xi->vectors.context, xi->event_channel);
    5.54 +    XnNotify(xi->handle, xi->event_channel);
    5.55    }
    5.56  
    5.57    //FUNCTION_EXIT();
    5.58 @@ -632,17 +632,17 @@ XenNet_RxBufferCheck(struct xennet_info 
    5.59    }
    5.60  
    5.61    do {
    5.62 -    prod = xi->rx.sring->rsp_prod;
    5.63 +    prod = xi->rx_ring.sring->rsp_prod;
    5.64      KeMemoryBarrier(); /* Ensure we see responses up to 'prod'. */
    5.65  
    5.66 -    for (cons = xi->rx.rsp_cons; cons != prod && packet_count < MAXIMUM_PACKETS_PER_INTERRUPT && packet_data < MAXIMUM_DATA_PER_INTERRUPT; cons++)
    5.67 +    for (cons = xi->rx_ring.rsp_cons; cons != prod && packet_count < MAXIMUM_PACKETS_PER_INTERRUPT && packet_data < MAXIMUM_DATA_PER_INTERRUPT; cons++)
    5.68      {
    5.69        id = (USHORT)(cons & (NET_RX_RING_SIZE - 1));
    5.70        page_buf = xi->rx_ring_pbs[id];
    5.71        NT_ASSERT(page_buf);
    5.72        xi->rx_ring_pbs[id] = NULL;
    5.73        xi->rx_id_free++;
    5.74 -      memcpy(&page_buf->rsp, RING_GET_RESPONSE(&xi->rx, cons), max(sizeof(struct netif_rx_response), sizeof(struct netif_extra_info)));
    5.75 +      memcpy(&page_buf->rsp, RING_GET_RESPONSE(&xi->rx_ring, cons), max(sizeof(struct netif_rx_response), sizeof(struct netif_extra_info)));
    5.76        if (!extra_info_flag)
    5.77        {
    5.78          if (page_buf->rsp.status <= 0
    5.79 @@ -689,7 +689,7 @@ XenNet_RxBufferCheck(struct xennet_info 
    5.80          }
    5.81        buffer_count++;
    5.82      }
    5.83 -    xi->rx.rsp_cons = cons;
    5.84 +    xi->rx_ring.rsp_cons = cons;
    5.85  
    5.86      /* Give netback more buffers */
    5.87      XenNet_FillRing(xi);
    5.88 @@ -697,12 +697,12 @@ XenNet_RxBufferCheck(struct xennet_info 
    5.89      if (packet_count >= MAXIMUM_PACKETS_PER_INTERRUPT || packet_data >= MAXIMUM_DATA_PER_INTERRUPT)
    5.90        break;
    5.91  
    5.92 -    more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xi->rx);
    5.93 +    more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xi->rx_ring);
    5.94      if (!more_to_do)
    5.95      {
    5.96 -      xi->rx.sring->rsp_event = xi->rx.rsp_cons + 1;
    5.97 +      xi->rx_ring.sring->rsp_event = xi->rx_ring.rsp_cons + 1;
    5.98        KeMemoryBarrier();
    5.99 -      more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xi->rx);
   5.100 +      more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xi->rx_ring);
   5.101      }
   5.102    } while (more_to_do);
   5.103    
   5.104 @@ -862,7 +862,7 @@ XenNet_BufferFree(xennet_info_t *xi)
   5.105    /* because we are shutting down this won't allocate new ones */
   5.106    while ((sb = get_pb_from_freelist(xi)) != NULL)
   5.107    {
   5.108 -    xi->vectors.GntTbl_EndAccess(xi->vectors.context,
   5.109 +    XnEndAccess(xi->handle,
   5.110          sb->gref, FALSE, (ULONG)'XNRX');
   5.111      IoFreeMdl(sb->mdl);
   5.112      NdisFreeMemory(sb->virtual, sizeof(shared_buffer_t), 0);
     6.1 --- a/xennet/xennet6_tx.c	Fri Dec 14 21:44:03 2012 +1100
     6.2 +++ b/xennet/xennet6_tx.c	Sun Jan 06 14:08:22 2013 +1100
     6.3 @@ -42,14 +42,14 @@ static __forceinline struct netif_tx_req
     6.4  XenNet_PutCbOnRing(struct xennet_info *xi, PVOID coalesce_buf, ULONG length, grant_ref_t gref)
     6.5  {
     6.6    struct netif_tx_request *tx;
     6.7 -  tx = RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
     6.8 -  xi->tx.req_prod_pvt++;
     6.9 +  tx = RING_GET_REQUEST(&xi->tx_ring, xi->tx_ring.req_prod_pvt);
    6.10 +  xi->tx_ring.req_prod_pvt++;
    6.11    xi->tx_ring_free--;
    6.12    tx->id = get_id_from_freelist(xi);
    6.13    NT_ASSERT(xi->tx_shadows[tx->id].gref == INVALID_GRANT_REF);
    6.14    NT_ASSERT(!xi->tx_shadows[tx->id].cb);
    6.15    xi->tx_shadows[tx->id].cb = coalesce_buf;
    6.16 -  tx->gref = xi->vectors.GntTbl_GrantAccess(xi->vectors.context, (ULONG)(MmGetPhysicalAddress(coalesce_buf).QuadPart >> PAGE_SHIFT), FALSE, gref, (ULONG)'XNTX');
    6.17 +  tx->gref = XnGrantAccess(xi->handle, (ULONG)(MmGetPhysicalAddress(coalesce_buf).QuadPart >> PAGE_SHIFT), FALSE, gref, (ULONG)'XNTX');
    6.18    xi->tx_shadows[tx->id].gref = tx->gref;
    6.19    tx->offset = 0;
    6.20    tx->size = (USHORT)length;
    6.21 @@ -85,7 +85,7 @@ XenNet_HWSendPacket(struct xennet_info *
    6.22    
    6.23    //FUNCTION_ENTER();
    6.24  
    6.25 -  gref = xi->vectors.GntTbl_GetRef(xi->vectors.context, (ULONG)'XNTX');
    6.26 +  gref = XnAllocateGrant(xi->handle, (ULONG)'XNTX');
    6.27    if (gref == INVALID_GRANT_REF)
    6.28    {
    6.29      FUNCTION_MSG("out of grefs\n");
    6.30 @@ -94,7 +94,7 @@ XenNet_HWSendPacket(struct xennet_info *
    6.31    coalesce_buf = NdisAllocateFromNPagedLookasideList(&xi->tx_lookaside_list);
    6.32    if (!coalesce_buf)
    6.33    {
    6.34 -    xi->vectors.GntTbl_PutRef(xi->vectors.context, gref, (ULONG)'XNTX');
    6.35 +    XnFreeGrant(xi->handle, gref, (ULONG)'XNTX');
    6.36      FUNCTION_MSG("out of memory\n");
    6.37      return FALSE;
    6.38    }
    6.39 @@ -142,9 +142,9 @@ XenNet_HWSendPacket(struct xennet_info *
    6.40    /* if we have enough space on the ring then we have enough id's so no need to check for that */
    6.41    if (xi->tx_ring_free < frags + 1)
    6.42    {
    6.43 -    xi->vectors.GntTbl_PutRef(xi->vectors.context, gref, (ULONG)'XNTX');
    6.44 +    XnFreeGrant(xi->handle, gref, (ULONG)'XNTX');
    6.45      NdisFreeToNPagedLookasideList(&xi->tx_lookaside_list, coalesce_buf);
    6.46 -    //KdPrint((__DRIVER_NAME "     Full on send - ring full\n"));
    6.47 +    FUNCTION_MSG("Full on send - ring full\n");
    6.48      return FALSE;
    6.49    }
    6.50    XenNet_ParsePacketHeader(&pi, coalesce_buf, PAGE_SIZE);
    6.51 @@ -284,9 +284,9 @@ XenNet_HWSendPacket(struct xennet_info *
    6.52    if (xen_gso)
    6.53    {
    6.54      NT_ASSERT(flags & NETTXF_extra_info);
    6.55 -    ei = (struct netif_extra_info *)RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
    6.56 -    //KdPrint((__DRIVER_NAME "     pos = %d\n", xi->tx.req_prod_pvt));
    6.57 -    xi->tx.req_prod_pvt++;
    6.58 +    ei = (struct netif_extra_info *)RING_GET_REQUEST(&xi->tx_ring, xi->tx_ring.req_prod_pvt);
    6.59 +    //KdPrint((__DRIVER_NAME "     pos = %d\n", xi->tx_ring.req_prod_pvt));
    6.60 +    xi->tx_ring.req_prod_pvt++;
    6.61      xi->tx_ring_free--;
    6.62      ei->type = XEN_NETIF_EXTRA_TYPE_GSO;
    6.63      ei->flags = 0;
    6.64 @@ -311,7 +311,7 @@ XenNet_HWSendPacket(struct xennet_info *
    6.65        PVOID va;
    6.66        if (!coalesce_buf)
    6.67        {
    6.68 -        gref = xi->vectors.GntTbl_GetRef(xi->vectors.context, (ULONG)'XNTX');
    6.69 +        gref = XnAllocateGrant(xi->handle, (ULONG)'XNTX');
    6.70          if (gref == INVALID_GRANT_REF)
    6.71          {
    6.72            KdPrint((__DRIVER_NAME "     out of grefs - partial send\n"));
    6.73 @@ -320,7 +320,7 @@ XenNet_HWSendPacket(struct xennet_info *
    6.74          coalesce_buf = NdisAllocateFromNPagedLookasideList(&xi->tx_lookaside_list);
    6.75          if (!coalesce_buf)
    6.76          {
    6.77 -          xi->vectors.GntTbl_PutRef(xi->vectors.context, gref, (ULONG)'XNTX');
    6.78 +          XnFreeGrant(xi->handle, gref, (ULONG)'XNTX');
    6.79            KdPrint((__DRIVER_NAME "     out of memory - partial send\n"));
    6.80            break;
    6.81          }
    6.82 @@ -366,21 +366,21 @@ XenNet_HWSendPacket(struct xennet_info *
    6.83      {
    6.84        ULONG offset;
    6.85        
    6.86 -      gref = xi->vectors.GntTbl_GetRef(xi->vectors.context, (ULONG)'XNTX');
    6.87 +      gref = XnAllocateGrant(xi->handle, (ULONG)'XNTX');
    6.88        if (gref == INVALID_GRANT_REF)
    6.89        {
    6.90          KdPrint((__DRIVER_NAME "     out of grefs - partial send\n"));
    6.91          break;
    6.92        }
    6.93 -      txN = RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
    6.94 -      xi->tx.req_prod_pvt++;
    6.95 +      txN = RING_GET_REQUEST(&xi->tx_ring, xi->tx_ring.req_prod_pvt);
    6.96 +      xi->tx_ring.req_prod_pvt++;
    6.97        xi->tx_ring_free--;
    6.98        txN->id = get_id_from_freelist(xi);
    6.99        NT_ASSERT(!xi->tx_shadows[txN->id].cb);
   6.100        offset = MmGetMdlByteOffset(pi.curr_mdl) + pi.curr_mdl_offset;
   6.101        pfn = MmGetMdlPfnArray(pi.curr_mdl)[offset >> PAGE_SHIFT];
   6.102        txN->offset = (USHORT)offset & (PAGE_SIZE - 1);
   6.103 -      txN->gref = xi->vectors.GntTbl_GrantAccess(xi->vectors.context, (ULONG)pfn, FALSE, gref, (ULONG)'XNTX');
   6.104 +      txN->gref = XnGrantAccess(xi->handle, (ULONG)pfn, FALSE, gref, (ULONG)'XNTX');
   6.105        NT_ASSERT(xi->tx_shadows[txN->id].gref == INVALID_GRANT_REF);
   6.106        xi->tx_shadows[txN->id].gref = txN->gref;
   6.107        //ASSERT(sg->Elements[sg_element].Length > sg_offset);
   6.108 @@ -413,7 +413,7 @@ XenNet_HWSendPacket(struct xennet_info *
   6.109    //FUNCTION_EXIT();
   6.110    xi->tx_outstanding++;
   6.111  //total_sent++;
   6.112 -//FUNCTION_MSG("sent packet\n");
   6.113 +  //FUNCTION_MSG("sent packet\n");
   6.114    return TRUE;
   6.115  }
   6.116  
   6.117 @@ -428,26 +428,25 @@ XenNet_SendQueuedPackets(struct xennet_i
   6.118    //FUNCTION_ENTER();
   6.119  
   6.120    NT_ASSERT(!KeTestSpinLock(&xi->tx_lock));
   6.121 +#if 0
   6.122    if (xi->device_state->suspend_resume_state_pdo != SR_STATE_RUNNING)
   6.123      return;
   6.124 +#endif
   6.125  
   6.126 -  while (!IsListEmpty(&xi->tx_waiting_pkt_list))
   6.127 -  {
   6.128 +  while (!IsListEmpty(&xi->tx_waiting_pkt_list)) {
   6.129      nb_entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
   6.130      nb = CONTAINING_RECORD(nb_entry, NET_BUFFER, NB_LIST_ENTRY_FIELD);
   6.131      
   6.132 -    if (!XenNet_HWSendPacket(xi, nb))
   6.133 -    {
   6.134 +    if (!XenNet_HWSendPacket(xi, nb)) {
   6.135        //KdPrint((__DRIVER_NAME "     No room for packet\n"));
   6.136        InsertHeadList(&xi->tx_waiting_pkt_list, nb_entry);
   6.137        break;
   6.138      }
   6.139    }
   6.140  
   6.141 -  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xi->tx, notify);
   6.142 -  if (notify)
   6.143 -  {
   6.144 -    xi->vectors.EvtChn_Notify(xi->vectors.context, xi->event_channel);
   6.145 +  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xi->tx_ring, notify);
   6.146 +  if (notify) {
   6.147 +    XnNotify(xi->handle, xi->event_channel);
   6.148    }
   6.149    //FUNCTION_EXIT();
   6.150  }
   6.151 @@ -481,34 +480,30 @@ XenNet_TxBufferGC(struct xennet_info *xi
   6.152    }
   6.153  
   6.154    do {
   6.155 -    prod = xi->tx.sring->rsp_prod;
   6.156 +    prod = xi->tx_ring.sring->rsp_prod;
   6.157      KeMemoryBarrier(); /* Ensure we see responses up to 'rsp_prod'. */
   6.158  
   6.159 -    for (cons = xi->tx.rsp_cons; cons != prod; cons++)
   6.160 +    for (cons = xi->tx_ring.rsp_cons; cons != prod; cons++)
   6.161      {
   6.162        struct netif_tx_response *txrsp;
   6.163        tx_shadow_t *shadow;
   6.164        
   6.165 -      txrsp = RING_GET_RESPONSE(&xi->tx, cons);
   6.166 +      txrsp = RING_GET_RESPONSE(&xi->tx_ring, cons);
   6.167        
   6.168        xi->tx_ring_free++;
   6.169        
   6.170 -      if (txrsp->status == NETIF_RSP_NULL)
   6.171 -      {
   6.172 +      if (txrsp->status == NETIF_RSP_NULL) {
   6.173          continue;
   6.174        }
   6.175  
   6.176        shadow = &xi->tx_shadows[txrsp->id];
   6.177 -      if (shadow->cb)
   6.178 -      {
   6.179 +      if (shadow->cb) {
   6.180          NdisFreeToNPagedLookasideList(&xi->tx_lookaside_list, shadow->cb);
   6.181          shadow->cb = NULL;
   6.182        }
   6.183        
   6.184 -      if (shadow->gref != INVALID_GRANT_REF)
   6.185 -      {
   6.186 -        xi->vectors.GntTbl_EndAccess(xi->vectors.context,
   6.187 -          shadow->gref, FALSE, (ULONG)'XNTX');
   6.188 +      if (shadow->gref != INVALID_GRANT_REF) {
   6.189 +        XnEndAccess(xi->handle, shadow->gref, FALSE, (ULONG)'XNTX');
   6.190          shadow->gref = INVALID_GRANT_REF;
   6.191        }
   6.192        
   6.193 @@ -565,12 +560,12 @@ XenNet_TxBufferGC(struct xennet_info *xi
   6.194        put_id_on_freelist(xi, txrsp->id);
   6.195      }
   6.196  
   6.197 -    xi->tx.rsp_cons = prod;
   6.198 +    xi->tx_ring.rsp_cons = prod;
   6.199      /* resist the temptation to set the event more than +1... it breaks things */
   6.200      if (!dont_set_event)
   6.201 -      xi->tx.sring->rsp_event = prod + 1;
   6.202 +      xi->tx_ring.sring->rsp_event = prod + 1;
   6.203      KeMemoryBarrier();
   6.204 -  } while (prod != xi->tx.sring->rsp_prod);
   6.205 +  } while (prod != xi->tx_ring.sring->rsp_prod);
   6.206  
   6.207    /* if queued packets, send them now */
   6.208    if (!xi->tx_shutting_down)
   6.209 @@ -589,6 +584,7 @@ XenNet_TxBufferGC(struct xennet_info *xi
   6.210      KeSetEvent(&xi->tx_idle_event, IO_NO_INCREMENT, FALSE);
   6.211    KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
   6.212  
   6.213 +#if 0
   6.214    if (xi->device_state->suspend_resume_state_pdo == SR_STATE_SUSPENDING
   6.215      && xi->device_state->suspend_resume_state_fdo != SR_STATE_SUSPENDING
   6.216      && xi->tx_id_free == NET_TX_RING_SIZE)
   6.217 @@ -596,9 +592,9 @@ XenNet_TxBufferGC(struct xennet_info *xi
   6.218      KdPrint((__DRIVER_NAME "     Setting SR_STATE_SUSPENDING\n"));
   6.219      xi->device_state->suspend_resume_state_fdo = SR_STATE_SUSPENDING;
   6.220      KdPrint((__DRIVER_NAME "     Notifying event channel %d\n", xi->device_state->pdo_event_channel));
   6.221 -    xi->vectors.EvtChn_Notify(xi->vectors.context, xi->device_state->pdo_event_channel);
   6.222 +    XnNotify(xi->handle, xi->device_state->pdo_event_channel);
   6.223    }
   6.224 -
   6.225 +#endif
   6.226    //FUNCTION_EXIT();
   6.227  }
   6.228  
   6.229 @@ -752,8 +748,7 @@ XenNet_TxInit(xennet_info_t *xi)
   6.230      PAGE_SIZE, XENNET_POOL_TAG, 0);
   6.231  
   6.232    xi->tx_id_free = 0;
   6.233 -  for (i = 0; i < NET_TX_RING_SIZE; i++)
   6.234 -  {
   6.235 +  for (i = 0; i < NET_TX_RING_SIZE; i++) {
   6.236      xi->tx_shadows[i].gref = INVALID_GRANT_REF;
   6.237      xi->tx_shadows[i].cb = NULL;
   6.238      put_id_on_freelist(xi, i);
     7.1 --- a/xenpci/evtchn.c	Fri Dec 14 21:44:03 2012 +1100
     7.2 +++ b/xenpci/evtchn.c	Sun Jan 06 14:08:22 2013 +1100
     7.3 @@ -235,7 +235,7 @@ EvtChn_EvtInterruptDisable(WDFINTERRUPT 
     7.4  }
     7.5  
     7.6  NTSTATUS
     7.7 -EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, ULONG flags)
     7.8 +EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags)
     7.9  {
    7.10    PXENPCI_DEVICE_DATA xpdd = Context;
    7.11    ev_action_t *action = &xpdd->ev_actions[Port];
    7.12 @@ -263,7 +263,7 @@ EvtChn_Bind(PVOID Context, evtchn_port_t
    7.13  }
    7.14  
    7.15  NTSTATUS
    7.16 -EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, ULONG flags)
    7.17 +EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags)
    7.18  {
    7.19    PXENPCI_DEVICE_DATA xpdd = Context;
    7.20    ev_action_t *action = &xpdd->ev_actions[Port];
     8.1 --- a/xenpci/sources	Fri Dec 14 21:44:03 2012 +1100
     8.2 +++ b/xenpci/sources	Sun Jan 06 14:08:22 2013 +1100
     8.3 @@ -16,7 +16,7 @@ TARGETLIBS=$(TARGETLIBS) $(LIBLFDS_DIR)\
     8.4  AMD64_SOURCES=hypercall.asm dbgprint_hook.asm
     8.5  I386_SOURCES=tpr_emulate.asm dbgprint_hook.asm
     8.6  
     8.7 -SOURCES=xenpci.rc xenpci.c xenpci_fdo.c xenpci_pdo.c evtchn.c \
     8.8 -        gnttbl.c xenbus.c memory.c xenpci_device_interface.c \
     8.9 +SOURCES=xenpci.rc xenpci.c xenpci_fdo.c xenpci_pdo.c xenpci_export.c \
    8.10 +        evtchn.c gnttbl.c xenbus.c memory.c xenpci_device_interface.c \
    8.11          xenbus_device_interface.c xenpci_highsync.c xenpci_patch_kernel.c \
    8.12          xenpci_dbgprint.c
     9.1 --- a/xenpci/xenbus.c	Fri Dec 14 21:44:03 2012 +1100
     9.2 +++ b/xenpci/xenbus.c	Sun Jan 06 14:08:22 2013 +1100
     9.3 @@ -231,7 +231,7 @@ XenBus_WatchWorkItemProc(WDFWORKITEM wor
     9.4    PCHAR path;
     9.5    int index;
     9.6    PXENBUS_WATCH_ENTRY entry;
     9.7 -  PXENBUS_WATCH_CALLBACK service_routine;
     9.8 +  PXN_WATCH_CALLBACK service_routine;
     9.9    PVOID service_context;  
    9.10  
    9.11    //FUNCTION_ENTER();
    9.12 @@ -587,7 +587,7 @@ XenBus_AddWatch(
    9.13    PVOID Context,
    9.14    xenbus_transaction_t xbt,
    9.15    char *Path,
    9.16 -  PXENBUS_WATCH_CALLBACK ServiceRoutine,
    9.17 +  PXN_WATCH_CALLBACK ServiceRoutine,
    9.18    PVOID ServiceContext)
    9.19  {
    9.20    PXENPCI_DEVICE_DATA xpdd = Context;
    9.21 @@ -639,7 +639,7 @@ XenBus_RemWatch(
    9.22    PVOID Context,
    9.23    xenbus_transaction_t xbt,
    9.24    char *Path,
    9.25 -  PXENBUS_WATCH_CALLBACK ServiceRoutine,
    9.26 +  PXN_WATCH_CALLBACK ServiceRoutine,
    9.27    PVOID ServiceContext)
    9.28  {
    9.29    PXENPCI_DEVICE_DATA xpdd = Context;
    10.1 --- a/xenpci/xenpci.def	Fri Dec 14 21:44:03 2012 +1100
    10.2 +++ b/xenpci/xenpci.def	Sun Jan 06 14:08:22 2013 +1100
    10.3 @@ -4,3 +4,28 @@ EXPORTS
    10.4  ;  DllInitialize PRIVATE
    10.5  ;  DllUnload PRIVATE
    10.6  ;  XenTestExport
    10.7 +
    10.8 + XnGetVersion
    10.9 + XnOpenDevice
   10.10 + XnCloseDevice
   10.11 + XnGetValue
   10.12 +
   10.13 + XnAllocateEvent
   10.14 + XnFreeEvent
   10.15 + XnBindEvent
   10.16 + XnUnBindEvent
   10.17 + XnNotify
   10.18 +
   10.19 + XnAllocateGrant
   10.20 + XnFreeGrant
   10.21 + XnGrantAccess
   10.22 + XnEndAccess
   10.23 +
   10.24 +; XnAddWatch
   10.25 +; XnRemoveWatch
   10.26 + XnReadString
   10.27 + XnWriteString
   10.28 + XnReadInt32
   10.29 + XnWriteInt32
   10.30 + XnReadInt64
   10.31 + XnWriteInt64
    11.1 --- a/xenpci/xenpci.h	Fri Dec 14 21:44:03 2012 +1100
    11.2 +++ b/xenpci/xenpci.h	Sun Jan 06 14:08:22 2013 +1100
    11.3 @@ -85,7 +85,7 @@ extern USHORT xen_version_major;
    11.4  extern USHORT xen_version_minor;
    11.5  
    11.6  typedef struct _ev_action_t {
    11.7 -  PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine;
    11.8 +  PXN_EVENT_CALLBACK ServiceRoutine;
    11.9    PVOID ServiceContext;
   11.10    CHAR description[128];
   11.11    ULONG type; /* EVT_ACTION_TYPE_* */
   11.12 @@ -108,7 +108,7 @@ typedef struct xsd_sockmsg xsd_sockmsg_t
   11.13  
   11.14  typedef struct _XENBUS_WATCH_ENTRY {
   11.15    char Path[128];
   11.16 -  PXENBUS_WATCH_CALLBACK ServiceRoutine;
   11.17 +  PXN_WATCH_CALLBACK ServiceRoutine;
   11.18    PVOID ServiceContext;
   11.19    int Count;
   11.20    int Active;
   11.21 @@ -257,6 +257,8 @@ typedef struct {
   11.22    domid_t backend_id;
   11.23    KEVENT backend_state_event;
   11.24    ULONG backend_state;
   11.25 +  PXN_BACKEND_STATE_CALLBACK backend_state_callback;
   11.26 +  PVOID backend_state_callback_context;
   11.27    FAST_MUTEX backend_state_mutex;
   11.28    ULONG frontend_state;
   11.29    PMDL config_page_mdl;
   11.30 @@ -266,7 +268,7 @@ typedef struct {
   11.31    PUCHAR requested_resources_ptr;
   11.32    PUCHAR assigned_resources_start;
   11.33    PUCHAR assigned_resources_ptr;
   11.34 -  XENPCI_DEVICE_STATE device_state;
   11.35 +  //XENPCI_DEVICE_STATE device_state;
   11.36    BOOLEAN restart_on_resume;
   11.37    BOOLEAN backend_initiated_remove;
   11.38    BOOLEAN do_not_enumerate;
   11.39 @@ -328,6 +330,11 @@ typedef struct {
   11.40  
   11.41  WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_INTERFACE_DATA, GetXpdid)
   11.42  
   11.43 +static __inline VOID
   11.44 +XenPci_FreeMem(PVOID Ptr) {
   11.45 +  ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
   11.46 +}
   11.47 +
   11.48  NTSTATUS
   11.49  XenBus_DeviceFileInit(WDFDEVICE device, PWDF_IO_QUEUE_CONFIG queue_config, WDFFILEOBJECT file_object);
   11.50  
   11.51 @@ -410,9 +417,9 @@ XenBus_EndTransaction(PVOID Context, xen
   11.52  char *
   11.53  XenBus_List(PVOID Context, xenbus_transaction_t xbt, char *prefix, char ***contents);
   11.54  char *
   11.55 -XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
   11.56 +XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXN_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
   11.57  char *
   11.58 -XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
   11.59 +XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXN_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
   11.60  //VOID
   11.61  //XenBus_ThreadProc(PVOID StartContext);
   11.62  NTSTATUS
   11.63 @@ -443,9 +450,9 @@ EvtChn_Mask(PVOID Context, evtchn_port_t
   11.64  NTSTATUS
   11.65  EvtChn_Unmask(PVOID Context, evtchn_port_t Port);
   11.66  NTSTATUS
   11.67 -EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, ULONG flags);
   11.68 +EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags);
   11.69  NTSTATUS
   11.70 -EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, ULONG flags);
   11.71 +EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags);
   11.72  NTSTATUS
   11.73  EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector, PCHAR description, ULONG flags);
   11.74  evtchn_port_t
    12.1 --- a/xenpci/xenpci_dbgprint.c	Fri Dec 14 21:44:03 2012 +1100
    12.2 +++ b/xenpci/xenpci_dbgprint.c	Sun Jan 06 14:08:22 2013 +1100
    12.3 @@ -75,6 +75,7 @@ static void XenDbgPrint(PCHAR string, UL
    12.4    LARGE_INTEGER current_time;
    12.5    //KIRQL old_irql = 0;
    12.6  
    12.7 +  /* make sure that each print gets to complete in its entirety */
    12.8    while(InterlockedCompareExchange(&debug_print_lock, 1, 0) == 1)
    12.9      KeStallExecutionProcessor(1);
   12.10  
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/xenpci/xenpci_export.c	Sun Jan 06 14:08:22 2013 +1100
    13.3 @@ -0,0 +1,636 @@
    13.4 +/*
    13.5 +PV Drivers for Windows Xen HVM Domains
    13.6 +Copyright (C) 2012 James Harper
    13.7 +
    13.8 +This program is free software; you can redistribute it and/or
    13.9 +modify it under the terms of the GNU General Public License
   13.10 +as published by the Free Software Foundation; either version 2
   13.11 +of the License, or (at your option) any later version.
   13.12 +
   13.13 +This program is distributed in the hope that it will be useful,
   13.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.16 +GNU General Public License for more details.
   13.17 +
   13.18 +You should have received a copy of the GNU General Public License
   13.19 +along with this program; if not, write to the Free Software
   13.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   13.21 +*/
   13.22 +
   13.23 +#include "xenpci.h"
   13.24 +
   13.25 +ULONG
   13.26 +XnGetVersion() {
   13.27 +  return 1;
   13.28 +}
   13.29 +
   13.30 +static VOID
   13.31 +XnBackendStateCallback(char *path, PVOID context) {
   13.32 +  WDFDEVICE device = context;
   13.33 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
   13.34 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
   13.35 +  PCHAR err;
   13.36 +  PCHAR value;
   13.37 +  ULONG backend_state;
   13.38 +  
   13.39 +  FUNCTION_ENTER();
   13.40 +  //RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
   13.41 +  FUNCTION_MSG("Read path=%s\n", path);
   13.42 +  err = XenBus_Read(xpdd, XBT_NIL, path, &value);
   13.43 +  if (err) {
   13.44 +    FUNCTION_MSG("Error %s\n", err);
   13.45 +    XenPci_FreeMem(err);
   13.46 +    /* this is pretty catastrophic... */
   13.47 +    /* maybe call the callback with an unknown or something... or just ignore? */
   13.48 +    FUNCTION_EXIT();
   13.49 +    return;
   13.50 +  }
   13.51 +  FUNCTION_MSG("Read value=%s\n", value);
   13.52 +  backend_state = atoi(value);
   13.53 +  XenPci_FreeMem(value);
   13.54 +  xppdd->backend_state_callback(xppdd->backend_state_callback_context, backend_state);
   13.55 +  FUNCTION_EXIT();
   13.56 +}
   13.57 +
   13.58 +
   13.59 +char *
   13.60 +XenBus_AddWatchx(
   13.61 +  PVOID Context,
   13.62 +  xenbus_transaction_t xbt,
   13.63 +  char *Path,
   13.64 +  PXN_WATCH_CALLBACK ServiceRoutine,
   13.65 +  PVOID ServiceContext);
   13.66 +
   13.67 +XN_HANDLE
   13.68 +XnOpenDevice(PDEVICE_OBJECT pdo, PXN_BACKEND_STATE_CALLBACK callback, PVOID context) {
   13.69 +  WDFDEVICE device;
   13.70 +  PXENPCI_PDO_DEVICE_DATA xppdd;
   13.71 +  PXENPCI_DEVICE_DATA xpdd;
   13.72 +  PCHAR response;
   13.73 +  CHAR path[128];
   13.74 +  
   13.75 +  FUNCTION_ENTER();
   13.76 +  device = WdfWdmDeviceGetWdfDeviceHandle(pdo);
   13.77 +  if (!device) {
   13.78 +    FUNCTION_MSG("Failed to get WDFDEVICE for %p\n", pdo);
   13.79 +    return NULL;
   13.80 +  }
   13.81 +  xppdd = GetXppdd(device);
   13.82 +  xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
   13.83 +  xppdd->backend_state_callback = callback;
   13.84 +  xppdd->backend_state_callback_context = context;
   13.85 +  RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
   13.86 +  response = XenBus_AddWatch(xpdd, XBT_NIL, path, XnBackendStateCallback, device);
   13.87 +  if (response) {
   13.88 +    FUNCTION_MSG("XnAddWatch - %s = %s\n", path, response);
   13.89 +    XenPci_FreeMem(response);
   13.90 +    xppdd->backend_state_callback = NULL;
   13.91 +    xppdd->backend_state_callback_context = NULL;
   13.92 +    FUNCTION_EXIT();
   13.93 +    return NULL;
   13.94 +  }
   13.95 +
   13.96 +  FUNCTION_EXIT();
   13.97 +  return device;
   13.98 +}
   13.99 +
  13.100 +VOID
  13.101 +XnCloseDevice(XN_HANDLE handle) {
  13.102 +  UNREFERENCED_PARAMETER(handle);
  13.103 +}
  13.104 +
  13.105 +#if 0
  13.106 +NTSTATUS
  13.107 +XnAddWatch(XN_HANDLE handle, char *path, PXN_WATCH_CALLBACK callback, PVOID context) {
  13.108 +  WDFDEVICE device = handle;
  13.109 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.110 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.111 +  PCHAR response;
  13.112 +  NTSTATUS status;
  13.113 +  
  13.114 +  response = XenBus_AddWatch(xpdd, XBT_NIL, path, callback, context);
  13.115 +  if (response == NULL) {
  13.116 +    FUNCTION_MSG("XnAddWatch - %s = NULL\n", path);
  13.117 +    status = STATUS_SUCCESS;
  13.118 +  } else {
  13.119 +    FUNCTION_MSG("XnAddWatch - %s = %s\n", path, response);
  13.120 +    XenPci_FreeMem(response);
  13.121 +    status = STATUS_UNSUCCESSFUL;
  13.122 +  }
  13.123 +  return status;
  13.124 +}
  13.125 +
  13.126 +NTSTATUS
  13.127 +XnRemoveWatch(XN_HANDLE handle, char *path, PXN_WATCH_CALLBACK callback, PVOID context) {
  13.128 +  WDFDEVICE device = handle;
  13.129 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.130 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.131 +  PCHAR response;
  13.132 +  NTSTATUS status;
  13.133 +
  13.134 +  response = XenBus_RemWatch(xpdd, XBT_NIL, path, callback, context);
  13.135 +  if (response == NULL) {
  13.136 +    FUNCTION_MSG("XnRemoveWatch - %s = NULL\n", path);
  13.137 +    status = STATUS_SUCCESS;
  13.138 +  } else {
  13.139 +    FUNCTION_MSG("XnRemoveWatch - %s = %s\n", path, response);
  13.140 +    XenPci_FreeMem(response);
  13.141 +    status = STATUS_UNSUCCESSFUL;
  13.142 +  }
  13.143 +}
  13.144 +#endif
  13.145 +
  13.146 +evtchn_port_t
  13.147 +XnAllocateEvent(XN_HANDLE handle) {
  13.148 +  WDFDEVICE device = handle;
  13.149 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.150 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.151 +  return EvtChn_AllocUnbound(xpdd, xppdd->backend_id);
  13.152 +}
  13.153 +
  13.154 +VOID
  13.155 +XnFreeEvent(XN_HANDLE handle, evtchn_port_t port) {
  13.156 +  WDFDEVICE device = handle;
  13.157 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.158 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.159 +  EvtChn_Close(xpdd, port);
  13.160 +  return;
  13.161 +}
  13.162 +
  13.163 +NTSTATUS
  13.164 +XnBindEvent(XN_HANDLE handle, evtchn_port_t port, PXN_EVENT_CALLBACK callback, PVOID context) {
  13.165 +  WDFDEVICE device = handle;
  13.166 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.167 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.168 +  return EvtChn_Bind(xpdd, port, callback, context, EVT_ACTION_FLAGS_DEFAULT);
  13.169 +}
  13.170 +
  13.171 +NTSTATUS
  13.172 +XnUnBindEvent(XN_HANDLE handle, evtchn_port_t port) {
  13.173 +  WDFDEVICE device = handle;
  13.174 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.175 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.176 +  return EvtChn_Unbind(xpdd, port);
  13.177 +}
  13.178 +
  13.179 +grant_ref_t
  13.180 +XnGrantAccess(XN_HANDLE handle, uint32_t frame, int readonly, grant_ref_t ref, ULONG tag)
  13.181 +{
  13.182 +  WDFDEVICE device = handle;
  13.183 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.184 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.185 +  return GntTbl_GrantAccess(xpdd, xppdd->backend_id, frame, readonly, ref, tag);
  13.186 +}
  13.187 +
  13.188 +BOOLEAN
  13.189 +XnEndAccess(XN_HANDLE handle, grant_ref_t ref, BOOLEAN keepref, ULONG tag)
  13.190 +{
  13.191 +  WDFDEVICE device = handle;
  13.192 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.193 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.194 +  return GntTbl_EndAccess(xpdd, ref, keepref, tag);
  13.195 +}
  13.196 +
  13.197 +grant_ref_t
  13.198 +XnAllocateGrant(XN_HANDLE handle, ULONG tag) {
  13.199 +  WDFDEVICE device = handle;
  13.200 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.201 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.202 +  return GntTbl_GetRef(xpdd, tag);
  13.203 +}
  13.204 +
  13.205 +VOID
  13.206 +XnFreeGrant(XN_HANDLE handle, grant_ref_t ref, ULONG tag) {
  13.207 +  WDFDEVICE device = handle;
  13.208 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.209 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.210 +  GntTbl_PutRef(xpdd, ref, tag);
  13.211 +}
  13.212 +
  13.213 +/* result must be freed with XnFreeMem() */
  13.214 +NTSTATUS
  13.215 +XnReadString(XN_HANDLE handle, ULONG base, PCHAR path, PCHAR *value) {
  13.216 +  WDFDEVICE device = handle;
  13.217 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.218 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.219 +  PCHAR response;
  13.220 +  CHAR full_path[1024];
  13.221 +  
  13.222 +  switch(base) {
  13.223 +  case XN_BASE_FRONTEND:
  13.224 +    strncpy(full_path, xppdd->path, 1024);
  13.225 +    break;
  13.226 +  case XN_BASE_BACKEND:
  13.227 +    strncpy(full_path, xppdd->backend_path, 1024);
  13.228 +    break;
  13.229 +  case XN_BASE_GLOBAL:
  13.230 +    strncpy(full_path, "", 1024);
  13.231 +  }
  13.232 +  strncat(full_path, "/", 1024);
  13.233 +  strncat(full_path, path, 1024);
  13.234 +  
  13.235 +  response = XenBus_Read(xpdd, XBT_NIL, full_path, value);
  13.236 +  if (response) {
  13.237 +    FUNCTION_MSG("Error reading shutdown path - %s\n", response);
  13.238 +    XenPci_FreeMem(response);
  13.239 +    FUNCTION_EXIT();
  13.240 +    return STATUS_UNSUCCESSFUL;
  13.241 +  }
  13.242 +  return STATUS_SUCCESS;
  13.243 +}
  13.244 +
  13.245 +NTSTATUS
  13.246 +XnWriteString(XN_HANDLE handle, ULONG base, PCHAR path, PCHAR value) {
  13.247 +  WDFDEVICE device = handle;
  13.248 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.249 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.250 +  PCHAR response;
  13.251 +  CHAR full_path[1024];
  13.252 +
  13.253 +  switch(base) {
  13.254 +  case XN_BASE_FRONTEND:
  13.255 +    strncpy(full_path, xppdd->path, 1024);
  13.256 +    break;
  13.257 +  case XN_BASE_BACKEND:
  13.258 +    strncpy(full_path, xppdd->backend_path, 1024);
  13.259 +    break;
  13.260 +  case XN_BASE_GLOBAL:
  13.261 +    strncpy(full_path, "", 1024);
  13.262 +  }
  13.263 +  strncat(full_path, "/", 1024);
  13.264 +  strncat(full_path, path, 1024);
  13.265 +  FUNCTION_MSG("XnWriteString(%s, %s)\n", full_path, value);
  13.266 +  response = XenBus_Write(xpdd, XBT_NIL, full_path, value);
  13.267 +  if (response) {
  13.268 +    FUNCTION_MSG("XnWriteString - %s = %s\n", full_path, response);
  13.269 +    XenPci_FreeMem(response);
  13.270 +    FUNCTION_EXIT();
  13.271 +    return STATUS_UNSUCCESSFUL;
  13.272 +  }
  13.273 +  return STATUS_SUCCESS;
  13.274 +}
  13.275 +
  13.276 +NTSTATUS
  13.277 +XnReadInt32(XN_HANDLE handle, ULONG base, PCHAR path, ULONG *value) {
  13.278 +  WDFDEVICE device = handle;
  13.279 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.280 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.281 +  CHAR full_path[1024];
  13.282 +  PCHAR response;
  13.283 +  PCHAR string_value;
  13.284 +
  13.285 +  switch(base) {
  13.286 +  case XN_BASE_FRONTEND:
  13.287 +    strncpy(full_path, xppdd->path, 1024);
  13.288 +    break;
  13.289 +  case XN_BASE_BACKEND:
  13.290 +    strncpy(full_path, xppdd->backend_path, 1024);
  13.291 +    break;
  13.292 +  case XN_BASE_GLOBAL:
  13.293 +    strncpy(full_path, "", 1024);
  13.294 +  }
  13.295 +  strncat(full_path, "/", 1024);
  13.296 +  strncat(full_path, path, 1024);
  13.297 +  response = XenBus_Read(xpdd, XBT_NIL, full_path, &string_value);
  13.298 +  if (response) {
  13.299 +    FUNCTION_MSG("XnReadInt - %s = %s\n", full_path, response);
  13.300 +    XenPci_FreeMem(response);
  13.301 +    FUNCTION_EXIT();
  13.302 +    return STATUS_UNSUCCESSFUL;
  13.303 +  }
  13.304 +  *value = atoi(string_value);
  13.305 +  return STATUS_SUCCESS;
  13.306 +}
  13.307 +
  13.308 +NTSTATUS
  13.309 +XnWriteInt32(XN_HANDLE handle, ULONG base, PCHAR path, ULONG value) {
  13.310 +  WDFDEVICE device = handle;
  13.311 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.312 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.313 +  CHAR full_path[1024];
  13.314 +  PCHAR response;
  13.315 +  
  13.316 +  switch(base) {
  13.317 +  case XN_BASE_FRONTEND:
  13.318 +    strncpy(full_path, xppdd->path, 1024);
  13.319 +    break;
  13.320 +  case XN_BASE_BACKEND:
  13.321 +    strncpy(full_path, xppdd->backend_path, 1024);
  13.322 +    break;
  13.323 +  case XN_BASE_GLOBAL:
  13.324 +    strncpy(full_path, "", 1024);
  13.325 +  }
  13.326 +  strncat(full_path, "/", 1024);
  13.327 +  strncat(full_path, path, 1024);
  13.328 +  
  13.329 +  FUNCTION_MSG("XnWriteInt32(%s, %d)\n", full_path, value);
  13.330 +  response = XenBus_Printf(xpdd, XBT_NIL, full_path, "%d", value);
  13.331 +  if (response) {
  13.332 +    FUNCTION_MSG("XnWriteInt - %s = %s\n", full_path, response);
  13.333 +    XenPci_FreeMem(response);
  13.334 +    FUNCTION_EXIT();
  13.335 +    return STATUS_UNSUCCESSFUL;
  13.336 +  }
  13.337 +  return STATUS_SUCCESS;
  13.338 +}
  13.339 +
  13.340 +NTSTATUS
  13.341 +XnReadInt64(XN_HANDLE handle, ULONG base, PCHAR path, ULONGLONG *value) {
  13.342 +  WDFDEVICE device = handle;
  13.343 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.344 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.345 +  CHAR full_path[1024];
  13.346 +  PCHAR response;
  13.347 +  PCHAR string_value;
  13.348 +  PCHAR ptr;
  13.349 +
  13.350 +  switch(base) {
  13.351 +  case XN_BASE_FRONTEND:
  13.352 +    strncpy(full_path, xppdd->path, 1024);
  13.353 +    break;
  13.354 +  case XN_BASE_BACKEND:
  13.355 +    strncpy(full_path, xppdd->backend_path, 1024);
  13.356 +    break;
  13.357 +  case XN_BASE_GLOBAL:
  13.358 +    strncpy(full_path, "", 1024);
  13.359 +    break;
  13.360 +  }
  13.361 +  strncat(full_path, "/", 1024);
  13.362 +  strncat(full_path, path, 1024);
  13.363 +  response = XenBus_Read(xpdd, XBT_NIL, full_path, &string_value);
  13.364 +  if (response) {
  13.365 +    FUNCTION_MSG("XnReadInt - %s = %s\n", full_path, response);
  13.366 +    XenPci_FreeMem(response);
  13.367 +    FUNCTION_EXIT();
  13.368 +    return STATUS_UNSUCCESSFUL;
  13.369 +  }
  13.370 +  *value = 0;
  13.371 +  for (ptr = string_value; *ptr && *ptr >= '0' && *ptr <= '9'; ptr++) {
  13.372 +    *value *= 10;
  13.373 +    *value += (*ptr) - '0';
  13.374 +  }
  13.375 +  return STATUS_SUCCESS;
  13.376 +}
  13.377 +
  13.378 +NTSTATUS
  13.379 +XnWriteInt64(XN_HANDLE handle, ULONG base, PCHAR path, ULONGLONG value) {
  13.380 +  WDFDEVICE device = handle;
  13.381 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.382 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.383 +  CHAR full_path[1024];
  13.384 +  PCHAR response;
  13.385 +  
  13.386 +  switch(base) {
  13.387 +  case XN_BASE_FRONTEND:
  13.388 +    strncpy(full_path, xppdd->path, 1024);
  13.389 +    break;
  13.390 +  case XN_BASE_BACKEND:
  13.391 +    strncpy(full_path, xppdd->backend_path, 1024);
  13.392 +    break;
  13.393 +  case XN_BASE_GLOBAL:
  13.394 +    strncpy(full_path, "", 1024);
  13.395 +  }
  13.396 +  strncat(full_path, "/", 1024);
  13.397 +  strncat(full_path, path, 1024);
  13.398 +  
  13.399 +  response = XenBus_Printf(xpdd, XBT_NIL, full_path, "%I64d", value);
  13.400 +  if (response) {
  13.401 +    FUNCTION_MSG("XnWriteInt - %s = %s\n", full_path, response);
  13.402 +    XenPci_FreeMem(response);
  13.403 +    FUNCTION_EXIT();
  13.404 +    return STATUS_UNSUCCESSFUL;
  13.405 +  }
  13.406 +  return STATUS_SUCCESS;
  13.407 +}
  13.408 +
  13.409 +NTSTATUS
  13.410 +XnNotify(XN_HANDLE handle, evtchn_port_t port) {
  13.411 +  WDFDEVICE device = handle;
  13.412 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.413 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.414 +  
  13.415 +  return EvtChn_Notify(xpdd, port);
  13.416 +}
  13.417 +
  13.418 +/* called at PASSIVE_LEVEL */
  13.419 +VOID
  13.420 +XnGetValue(XN_HANDLE handle, ULONG value_type, PVOID value) {
  13.421 +  WDFDEVICE device = handle;
  13.422 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.423 +  //PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.424 +  DECLARE_UNICODE_STRING_SIZE(my_device_name, 128);
  13.425 +  ULONG i;
  13.426 +
  13.427 +  switch (value_type) {
  13.428 +  case XN_VALUE_TYPE_QEMU_HIDE_FLAGS:
  13.429 +    *(PULONG)value = (ULONG)qemu_hide_flags_value;
  13.430 +    break;
  13.431 +  case XN_VALUE_TYPE_QEMU_FILTER:
  13.432 +    *(PULONG)value = FALSE;
  13.433 +    RtlUnicodeStringPrintf(&my_device_name, L"#%S#", xppdd->device);
  13.434 +    for (i = 0; i < WdfCollectionGetCount(qemu_hide_devices); i++) {
  13.435 +      WDFSTRING wdf_string = WdfCollectionGetItem(qemu_hide_devices, i);
  13.436 +      UNICODE_STRING hide_device_name;
  13.437 +      WdfStringGetUnicodeString(wdf_string, &hide_device_name);
  13.438 +      if (RtlCompareUnicodeString(&hide_device_name, &my_device_name, TRUE) != 0) {
  13.439 +        *(PULONG)value = TRUE;
  13.440 +        break;
  13.441 +      }
  13.442 +    }
  13.443 +    break;
  13.444 +  default:
  13.445 +    FUNCTION_MSG("GetValue unknown type %d\n", value_type);
  13.446 +    break;
  13.447 +  }
  13.448 +}
  13.449 +
  13.450 +#if 0
  13.451 +static NTSTATUS
  13.452 +XenConfig_InitConfigPage(WDFDEVICE device)
  13.453 +{
  13.454 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.455 +  //PXENCONFIG_DEVICE_DATA xcdd = (PXENCONFIG_DEVICE_DATA)device_object->DeviceExtension;
  13.456 +  //PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
  13.457 +  //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
  13.458 +  PUCHAR ptr;
  13.459 +  PDEVICE_OBJECT curr, prev;
  13.460 +  PDRIVER_OBJECT fdo_driver_object;
  13.461 +  PUCHAR fdo_driver_extension;
  13.462 +  
  13.463 +  FUNCTION_ENTER();
  13.464 +  
  13.465 +  ptr = MmGetMdlVirtualAddress(xppdd->config_page_mdl);
  13.466 +  curr = IoGetAttachedDeviceReference(WdfDeviceWdmGetDeviceObject(device));
  13.467 +  //curr = WdfDeviceWdmGetAttachedDevice(device);
  13.468 +  while (curr != NULL)
  13.469 +  {
  13.470 +    fdo_driver_object = curr->DriverObject;
  13.471 +    KdPrint((__DRIVER_NAME "     fdo_driver_object = %p\n", fdo_driver_object));
  13.472 +    if (fdo_driver_object)
  13.473 +    {
  13.474 +      fdo_driver_extension = IoGetDriverObjectExtension(fdo_driver_object, UlongToPtr(XEN_INIT_DRIVER_EXTENSION_MAGIC));
  13.475 +      KdPrint((__DRIVER_NAME "     fdo_driver_extension = %p\n", fdo_driver_extension));
  13.476 +      if (fdo_driver_extension)
  13.477 +      {
  13.478 +        memcpy(ptr, fdo_driver_extension, PAGE_SIZE);
  13.479 +        ObDereferenceObject(curr);
  13.480 +        break;
  13.481 +      }
  13.482 +    }
  13.483 +    prev = curr;
  13.484 +    curr = IoGetLowerDeviceObject(curr);
  13.485 +    ObDereferenceObject(prev);
  13.486 +  }
  13.487 +  
  13.488 +  FUNCTION_EXIT();
  13.489 +  
  13.490 +  return STATUS_SUCCESS;
  13.491 +}
  13.492 +
  13.493 +static NTSTATUS
  13.494 +XenPci_EvtChn_Bind(PVOID context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
  13.495 +{
  13.496 +  WDFDEVICE device = context;
  13.497 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.498 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.499 +  
  13.500 +  return EvtChn_Bind(xpdd, Port, ServiceRoutine, ServiceContext, EVT_ACTION_FLAGS_DEFAULT);
  13.501 +}
  13.502 +
  13.503 +static NTSTATUS
  13.504 +XenPci_EvtChn_BindDpc(PVOID context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
  13.505 +{
  13.506 +  WDFDEVICE device = context;
  13.507 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.508 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.509 +  
  13.510 +  return EvtChn_BindDpc(xpdd, Port, ServiceRoutine, ServiceContext, EVT_ACTION_FLAGS_DEFAULT);
  13.511 +}
  13.512 +
  13.513 +static NTSTATUS
  13.514 +XenPci_EvtChn_Unbind(PVOID context, evtchn_port_t Port)
  13.515 +{
  13.516 +  WDFDEVICE device = context;
  13.517 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.518 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.519 +  
  13.520 +  return EvtChn_Unbind(xpdd, Port);
  13.521 +}
  13.522 +
  13.523 +static NTSTATUS
  13.524 +XenPci_EvtChn_Mask(PVOID context, evtchn_port_t Port)
  13.525 +{
  13.526 +  WDFDEVICE device = context;
  13.527 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.528 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.529 +  
  13.530 +  return EvtChn_Mask(xpdd, Port);
  13.531 +}
  13.532 +
  13.533 +static NTSTATUS
  13.534 +XenPci_EvtChn_Unmask(PVOID context, evtchn_port_t Port)
  13.535 +{
  13.536 +  WDFDEVICE device = context;
  13.537 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.538 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.539 +  
  13.540 +  return EvtChn_Unmask(xpdd, Port);
  13.541 +}
  13.542 +
  13.543 +static BOOLEAN
  13.544 +XenPci_EvtChn_AckEvent(PVOID context, evtchn_port_t port, BOOLEAN *last_interrupt)
  13.545 +{
  13.546 +  WDFDEVICE device = context;
  13.547 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.548 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.549 +  
  13.550 +  return EvtChn_AckEvent(xpdd, port, last_interrupt);
  13.551 +}
  13.552 +
  13.553 +typedef struct {
  13.554 +  PXEN_EVTCHN_SYNC_ROUTINE sync_routine;
  13.555 +  PVOID sync_context;
  13.556 +} sync_context_t;
  13.557 +
  13.558 +static BOOLEAN
  13.559 +XenPci_EvtChn_Sync_Routine(WDFINTERRUPT interrupt, WDFCONTEXT context)
  13.560 +{
  13.561 +  sync_context_t *wdf_sync_context = context;
  13.562 +  UNREFERENCED_PARAMETER(interrupt);
  13.563 +  return wdf_sync_context->sync_routine(wdf_sync_context->sync_context);
  13.564 +}
  13.565 +
  13.566 +static BOOLEAN
  13.567 +XenPci_EvtChn_Sync(PVOID context, PXEN_EVTCHN_SYNC_ROUTINE sync_routine, PVOID sync_context)
  13.568 +{
  13.569 +  WDFDEVICE device = context;
  13.570 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.571 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.572 +  sync_context_t wdf_sync_context;
  13.573 +  
  13.574 +  wdf_sync_context.sync_routine = sync_routine;
  13.575 +  wdf_sync_context.sync_context = sync_context;
  13.576 +  
  13.577 +  return WdfInterruptSynchronize(xpdd->interrupt, XenPci_EvtChn_Sync_Routine, &wdf_sync_context);
  13.578 +}
  13.579 +
  13.580 +
  13.581 +PCHAR
  13.582 +XenPci_XenBus_Read(PVOID context, xenbus_transaction_t xbt, char *path, char **value)
  13.583 +{
  13.584 +  WDFDEVICE device = context;
  13.585 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.586 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.587 +  return XenBus_Read(xpdd, xbt, path, value);
  13.588 +}
  13.589 +
  13.590 +PCHAR
  13.591 +XenPci_XenBus_Write(PVOID context, xenbus_transaction_t xbt, char *path, char *value)
  13.592 +{
  13.593 +  WDFDEVICE device = context;
  13.594 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.595 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.596 +  return XenBus_Write(xpdd, xbt, path, value);
  13.597 +}
  13.598 +
  13.599 +PCHAR
  13.600 +XenPci_XenBus_Printf(PVOID context, xenbus_transaction_t xbt, char *path, char *fmt, ...)
  13.601 +{
  13.602 +  //PXENPCI_PDO_DEVICE_DATA xppdd = Context;
  13.603 +  //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
  13.604 +  //return XenBus_Printf(xpdd, xbt, path, value);
  13.605 +  UNREFERENCED_PARAMETER(context);
  13.606 +  UNREFERENCED_PARAMETER(xbt);
  13.607 +  UNREFERENCED_PARAMETER(path);
  13.608 +  UNREFERENCED_PARAMETER(fmt);
  13.609 +  return NULL;
  13.610 +}
  13.611 +
  13.612 +PCHAR
  13.613 +XenPci_XenBus_StartTransaction(PVOID context, xenbus_transaction_t *xbt)
  13.614 +{
  13.615 +  WDFDEVICE device = context;
  13.616 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.617 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.618 +  return XenBus_StartTransaction(xpdd, xbt);
  13.619 +}
  13.620 +
  13.621 +PCHAR
  13.622 +XenPci_XenBus_EndTransaction(PVOID context, xenbus_transaction_t xbt, int abort, int *retry)
  13.623 +{
  13.624 +  WDFDEVICE device = context;
  13.625 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.626 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.627 +  return XenBus_EndTransaction(xpdd, xbt, abort, retry);
  13.628 +}
  13.629 +
  13.630 +PCHAR
  13.631 +XenPci_XenBus_List(PVOID context, xenbus_transaction_t xbt, char *prefix, char ***contents)
  13.632 +{
  13.633 +  WDFDEVICE device = context;
  13.634 +  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  13.635 +  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  13.636 +  return XenBus_List(xpdd, xbt, prefix, contents);
  13.637 +}
  13.638 +
  13.639 +#endif
    14.1 --- a/xenpci/xenpci_fdo.c	Fri Dec 14 21:44:03 2012 +1100
    14.2 +++ b/xenpci/xenpci_fdo.c	Sun Jan 06 14:08:22 2013 +1100
    14.3 @@ -554,7 +554,9 @@ XenPci_SuspendResume(WDFWORKITEM workite
    14.4      while ((status = WdfChildListRetrieveNextDevice(child_list, &child_iterator, &child_device, NULL)) == STATUS_SUCCESS)
    14.5      {
    14.6        KdPrint((__DRIVER_NAME "     Suspending child\n"));
    14.7 +#if 0
    14.8        XenPci_Pdo_Suspend(child_device);
    14.9 +#endif
   14.10      }
   14.11      WdfChildListEndIteration(child_list, &child_iterator);
   14.12  
   14.13 @@ -571,7 +573,9 @@ XenPci_SuspendResume(WDFWORKITEM workite
   14.14      while ((status = WdfChildListRetrieveNextDevice(child_list, &child_iterator, &child_device, NULL)) == STATUS_SUCCESS)
   14.15      {
   14.16        KdPrint((__DRIVER_NAME "     Resuming child\n"));
   14.17 +#if 0
   14.18        XenPci_Pdo_Resume(child_device);
   14.19 +#endif
   14.20      }
   14.21      WdfChildListEndIteration(child_list, &child_iterator);
   14.22  
    15.1 --- a/xenpci/xenpci_pdo.c	Fri Dec 14 21:44:03 2012 +1100
    15.2 +++ b/xenpci/xenpci_pdo.c	Sun Jan 06 14:08:22 2013 +1100
    15.3 @@ -63,6 +63,7 @@ XenPci_ReadBackendState(PXENPCI_PDO_DEVI
    15.4    }
    15.5  }
    15.6  
    15.7 +#if 0
    15.8  static NTSTATUS
    15.9  XenPciPdo_ReconfigureCompletionRoutine(
   15.10    PDEVICE_OBJECT device_object,
   15.11 @@ -77,6 +78,7 @@ XenPciPdo_ReconfigureCompletionRoutine(
   15.12    }
   15.13    return STATUS_MORE_PROCESSING_REQUIRED;
   15.14  }
   15.15 +#endif
   15.16  
   15.17  static VOID
   15.18  XenPci_UpdateBackendState(PVOID context)
   15.19 @@ -172,7 +174,7 @@ XenPci_BackendStateHandler(char *path, P
   15.20  }
   15.21  
   15.22  static NTSTATUS
   15.23 -XenPci_GetBackendAndAddWatch(WDFDEVICE device)
   15.24 +XenPci_GetBackendDetails(WDFDEVICE device)
   15.25  {
   15.26    PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
   15.27    PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
   15.28 @@ -205,283 +207,16 @@ XenPci_GetBackendAndAddWatch(WDFDEVICE d
   15.29    }
   15.30    xppdd->backend_id = (domid_t)atoi(value);
   15.31    XenPci_FreeMem(value);
   15.32 -
   15.33 +#if 0
   15.34    /* Add watch on backend state */
   15.35    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
   15.36    XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackendStateHandler, device);
   15.37 +#endif
   15.38  
   15.39    FUNCTION_EXIT();  
   15.40    return STATUS_SUCCESS;
   15.41  }
   15.42  
   15.43 -static NTSTATUS
   15.44 -XenConfig_InitConfigPage(WDFDEVICE device)
   15.45 -{
   15.46 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
   15.47 -  //PXENCONFIG_DEVICE_DATA xcdd = (PXENCONFIG_DEVICE_DATA)device_object->DeviceExtension;
   15.48 -  //PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
   15.49 -  //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
   15.50 -  PUCHAR ptr;
   15.51 -  PDEVICE_OBJECT curr, prev;
   15.52 -  PDRIVER_OBJECT fdo_driver_object;
   15.53 -  PUCHAR fdo_driver_extension;
   15.54 -  
   15.55 -  FUNCTION_ENTER();
   15.56 -  
   15.57 -  ptr = MmGetMdlVirtualAddress(xppdd->config_page_mdl);
   15.58 -  curr = IoGetAttachedDeviceReference(WdfDeviceWdmGetDeviceObject(device));
   15.59 -  //curr = WdfDeviceWdmGetAttachedDevice(device);
   15.60 -  while (curr != NULL)
   15.61 -  {
   15.62 -    fdo_driver_object = curr->DriverObject;
   15.63 -    KdPrint((__DRIVER_NAME "     fdo_driver_object = %p\n", fdo_driver_object));
   15.64 -    if (fdo_driver_object)
   15.65 -    {
   15.66 -      fdo_driver_extension = IoGetDriverObjectExtension(fdo_driver_object, UlongToPtr(XEN_INIT_DRIVER_EXTENSION_MAGIC));
   15.67 -      KdPrint((__DRIVER_NAME "     fdo_driver_extension = %p\n", fdo_driver_extension));
   15.68 -      if (fdo_driver_extension)
   15.69 -      {
   15.70 -        memcpy(ptr, fdo_driver_extension, PAGE_SIZE);
   15.71 -        ObDereferenceObject(curr);
   15.72 -        break;
   15.73 -      }
   15.74 -    }
   15.75 -    prev = curr;
   15.76 -    curr = IoGetLowerDeviceObject(curr);
   15.77 -    ObDereferenceObject(prev);
   15.78 -  }
   15.79 -  
   15.80 -  FUNCTION_EXIT();
   15.81 -  
   15.82 -  return STATUS_SUCCESS;
   15.83 -}
   15.84 -
   15.85 -static NTSTATUS
   15.86 -XenPci_EvtChn_Bind(PVOID context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
   15.87 -{
   15.88 -  WDFDEVICE device = context;
   15.89 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
   15.90 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
   15.91 -  
   15.92 -  return EvtChn_Bind(xpdd, Port, ServiceRoutine, ServiceContext, EVT_ACTION_FLAGS_DEFAULT);
   15.93 -}
   15.94 -
   15.95 -static NTSTATUS
   15.96 -XenPci_EvtChn_BindDpc(PVOID context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
   15.97 -{
   15.98 -  WDFDEVICE device = context;
   15.99 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.100 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.101 -  
  15.102 -  return EvtChn_BindDpc(xpdd, Port, ServiceRoutine, ServiceContext, EVT_ACTION_FLAGS_DEFAULT);
  15.103 -}
  15.104 -
  15.105 -static NTSTATUS
  15.106 -XenPci_EvtChn_Unbind(PVOID context, evtchn_port_t Port)
  15.107 -{
  15.108 -  WDFDEVICE device = context;
  15.109 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.110 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.111 -  
  15.112 -  return EvtChn_Unbind(xpdd, Port);
  15.113 -}
  15.114 -
  15.115 -static NTSTATUS
  15.116 -XenPci_EvtChn_Mask(PVOID context, evtchn_port_t Port)
  15.117 -{
  15.118 -  WDFDEVICE device = context;
  15.119 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.120 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.121 -  
  15.122 -  return EvtChn_Mask(xpdd, Port);
  15.123 -}
  15.124 -
  15.125 -static NTSTATUS
  15.126 -XenPci_EvtChn_Unmask(PVOID context, evtchn_port_t Port)
  15.127 -{
  15.128 -  WDFDEVICE device = context;
  15.129 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.130 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.131 -  
  15.132 -  return EvtChn_Unmask(xpdd, Port);
  15.133 -}
  15.134 -
  15.135 -static NTSTATUS
  15.136 -XenPci_EvtChn_Notify(PVOID context, evtchn_port_t Port)
  15.137 -{
  15.138 -  WDFDEVICE device = context;
  15.139 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.140 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.141 -  
  15.142 -  return EvtChn_Notify(xpdd, Port);
  15.143 -}
  15.144 -
  15.145 -static BOOLEAN
  15.146 -XenPci_EvtChn_AckEvent(PVOID context, evtchn_port_t port, BOOLEAN *last_interrupt)
  15.147 -{
  15.148 -  WDFDEVICE device = context;
  15.149 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.150 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.151 -  
  15.152 -  return EvtChn_AckEvent(xpdd, port, last_interrupt);
  15.153 -}
  15.154 -
  15.155 -typedef struct {
  15.156 -  PXEN_EVTCHN_SYNC_ROUTINE sync_routine;
  15.157 -  PVOID sync_context;
  15.158 -} sync_context_t;
  15.159 -
  15.160 -static BOOLEAN
  15.161 -XenPci_EvtChn_Sync_Routine(WDFINTERRUPT interrupt, WDFCONTEXT context)
  15.162 -{
  15.163 -  sync_context_t *wdf_sync_context = context;
  15.164 -  UNREFERENCED_PARAMETER(interrupt);
  15.165 -  return wdf_sync_context->sync_routine(wdf_sync_context->sync_context);
  15.166 -}
  15.167 -
  15.168 -static BOOLEAN
  15.169 -XenPci_EvtChn_Sync(PVOID context, PXEN_EVTCHN_SYNC_ROUTINE sync_routine, PVOID sync_context)
  15.170 -{
  15.171 -  WDFDEVICE device = context;
  15.172 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.173 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.174 -  sync_context_t wdf_sync_context;
  15.175 -  
  15.176 -  wdf_sync_context.sync_routine = sync_routine;
  15.177 -  wdf_sync_context.sync_context = sync_context;
  15.178 -  
  15.179 -  return WdfInterruptSynchronize(xpdd->interrupt, XenPci_EvtChn_Sync_Routine, &wdf_sync_context);
  15.180 -}
  15.181 -
  15.182 -static grant_ref_t
  15.183 -XenPci_GntTbl_GrantAccess(PVOID context, uint32_t frame, int readonly, grant_ref_t ref, ULONG tag)
  15.184 -{
  15.185 -  WDFDEVICE device = context;
  15.186 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.187 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.188 -  
  15.189 -  return GntTbl_GrantAccess(xpdd, xppdd->backend_id, frame, readonly, ref, tag);
  15.190 -}
  15.191 -
  15.192 -static BOOLEAN
  15.193 -XenPci_GntTbl_EndAccess(PVOID context, grant_ref_t ref, BOOLEAN keepref, ULONG tag)
  15.194 -{
  15.195 -  WDFDEVICE device = context;
  15.196 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.197 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.198 -  
  15.199 -  return GntTbl_EndAccess(xpdd, ref, keepref, tag);
  15.200 -}
  15.201 -
  15.202 -static VOID
  15.203 -XenPci_GntTbl_PutRef(PVOID context, grant_ref_t ref, ULONG tag)
  15.204 -{
  15.205 -  WDFDEVICE device = context;
  15.206 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.207 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.208 -  
  15.209 -  GntTbl_PutRef(xpdd, ref, tag);
  15.210 -}
  15.211 -
  15.212 -static grant_ref_t
  15.213 -XenPci_GntTbl_GetRef(PVOID context, ULONG tag)
  15.214 -{
  15.215 -  WDFDEVICE device = context;
  15.216 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.217 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.218 -  
  15.219 -  return GntTbl_GetRef(xpdd, tag);
  15.220 -}
  15.221 -
  15.222 -PCHAR
  15.223 -XenPci_XenBus_Read(PVOID context, xenbus_transaction_t xbt, char *path, char **value)
  15.224 -{
  15.225 -  WDFDEVICE device = context;
  15.226 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.227 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.228 -  return XenBus_Read(xpdd, xbt, path, value);
  15.229 -}
  15.230 -
  15.231 -PCHAR
  15.232 -XenPci_XenBus_Write(PVOID context, xenbus_transaction_t xbt, char *path, char *value)
  15.233 -{
  15.234 -  WDFDEVICE device = context;
  15.235 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.236 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.237 -  return XenBus_Write(xpdd, xbt, path, value);
  15.238 -}
  15.239 -
  15.240 -PCHAR
  15.241 -XenPci_XenBus_Printf(PVOID context, xenbus_transaction_t xbt, char *path, char *fmt, ...)
  15.242 -{
  15.243 -  //PXENPCI_PDO_DEVICE_DATA xppdd = Context;
  15.244 -  //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
  15.245 -  //return XenBus_Printf(xpdd, xbt, path, value);
  15.246 -  UNREFERENCED_PARAMETER(context);
  15.247 -  UNREFERENCED_PARAMETER(xbt);
  15.248 -  UNREFERENCED_PARAMETER(path);
  15.249 -  UNREFERENCED_PARAMETER(fmt);
  15.250 -  return NULL;
  15.251 -}
  15.252 -
  15.253 -PCHAR
  15.254 -XenPci_XenBus_StartTransaction(PVOID context, xenbus_transaction_t *xbt)
  15.255 -{
  15.256 -  WDFDEVICE device = context;
  15.257 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.258 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.259 -  return XenBus_StartTransaction(xpdd, xbt);
  15.260 -}
  15.261 -
  15.262 -PCHAR
  15.263 -XenPci_XenBus_EndTransaction(PVOID context, xenbus_transaction_t xbt, int abort, int *retry)
  15.264 -{
  15.265 -  WDFDEVICE device = context;
  15.266 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.267 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.268 -  return XenBus_EndTransaction(xpdd, xbt, abort, retry);
  15.269 -}
  15.270 -
  15.271 -PCHAR
  15.272 -XenPci_XenBus_List(PVOID context, xenbus_transaction_t xbt, char *prefix, char ***contents)
  15.273 -{
  15.274 -  WDFDEVICE device = context;
  15.275 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.276 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.277 -  return XenBus_List(xpdd, xbt, prefix, contents);
  15.278 -}
  15.279 -
  15.280 -PCHAR
  15.281 -XenPci_XenBus_AddWatch(PVOID context, xenbus_transaction_t xbt, char *path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext)
  15.282 -{
  15.283 -  WDFDEVICE device = context;
  15.284 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.285 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.286 -  PCHAR retval;
  15.287 -  
  15.288 -  FUNCTION_ENTER();
  15.289 -  retval = XenBus_AddWatch(xpdd, xbt, path, ServiceRoutine, ServiceContext);
  15.290 -  if (retval == NULL)
  15.291 -  {
  15.292 -    KdPrint((__DRIVER_NAME "     XenPci_XenBus_AddWatch - %s = NULL\n", path));
  15.293 -  }
  15.294 -  else
  15.295 -  {
  15.296 -    KdPrint((__DRIVER_NAME "     XenPci_XenBus_AddWatch - %s = %s\n", path, retval));
  15.297 -  }
  15.298 -  FUNCTION_EXIT();
  15.299 -  return retval;
  15.300 -}
  15.301 -
  15.302 -PCHAR
  15.303 -XenPci_XenBus_RemWatch(PVOID context, xenbus_transaction_t xbt, char *path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext)
  15.304 -{
  15.305 -  WDFDEVICE device = context;
  15.306 -  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  15.307 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  15.308 -  return XenBus_RemWatch(xpdd, xbt, path, ServiceRoutine, ServiceContext);
  15.309 -}
  15.310 -
  15.311  /*
  15.312  Called at PASSIVE_LEVEL
  15.313  Called during restore
  15.314 @@ -527,6 +262,7 @@ XenPci_ChangeFrontendState(WDFDEVICE dev
  15.315    return STATUS_SUCCESS;
  15.316  }
  15.317  
  15.318 +#if 0
  15.319  static NTSTATUS
  15.320  XenPci_ChangeFrontendStateMap(WDFDEVICE device, PXENPCI_STATE_MAP_ELEMENT map)
  15.321  {
  15.322 @@ -611,7 +347,9 @@ struct dummy_sring {
  15.323      RING_IDX rsp_prod, rsp_event;
  15.324      uint8_t  pad[48];
  15.325  };
  15.326 +#endif
  15.327  
  15.328 +#if 0
  15.329  static NTSTATUS
  15.330  XenPci_XenConfigDeviceSpecifyBuffers(WDFDEVICE device, PUCHAR src, PUCHAR dst)
  15.331  {
  15.332 @@ -924,6 +662,7 @@ XenPci_XenConfigDevice(WDFDEVICE device)
  15.333    
  15.334    return status;
  15.335  }
  15.336 +#endif
  15.337  
  15.338  static NTSTATUS
  15.339  XenPciPdo_EvtDeviceWdmIrpPreprocess_START_DEVICE(WDFDEVICE device, PIRP irp)
  15.340 @@ -1116,7 +855,7 @@ XenPciPdo_EvtDeviceD0Entry(WDFDEVICE dev
  15.341      break;  
  15.342    }
  15.343  
  15.344 -  status = XenPci_GetBackendAndAddWatch(device);
  15.345 +  status = XenPci_GetBackendDetails(device);
  15.346    if (!NT_SUCCESS(status))
  15.347    {
  15.348      WdfDeviceSetFailed(device, WdfDeviceFailedNoRestart);
  15.349 @@ -1126,13 +865,16 @@ XenPciPdo_EvtDeviceD0Entry(WDFDEVICE dev
  15.350  
  15.351    if (previous_state == WdfPowerDeviceD3 || previous_state == WdfPowerDeviceD3Final)
  15.352    {
  15.353 +#if 0
  15.354      xppdd->requested_resources_ptr = xppdd->requested_resources_start;
  15.355      xppdd->assigned_resources_start = xppdd->assigned_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
  15.356      XenConfig_InitConfigPage(device);
  15.357      status = XenPci_XenConfigDevice(device);
  15.358 +#endif
  15.359    }
  15.360    else if (previous_state == WdfPowerDevicePrepareForHibernation)
  15.361    {
  15.362 +#if 0
  15.363      PVOID src, dst;
  15.364      
  15.365      ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
  15.366 @@ -1146,6 +888,7 @@ XenPciPdo_EvtDeviceD0Entry(WDFDEVICE dev
  15.367  
  15.368      MmUnmapIoSpace(dst, xppdd->config_page_length);
  15.369      ExFreePoolWithTag(src, XENPCI_POOL_TAG);
  15.370 +#endif
  15.371    }
  15.372  
  15.373    if (!NT_SUCCESS(status))
  15.374 @@ -1213,7 +956,9 @@ XenPciPdo_EvtDeviceD0Exit(WDFDEVICE devi
  15.375    }
  15.376    else
  15.377    {
  15.378 +#if 0
  15.379      status = XenPci_XenShutdownDevice(device);
  15.380 +#endif
  15.381    }
  15.382    
  15.383    /* Remove watch on backend state */
  15.384 @@ -1319,7 +1064,7 @@ XenPci_EvtChildListCreateDevice(WDFCHILD
  15.385    DECLARE_UNICODE_STRING_SIZE(buffer, 512);
  15.386    DECLARE_CONST_UNICODE_STRING(location, L"Xen Bus");
  15.387    PXENPCI_PDO_DEVICE_DATA xppdd;
  15.388 -  PXENPCI_DEVICE_DATA xpdd = GetXpdd(WdfChildListGetDevice(child_list));
  15.389 +  //PXENPCI_DEVICE_DATA xpdd = GetXpdd(WdfChildListGetDevice(child_list));
  15.390    WDF_PDO_EVENT_CALLBACKS pdo_callbacks;
  15.391    WDF_PNPPOWER_EVENT_CALLBACKS child_pnp_power_callbacks;
  15.392    UCHAR pnp_minor_functions[] = { IRP_MN_START_DEVICE };
  15.393 @@ -1406,11 +1151,13 @@ XenPci_EvtChildListCreateDevice(WDFCHILD
  15.394  
  15.395    xppdd->config_page_mdl = AllocateUncachedPage();
  15.396  
  15.397 +#if 0
  15.398    xppdd->device_state.magic = XEN_DEVICE_STATE_MAGIC;
  15.399    xppdd->device_state.length = sizeof(XENPCI_DEVICE_STATE);
  15.400    xppdd->device_state.suspend_resume_state_pdo = SR_STATE_RUNNING;
  15.401    xppdd->device_state.suspend_resume_state_fdo = SR_STATE_RUNNING;
  15.402    xppdd->device_state.pdo_event_channel = xpdd->pdo_event_channel;
  15.403 +#endif
  15.404    WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFilePaging, TRUE);
  15.405    WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileHibernation, TRUE);
  15.406    WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileDump, TRUE);
  15.407 @@ -1453,6 +1200,7 @@ XenPci_EvtChildListCreateDevice(WDFCHILD
  15.408    return status;
  15.409  }
  15.410  
  15.411 +#if 0
  15.412  static __forceinline VOID
  15.413  XenPci_Pdo_ChangeSuspendState(WDFDEVICE device, ULONG new_state)
  15.414  {
  15.415 @@ -1556,7 +1304,7 @@ XenPci_Pdo_Resume(WDFDEVICE device)
  15.416  
  15.417    if (xppdd->restart_on_resume)
  15.418    {  
  15.419 -    status = XenPci_GetBackendAndAddWatch(device);
  15.420 +    status = XenPci_GetBackendDetails(device);
  15.421    
  15.422      if (XenPci_ChangeFrontendState(device, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
  15.423      {
  15.424 @@ -1595,3 +1343,4 @@ XenPci_Pdo_Resume(WDFDEVICE device)
  15.425  
  15.426    return STATUS_SUCCESS;
  15.427  }
  15.428 +#endif
  15.429 \ No newline at end of file
    16.1 --- a/xenvbd/sources	Fri Dec 14 21:44:03 2012 +1100
    16.2 +++ b/xenvbd/sources	Sun Jan 06 14:08:22 2013 +1100
    16.3 @@ -3,6 +3,11 @@
    16.4  !UNDEF KMDF_VERSION_MAJOR
    16.5  TARGETNAME=xenvbd
    16.6  TARGETTYPE=DRIVER
    16.7 +!IF $(386)
    16.8 +TARGETLIBS=$(TARGETLIBS) ..\xenpci\obj$(BUILD_ALT_DIR)\i386\xenpci.lib
    16.9 +!ELSE
   16.10 +TARGETLIBS=$(TARGETLIBS) ..\xenpci\obj$(BUILD_ALT_DIR)\AMD64\xenpci.lib
   16.11 +!ENDIF
   16.12  !IF "$(DDK_TARGET_OS)" == "Win2K" || "$(DDK_TARGET_OS)" == "WinXP" || "$(DDK_TARGET_OS)" == "WinNET"
   16.13  TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\scsiport.lib
   16.14  C_DEFINES=$(C_DEFINES) -D_GPLPV_SCSIPORT
    17.1 --- a/xenvbd/xenvbd_storport.c	Fri Dec 14 21:44:03 2012 +1100
    17.2 +++ b/xenvbd/xenvbd_storport.c	Sun Jan 06 14:08:22 2013 +1100
    17.3 @@ -28,9 +28,17 @@ Foundation, Inc., 51 Franklin Street, Fi
    17.4    #define LongLongToPtr(x) UlongToPtr(x)
    17.5  #endif
    17.6  
    17.7 +#if defined(__x86_64__)
    17.8 +  #define ABI_PROTOCOL "x86_64-abi"
    17.9 +#else
   17.10 +  #define ABI_PROTOCOL "x86_32-abi"
   17.11 +#endif
   17.12 +
   17.13  /* Not really necessary but keeps PREfast happy */
   17.14  DRIVER_INITIALIZE DriverEntry;
   17.15 -static BOOLEAN XenVbd_HandleEvent(PVOID DeviceExtension);
   17.16 +static VOID XenVbd_HandleEventDpc(PSTOR_DPC dpc, PVOID DeviceExtension, PVOID arg1, PVOID arg2);
   17.17 +static VOID XenVbd_HandleEventDIRQL(PVOID DeviceExtension);
   17.18 +static VOID XenVbd_ProcessSrbList(PXENVBD_DEVICE_DATA xvdd);
   17.19  
   17.20  static BOOLEAN dump_mode = FALSE;
   17.21  #define DUMP_MODE_ERROR_LIMIT 64
   17.22 @@ -77,40 +85,19 @@ put_shadow_on_freelist(PXENVBD_DEVICE_DA
   17.23  }
   17.24  
   17.25  static blkif_response_t *
   17.26 -XenVbd_GetResponse(PXENVBD_DEVICE_DATA xvdd, int i)
   17.27 -{
   17.28 -  blkif_other_response_t *rep;
   17.29 -  if (!xvdd->use_other)
   17.30 -    return RING_GET_RESPONSE(&xvdd->ring, i);
   17.31 -  rep = RING_GET_RESPONSE(&xvdd->other_ring, i);
   17.32 -  xvdd->tmp_rep.id = rep->id;
   17.33 -  xvdd->tmp_rep.operation = rep->operation;
   17.34 -  xvdd->tmp_rep.status = rep->status;
   17.35 -  return &xvdd->tmp_rep;
   17.36 +XenVbd_GetResponse(PXENVBD_DEVICE_DATA xvdd, int i) {
   17.37 +  return RING_GET_RESPONSE(&xvdd->ring, i);
   17.38  }
   17.39  
   17.40  static VOID
   17.41 -XenVbd_PutRequest(PXENVBD_DEVICE_DATA xvdd, blkif_request_t *req)
   17.42 -{
   17.43 -  blkif_other_request_t *other_req;
   17.44 -
   17.45 -  if (!xvdd->use_other)
   17.46 -  {
   17.47 -    *RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt) = *req;
   17.48 -  }
   17.49 -  else
   17.50 -  {  
   17.51 -    other_req = RING_GET_REQUEST(&xvdd->other_ring, xvdd->ring.req_prod_pvt);
   17.52 -    other_req->operation = req->operation;
   17.53 -    other_req->nr_segments = req->nr_segments;
   17.54 -    other_req->handle = req->handle;
   17.55 -    other_req->id = req->id;
   17.56 -    other_req->sector_number = req->sector_number;
   17.57 -    memcpy(other_req->seg, req->seg, sizeof(struct blkif_request_segment) * req->nr_segments);
   17.58 -  }
   17.59 +XenVbd_PutRequest(PXENVBD_DEVICE_DATA xvdd, blkif_request_t *req) {
   17.60 +  //FUNCTION_ENTER();
   17.61 +  *RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt) = *req;
   17.62    xvdd->ring.req_prod_pvt++;
   17.63 +  //FUNCTION_EXIT();
   17.64  }
   17.65  
   17.66 +#if 0
   17.67  static ULONG
   17.68  XenVbd_InitConfig(PXENVBD_DEVICE_DATA xvdd)
   17.69  {
   17.70 @@ -181,7 +168,7 @@ XenVbd_InitConfig(PXENVBD_DEVICE_DATA xv
   17.71    status = xvdd->vectors.XenPci_XenConfigDevice(xvdd->vectors.context);
   17.72    if (!NT_SUCCESS(status))
   17.73    {
   17.74 -    xvdd->inactive = TRUE;
   17.75 +    xvdd->vbd_status = VBD_STATUS_INACTIVE;
   17.76      KdPrint(("Failed to complete device configuration (%08x)\n", status));
   17.77      FUNCTION_EXIT();
   17.78      return SP_RETURN_BAD_CONFIG;
   17.79 @@ -198,8 +185,6 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
   17.80    USHORT type;
   17.81    PCHAR setting, value, value2;
   17.82    ULONG qemu_protocol_version = 0;
   17.83 -  BOOLEAN qemu_hide_filter = FALSE;
   17.84 -  ULONG qemu_hide_flags_value = 0;
   17.85  
   17.86    FUNCTION_ENTER();
   17.87    
   17.88 @@ -207,7 +192,7 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
   17.89    xvdd->sring = NULL;
   17.90    xvdd->event_channel = 0;
   17.91    
   17.92 -  xvdd->inactive = TRUE;  
   17.93 +  //xvdd->inactive = TRUE;  
   17.94    
   17.95    ptr = xvdd->device_base;
   17.96    while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
   17.97 @@ -248,11 +233,6 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
   17.98          /* cheat here - save the state of the ring in the topmost bits of the event-channel */
   17.99          xvdd->event_channel_ptr = (ULONG *)(((PCHAR)ptr) - sizeof(ULONG));
  17.100          xvdd->event_channel = PtrToUlong(value) & 0x3FFFFFFF;
  17.101 -        if (PtrToUlong(value) & 0x80000000)
  17.102 -        {
  17.103 -          xvdd->cached_use_other = (BOOLEAN)!!(PtrToUlong(value) & 0x40000000);
  17.104 -          KdPrint((__DRIVER_NAME "     cached_use_other = %d\n", xvdd->cached_use_other));
  17.105 -        }
  17.106        }
  17.107        break;
  17.108      case XEN_INIT_TYPE_READ_STRING_BACK:
  17.109 @@ -361,6 +341,7 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
  17.110    FUNCTION_EXIT();
  17.111    return SP_RETURN_FOUND;
  17.112  }
  17.113 +#endif
  17.114  
  17.115  static __inline ULONG
  17.116  decode_cdb_length(PSCSI_REQUEST_BLOCK srb)
  17.117 @@ -421,26 +402,22 @@ decode_cdb_is_read(PSCSI_REQUEST_BLOCK s
  17.118  }
  17.119  
  17.120  static VOID
  17.121 -XenVbd_PutSrbOnList(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
  17.122 -{
  17.123 +XenVbd_PutSrbOnList(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb) {
  17.124    srb_list_entry_t *srb_entry = srb->SrbExtension;
  17.125    srb_entry->srb = srb;
  17.126 -  if (srb->Function == SRB_FUNCTION_EXECUTE_SCSI)
  17.127 -  {
  17.128 -    srb_entry->outstanding_requests = 0;
  17.129 -    srb_entry->length = srb->DataTransferLength;
  17.130 -    srb_entry->offset = 0;
  17.131 -    srb_entry->error = FALSE;
  17.132 -  }
  17.133 +  srb_entry->outstanding_requests = 0;
  17.134 +  srb_entry->length = srb->DataTransferLength;
  17.135 +  srb_entry->offset = 0;
  17.136 +  srb_entry->error = FALSE;
  17.137    InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
  17.138  }
  17.139  
  17.140  /* called with StartIoLock held */
  17.141 -static VOID
  17.142 -XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVICE_DATA xvdd)
  17.143 +/* returns TRUE if something was put on the ring and notify might be required */
  17.144 +static BOOLEAN
  17.145 +XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
  17.146  {
  17.147 -  PSCSI_REQUEST_BLOCK srb;
  17.148 -  srb_list_entry_t *srb_entry;
  17.149 +  srb_list_entry_t *srb_entry = srb->SrbExtension;
  17.150    /* sector_number and block_count are the adjusted-to-512-byte-sector values */
  17.151    ULONGLONG sector_number;
  17.152    ULONG block_count;
  17.153 @@ -448,208 +425,316 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
  17.154    ULONG remaining, offset, length;
  17.155    grant_ref_t gref;
  17.156    PUCHAR ptr;
  17.157 -  int notify;
  17.158    int i;
  17.159    PVOID system_address;
  17.160 -  BOOLEAN failed;
  17.161  
  17.162    //if (dump_mode) FUNCTION_ENTER();
  17.163  
  17.164 -  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)
  17.165 -  {
  17.166 -    srb = srb_entry->srb;
  17.167 -    NT_ASSERT(srb);
  17.168 -    if (srb->Function != SRB_FUNCTION_EXECUTE_SCSI) {
  17.169 -      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_%02x retrieved from ring\n", srb->Function));
  17.170 -      if (xvdd->shadow_free != SHADOW_ENTRIES) {
  17.171 -        KdPrint((__DRIVER_NAME "     busy\n"));
  17.172 -        /* put it back at the end of the list just in case something is queued that needs to be processed */
  17.173 -        InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
  17.174 -        break; /* stall the queue until it's all empty */
  17.175 -      }
  17.176 -      else
  17.177 -      {
  17.178 -        KdPrint((__DRIVER_NAME "     completing\n"));
  17.179 -        srb->SrbStatus = SRB_STATUS_SUCCESS;
  17.180 -        StorPortNotification(RequestComplete, xvdd, srb);
  17.181 -        continue;
  17.182 -      }
  17.183 -    }
  17.184 -
  17.185 -    if (!dump_mode) {
  17.186 -      if (StorPortGetSystemAddress(xvdd, srb, &system_address) != STOR_STATUS_SUCCESS) {
  17.187 -        KdPrint((__DRIVER_NAME "     Failed to map DataBuffer\n"));
  17.188 -        srb->SrbStatus = SRB_STATUS_BUSY;
  17.189 -        StorPortNotification(RequestComplete, xvdd, srb);
  17.190 -        continue;
  17.191 -      }
  17.192 -      system_address = (PUCHAR)system_address + srb_entry->offset;
  17.193 -    } else {
  17.194 -      //KdPrint((__DRIVER_NAME "     DataBuffer = %p\n", srb->DataBuffer));
  17.195 -      system_address = (PUCHAR)srb->DataBuffer + srb_entry->offset;
  17.196 -    }
  17.197 -    block_count = decode_cdb_length(srb);
  17.198 -    sector_number = decode_cdb_sector(srb);
  17.199 -    block_count *= xvdd->bytes_per_sector / 512;
  17.200 -    sector_number *= xvdd->bytes_per_sector / 512;
  17.201 +  //FUNCTION_MSG("aligned_buffer_in_use = %d\n", xvdd->aligned_buffer_in_use);
  17.202 +  //FUNCTION_MSG("shadow_free = %d\n", xvdd->shadow_free);
  17.203 +  
  17.204 +  NT_ASSERT(srb);
  17.205  
  17.206 -    NT_ASSERT(block_count * 512 == srb->DataTransferLength);
  17.207 -    
  17.208 -    sector_number += srb_entry->offset / 512;
  17.209 -    block_count -= srb_entry->offset / 512;
  17.210 -
  17.211 -    NT_ASSERT(block_count > 0);
  17.212 +  if (!dump_mode) {
  17.213 +    if (StorPortGetSystemAddress(xvdd, srb, &system_address) != STOR_STATUS_SUCCESS) {
  17.214 +      FUNCTION_MSG("Failed to map DataBuffer\n");
  17.215 +      InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
  17.216 +      return FALSE;
  17.217 +    }
  17.218 +    system_address = (PUCHAR)system_address + srb_entry->offset;
  17.219 +  } else {
  17.220 +    //KdPrint((__DRIVER_NAME "     DataBuffer = %p\n", srb->DataBuffer));
  17.221 +    system_address = (PUCHAR)srb->DataBuffer + srb_entry->offset;
  17.222 +  }
  17.223 +  block_count = decode_cdb_length(srb);
  17.224 +  sector_number = decode_cdb_sector(srb);
  17.225 +  block_count *= xvdd->bytes_per_sector / 512;
  17.226 +  sector_number *= xvdd->bytes_per_sector / 512;
  17.227  
  17.228 -    /* look for pending writes that overlap this one */
  17.229 -    /* we get warnings from drbd if we don't */
  17.230 -    if (srb_entry->offset == 0) {
  17.231 -      for (i = 0; i < MAX_SHADOW_ENTRIES; i++) {
  17.232 -        PSCSI_REQUEST_BLOCK srb2;
  17.233 -        ULONGLONG sector_number2;
  17.234 -        ULONG block_count2;
  17.235 -        
  17.236 -        srb2 = xvdd->shadows[i].srb;
  17.237 -        if (!srb2)
  17.238 -          continue;
  17.239 -        if (decode_cdb_is_read(srb2))
  17.240 -          continue;
  17.241 -        block_count2 = decode_cdb_length(srb2);;
  17.242 -        block_count2 *= xvdd->bytes_per_sector / 512;
  17.243 -        sector_number2 = decode_cdb_sector(srb2);
  17.244 -        sector_number2 *= xvdd->bytes_per_sector / 512;
  17.245 -        
  17.246 -        if (sector_number < sector_number2 && sector_number + block_count <= sector_number2)
  17.247 -          continue;
  17.248 -        if (sector_number2 < sector_number && sector_number2 + block_count2 <= sector_number)
  17.249 -          continue;
  17.250 +  NT_ASSERT(block_count * 512 == srb->DataTransferLength);
  17.251 +  
  17.252 +  sector_number += srb_entry->offset / 512;
  17.253 +  block_count -= srb_entry->offset / 512;
  17.254  
  17.255 -        KdPrint((__DRIVER_NAME "     Concurrent outstanding write detected (%I64d, %d) (%I64d, %d)\n",
  17.256 -          sector_number, block_count, sector_number2, block_count2));
  17.257 -        /* put the srb back at the start of the queue */
  17.258 -        InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
  17.259 -        break; /* stall the queue */
  17.260 -      }
  17.261 -      if (i != MAX_SHADOW_ENTRIES) {
  17.262 -        break; /* stall the queue but submit any outstanding requests */
  17.263 -      }
  17.264 +  NT_ASSERT(block_count > 0);
  17.265 +
  17.266 +  /* look for pending writes that overlap this one */
  17.267 +  /* we get warnings from drbd if we don't */
  17.268 +  if (srb_entry->offset == 0) {
  17.269 +    for (i = 0; i < MAX_SHADOW_ENTRIES; i++) {
  17.270 +      PSCSI_REQUEST_BLOCK srb2;
  17.271 +      ULONGLONG sector_number2;
  17.272 +      ULONG block_count2;
  17.273 +      
  17.274 +      srb2 = xvdd->shadows[i].srb;
  17.275 +      if (!srb2)
  17.276 +        continue;
  17.277 +      if (decode_cdb_is_read(srb2))
  17.278 +        continue;
  17.279 +      block_count2 = decode_cdb_length(srb2);;
  17.280 +      block_count2 *= xvdd->bytes_per_sector / 512;
  17.281 +      sector_number2 = decode_cdb_sector(srb2);
  17.282 +      sector_number2 *= xvdd->bytes_per_sector / 512;
  17.283 +      
  17.284 +      if (sector_number < sector_number2 && sector_number + block_count <= sector_number2)
  17.285 +        continue;
  17.286 +      if (sector_number2 < sector_number && sector_number2 + block_count2 <= sector_number)
  17.287 +        continue;
  17.288 +
  17.289 +      KdPrint((__DRIVER_NAME "     Concurrent outstanding write detected (%I64d, %d) (%I64d, %d)\n",
  17.290 +        sector_number, block_count, sector_number2, block_count2));
  17.291 +      break;
  17.292      }
  17.293 -    
  17.294 -    shadow = get_shadow_from_freelist(xvdd);
  17.295 -    if (!shadow) {
  17.296 +    if (i != MAX_SHADOW_ENTRIES) {
  17.297        /* put the srb back at the start of the queue */
  17.298        InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
  17.299 -      break; /* stall the queue but submit any outstanding requests */
  17.300 +      return FALSE;
  17.301      }
  17.302 -    NT_ASSERT(!shadow->aligned_buffer_in_use);
  17.303 -    NT_ASSERT(!shadow->srb);
  17.304 -    shadow->req.sector_number = sector_number;
  17.305 -    shadow->req.handle = 0;
  17.306 -    shadow->req.operation = decode_cdb_is_read(srb)?BLKIF_OP_READ:BLKIF_OP_WRITE;
  17.307 -    shadow->req.nr_segments = 0;
  17.308 -    shadow->srb = srb;
  17.309 -    shadow->length = 0;
  17.310 -    shadow->system_address = system_address;
  17.311 -    shadow->reset = FALSE;
  17.312 +  }
  17.313 +  
  17.314 +  shadow = get_shadow_from_freelist(xvdd);
  17.315 +  if (!shadow) {
  17.316 +    /* put the srb back at the start of the queue */
  17.317 +    InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
  17.318 +    return FALSE;
  17.319 +  }
  17.320 +  NT_ASSERT(!shadow->aligned_buffer_in_use);
  17.321 +  NT_ASSERT(!shadow->srb);
  17.322 +  shadow->req.sector_number = sector_number;
  17.323 +  shadow->req.handle = 0;
  17.324 +  shadow->req.operation = decode_cdb_is_read(srb)?BLKIF_OP_READ:BLKIF_OP_WRITE;
  17.325 +  shadow->req.nr_segments = 0;
  17.326 +  shadow->srb = srb;
  17.327 +  shadow->length = 0;
  17.328 +  shadow->system_address = system_address;
  17.329 +  shadow->reset = FALSE;
  17.330  
  17.331 -    if (!dump_mode) {
  17.332 -      if ((ULONG_PTR)shadow->system_address & 511) {
  17.333 -        xvdd->aligned_buffer_in_use = TRUE;
  17.334 -        /* limit to aligned_buffer_size */
  17.335 -        block_count = min(block_count, xvdd->aligned_buffer_size / 512);
  17.336 -        ptr = (PUCHAR)xvdd->aligned_buffer;
  17.337 -        if (!decode_cdb_is_read(srb))
  17.338 -          memcpy(ptr, shadow->system_address, block_count * 512);
  17.339 -        shadow->aligned_buffer_in_use = TRUE;
  17.340 -      } else {
  17.341 -        ptr = (PUCHAR)shadow->system_address;
  17.342 -        shadow->aligned_buffer_in_use = FALSE;
  17.343 -      }
  17.344 +  if (!dump_mode) {
  17.345 +    if ((ULONG_PTR)shadow->system_address & 511) {
  17.346 +      xvdd->aligned_buffer_in_use = TRUE;
  17.347 +      /* limit to aligned_buffer_size */
  17.348 +      block_count = min(block_count, xvdd->aligned_buffer_size / 512);
  17.349 +      ptr = (PUCHAR)xvdd->aligned_buffer;
  17.350 +      if (!decode_cdb_is_read(srb))
  17.351 +        memcpy(ptr, shadow->system_address, block_count * 512);
  17.352 +      shadow->aligned_buffer_in_use = TRUE;
  17.353      } else {
  17.354 -      NT_ASSERT(!((ULONG_PTR)shadow->system_address & 511));
  17.355 -      ptr = shadow->system_address;
  17.356 +      ptr = (PUCHAR)shadow->system_address;
  17.357        shadow->aligned_buffer_in_use = FALSE;
  17.358      }
  17.359 -
  17.360 -    //KdPrint((__DRIVER_NAME "     sector_number = %d, block_count = %d\n", (ULONG)sector_number, block_count));
  17.361 -    //KdPrint((__DRIVER_NAME "     DataBuffer   = %p\n", srb->DataBuffer));
  17.362 -    //KdPrint((__DRIVER_NAME "     system_address   = %p\n", shadow->system_address));
  17.363 -    //KdPrint((__DRIVER_NAME "     offset   = %d, length = %d\n", srb_entry->offset, srb_entry->length));
  17.364 -    //KdPrint((__DRIVER_NAME "     ptr   = %p\n", ptr));
  17.365 +  } else {
  17.366 +    NT_ASSERT(!((ULONG_PTR)shadow->system_address & 511));
  17.367 +    ptr = shadow->system_address;
  17.368 +    shadow->aligned_buffer_in_use = FALSE;
  17.369 +  }
  17.370  
  17.371 -    //KdPrint((__DRIVER_NAME "     handle = %d\n", shadow->req.handle));
  17.372 -    //KdPrint((__DRIVER_NAME "     operation = %d\n", shadow->req.operation));
  17.373 -    
  17.374 -    remaining = block_count * 512;
  17.375 -    failed = FALSE;
  17.376 -    while (remaining > 0 && shadow->req.nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST) {
  17.377 -      PHYSICAL_ADDRESS physical_address;
  17.378 +  //KdPrint((__DRIVER_NAME "     sector_number = %d, block_count = %d\n", (ULONG)sector_number, block_count));
  17.379 +  //KdPrint((__DRIVER_NAME "     DataBuffer   = %p\n", srb->DataBuffer));
  17.380 +  //KdPrint((__DRIVER_NAME "     system_address   = %p\n", shadow->system_address));
  17.381 +  //KdPrint((__DRIVER_NAME "     offset   = %d, length = %d\n", srb_entry->offset, srb_entry->length));
  17.382 +  //KdPrint((__DRIVER_NAME "     ptr   = %p\n", ptr));
  17.383  
  17.384 -      if (!dump_mode) {
  17.385 -        physical_address = MmGetPhysicalAddress(ptr);
  17.386 -      } else {
  17.387 -        ULONG length;       
  17.388 -        physical_address = StorPortGetPhysicalAddress(xvdd, srb, ptr, &length);
  17.389 +  //KdPrint((__DRIVER_NAME "     handle = %d\n", shadow->req.handle));
  17.390 +  //KdPrint((__DRIVER_NAME "     operation = %d\n", shadow->req.operation));
  17.391 +  
  17.392 +  remaining = block_count * 512;
  17.393 +  while (remaining > 0 && shadow->req.nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST) {
  17.394 +    PHYSICAL_ADDRESS physical_address;
  17.395 +
  17.396 +    if (!dump_mode) {
  17.397 +      physical_address = MmGetPhysicalAddress(ptr);
  17.398 +    } else {
  17.399 +      ULONG length;       
  17.400 +      physical_address = StorPortGetPhysicalAddress(xvdd, srb, ptr, &length);
  17.401 +    }
  17.402 +    gref = XnGrantAccess(xvdd->handle,
  17.403 +           (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, xvdd->grant_tag);
  17.404 +    if (gref == INVALID_GRANT_REF) {
  17.405 +      ULONG i;
  17.406 +      for (i = 0; i < shadow->req.nr_segments; i++) {
  17.407 +        XnEndAccess(xvdd->handle,
  17.408 +          shadow->req.seg[i].gref, FALSE, xvdd->grant_tag);
  17.409        }
  17.410 -      gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context,
  17.411 -             (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, xvdd->grant_tag);
  17.412 -      if (gref == INVALID_GRANT_REF) {
  17.413 -        ULONG i;
  17.414 -        for (i = 0; i < shadow->req.nr_segments; i++) {
  17.415 -          xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
  17.416 -            shadow->req.seg[i].gref, FALSE, xvdd->grant_tag);
  17.417 -        }
  17.418 -        if (shadow->aligned_buffer_in_use) {
  17.419 -          shadow->aligned_buffer_in_use = FALSE;
  17.420 -          xvdd->aligned_buffer_in_use = FALSE;
  17.421 -        }
  17.422 -        /* put the srb back at the start of the queue */
  17.423 -        InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
  17.424 -        put_shadow_on_freelist(xvdd, shadow);
  17.425 -        KdPrint((__DRIVER_NAME "     Out of gref's. Deferring\n"));
  17.426 -        failed = TRUE;
  17.427 -        /* what if there are no requests currently in progress to kick the queue again?? */
  17.428 -        break; /* stall the queue but submit any outstanding requests */
  17.429 +      if (shadow->aligned_buffer_in_use) {
  17.430 +        shadow->aligned_buffer_in_use = FALSE;
  17.431 +        xvdd->aligned_buffer_in_use = FALSE;
  17.432        }
  17.433 -      offset = physical_address.LowPart & (PAGE_SIZE - 1);
  17.434 -      length = min(PAGE_SIZE - offset, remaining);
  17.435 -      NT_ASSERT((offset & 511) == 0);
  17.436 -      NT_ASSERT((length & 511) == 0);
  17.437 -      NT_ASSERT(offset + length <= PAGE_SIZE);
  17.438 -      shadow->req.seg[shadow->req.nr_segments].gref = gref;
  17.439 -      shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset / 512);
  17.440 -      shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) / 512) - 1);
  17.441 -      remaining -= length;
  17.442 -      ptr += length;
  17.443 -      shadow->length += length;
  17.444 -      shadow->req.nr_segments++;
  17.445 +      /* put the srb back at the start of the queue */
  17.446 +      InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
  17.447 +      put_shadow_on_freelist(xvdd, shadow);
  17.448 +      KdPrint((__DRIVER_NAME "     Out of gref's. Deferring\n"));
  17.449 +      /* TODO: what if there are no requests currently in progress to kick the queue again?? timer? */
  17.450 +      return FALSE;
  17.451      }
  17.452 -    if (failed)
  17.453 -      break;
  17.454 -    srb_entry->offset += shadow->length;
  17.455 -    srb_entry->outstanding_requests++;
  17.456 -    if (srb_entry->offset < srb_entry->length) {
  17.457 -      if (dump_mode) KdPrint((__DRIVER_NAME "     inserting back into list\n"));
  17.458 -      /* put the srb back at the start of the queue to continue on the next request */
  17.459 -      InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
  17.460 -    }
  17.461 -    XenVbd_PutRequest(xvdd, &shadow->req);
  17.462 +    offset = physical_address.LowPart & (PAGE_SIZE - 1);
  17.463 +    length = min(PAGE_SIZE - offset, remaining);
  17.464 +    NT_ASSERT((offset & 511) == 0);
  17.465 +    NT_ASSERT((length & 511) == 0);
  17.466 +    NT_ASSERT(offset + length <= PAGE_SIZE);
  17.467 +    shadow->req.seg[shadow->req.nr_segments].gref = gref;
  17.468 +    shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset / 512);
  17.469 +    shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) / 512) - 1);
  17.470 +    remaining -= length;
  17.471 +    ptr += length;
  17.472 +    shadow->length += length;
  17.473 +    shadow->req.nr_segments++;
  17.474    }
  17.475 -  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
  17.476 -  if (notify) {
  17.477 -    xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
  17.478 +  srb_entry->offset += shadow->length;
  17.479 +  srb_entry->outstanding_requests++;
  17.480 +  if (srb_entry->offset < srb_entry->length) {
  17.481 +    if (dump_mode) KdPrint((__DRIVER_NAME "     inserting back into list\n"));
  17.482 +    /* put the srb back at the start of the queue to continue on the next request */
  17.483 +    InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
  17.484    }
  17.485 +  XenVbd_PutRequest(xvdd, &shadow->req);
  17.486 +  return TRUE;
  17.487 +  //FUNCTION_EXIT();
  17.488  }
  17.489  
  17.490 +static VOID
  17.491 +XenVbd_BackendStateCallback(PVOID context, ULONG state) {
  17.492 +  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)context;
  17.493 +  PCHAR mode;
  17.494 +  PCHAR device_type;
  17.495 +  PFN_NUMBER pfn;
  17.496 +  ULONG status;
  17.497 +  BOOLEAN active = FALSE;
  17.498 +  BOOLEAN qemu_hide_filter = FALSE;
  17.499 +  ULONG qemu_hide_flags_value = 0;
  17.500 +  STOR_LOCK_HANDLE lock_handle;
  17.501 + 
  17.502 +  FUNCTION_ENTER();
  17.503 +  if (state == xvdd->backend_state) {
  17.504 +    FUNCTION_MSG("same state %d\n", state);
  17.505 +    FUNCTION_EXIT();
  17.506 +  }
  17.507 +  FUNCTION_MSG("XenbusState = %d -> %d\n", xvdd->backend_state, state);
  17.508 +  
  17.509 +  switch (state) {
  17.510 +  case XenbusStateUnknown:
  17.511 +    break;
  17.512 +
  17.513 +  case XenbusStateInitialising:
  17.514 +  case XenbusStateInitWait:
  17.515 +  case XenbusStateInitialised:
  17.516 +    FUNCTION_MSG("XenbusState Initialising/InitWait/Initialised\n");
  17.517 +    if (xvdd->frontend_state != XenbusStateInitialised) {
  17.518 +      xvdd->frontend_state = XenbusStateInitialised;
  17.519 +      xvdd->event_channel = XnAllocateEvent(xvdd->handle);
  17.520 +      if (!xvdd->event_channel) {
  17.521 +        // !!PANIC!!
  17.522 +      }
  17.523 +      FUNCTION_MSG("event_channel = %d\n", xvdd->event_channel);
  17.524 +      status = XnBindEvent(xvdd->handle, xvdd->event_channel, XenVbd_HandleEventDIRQL, xvdd);
  17.525 +      status = XnWriteInt32(xvdd->handle, XN_BASE_FRONTEND, "event-channel", xvdd->event_channel);
  17.526 +      xvdd->sring = (blkif_sring_t *)ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENVBD_POOL_TAG);
  17.527 +      if (!xvdd->sring) {
  17.528 +        // !!PANIC!!
  17.529 +      }
  17.530 +      FUNCTION_MSG("sring = %p\n", xvdd->sring);
  17.531 +      SHARED_RING_INIT(xvdd->sring);
  17.532 +      FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE);
  17.533 +      pfn = MmGetPhysicalAddress(xvdd->sring).QuadPart >> PAGE_SHIFT;
  17.534 +      FUNCTION_MSG("sring pfn = %d\n", (ULONG)pfn);
  17.535 +      xvdd->sring_gref = XnGrantAccess(xvdd->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, xvdd->grant_tag);
  17.536 +      FUNCTION_MSG("sring_gref = %d\n", xvdd->sring_gref);
  17.537 +      status = XnWriteInt32(xvdd->handle, XN_BASE_FRONTEND, "ring-ref", xvdd->sring_gref);
  17.538 +      status = XnWriteString(xvdd->handle, XN_BASE_FRONTEND, "protocol", ABI_PROTOCOL);
  17.539 +      status = XnWriteInt32(xvdd->handle, XN_BASE_FRONTEND, "state", XenbusStateInitialised);
  17.540 +    }
  17.541 +    break;
  17.542 +
  17.543 +  case XenbusStateConnected:
  17.544 +    FUNCTION_MSG("XenbusState Connected\n");
  17.545 +    if (xvdd->frontend_state != XenbusStateConnected) {
  17.546 +      xvdd->frontend_state = XenbusStateConnected;
  17.547 +      status = XnReadInt64(xvdd->handle, XN_BASE_BACKEND, "sectors", &xvdd->total_sectors);
  17.548 +      status = XnReadInt32(xvdd->handle, XN_BASE_BACKEND, "sector-size", &xvdd->hw_bytes_per_sector);
  17.549 +      if (xvdd->device_type == XENVBD_DEVICETYPE_CDROM) {
  17.550 +        /* CD/DVD drives must have bytes_per_sector = 2048. */
  17.551 +        xvdd->bytes_per_sector = 2048;
  17.552 +        xvdd->hw_bytes_per_sector = 2048;
  17.553 +      } else {
  17.554 +        xvdd->bytes_per_sector = 512;
  17.555 +      }
  17.556 +      /* for some reason total_sectors is measured in 512 byte sectors always, so correct this to be in bytes_per_sectors */
  17.557 +      xvdd->total_sectors /= xvdd->bytes_per_sector / 512;
  17.558 +      status = XnReadInt32(xvdd->handle, XN_BASE_BACKEND, "feature-barrier", &xvdd->feature_barrier);
  17.559 +      status = XnReadInt32(xvdd->handle, XN_BASE_BACKEND, "feature-discard", &xvdd->feature_discard);
  17.560 +      status = XnReadInt32(xvdd->handle, XN_BASE_BACKEND, "feature-flush-cache", &xvdd->feature_flush_cache);
  17.561 +      status = XnReadString(xvdd->handle, XN_BASE_BACKEND, "mode", &mode);
  17.562 +      if (strncmp(mode, "r", 1) == 0) {
  17.563 +        FUNCTION_MSG("mode = r\n");
  17.564 +        xvdd->device_mode = XENVBD_DEVICEMODE_READ;
  17.565 +      } else if (strncmp(mode, "w", 1) == 0) {
  17.566 +        FUNCTION_MSG("mode = w\n");    
  17.567 +        xvdd->device_mode = XENVBD_DEVICEMODE_WRITE;
  17.568 +      } else {
  17.569 +        FUNCTION_MSG("mode = unknown\n");
  17.570 +        xvdd->device_mode = XENVBD_DEVICEMODE_UNKNOWN;
  17.571 +      }
  17.572 +      XnFreeMem(xvdd->handle, mode);
  17.573 +
  17.574 +      // read device-type
  17.575 +      status = XnReadString(xvdd->handle, XN_BASE_FRONTEND, "device-type", &device_type);
  17.576 +      if (strcmp(device_type, "disk") == 0) {
  17.577 +        FUNCTION_MSG("device-type = Disk\n");    
  17.578 +        xvdd->device_type = XENVBD_DEVICETYPE_DISK;
  17.579 +      } else if (strcmp(device_type, "cdrom") == 0) {
  17.580 +        FUNCTION_MSG("device-type = CDROM\n");    
  17.581 +        xvdd->device_type = XENVBD_DEVICETYPE_CDROM;
  17.582 +      } else {
  17.583 +        FUNCTION_MSG("device-type = %s (This probably won't work!)\n", device_type);
  17.584 +        xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
  17.585 +      }
  17.586 +      XnFreeMem(xvdd->handle, device_type);
  17.587 +      status = XnWriteInt32(xvdd->handle, XN_BASE_FRONTEND, "state", XenbusStateConnected);
  17.588 +      // check that everything is good
  17.589 +      XnGetValue(xvdd->handle, XN_VALUE_TYPE_QEMU_HIDE_FLAGS, &qemu_hide_flags_value);
  17.590 +      XnGetValue(xvdd->handle, XN_VALUE_TYPE_QEMU_FILTER, &qemu_hide_filter);
  17.591 +
  17.592 +      if (((qemu_hide_flags_value & QEMU_UNPLUG_ALL_IDE_DISKS) && xvdd->device_type != XENVBD_DEVICETYPE_CDROM) || qemu_hide_filter)
  17.593 +        active = TRUE;
  17.594 +
  17.595 +      if (active && (xvdd->device_type == XENVBD_DEVICETYPE_UNKNOWN
  17.596 +          || xvdd->sring == NULL
  17.597 +          || xvdd->event_channel == 0
  17.598 +          || xvdd->total_sectors == 0
  17.599 +          || xvdd->hw_bytes_per_sector == 0)) {
  17.600 +        FUNCTION_MSG("Missing settings\n");
  17.601 +        active = FALSE;
  17.602 +      }
  17.603 +
  17.604 +      if (active)
  17.605 +        xvdd->vbd_status = VBD_STATUS_ACTIVE;
  17.606 +      else
  17.607 +        xvdd->vbd_status = VBD_STATUS_INACTIVE;
  17.608 +      StorPortAcquireSpinLock(xvdd, StartIoLock, NULL, &lock_handle);
  17.609 +      XenVbd_ProcessSrbList(xvdd);
  17.610 +      StorPortReleaseSpinLock(xvdd, &lock_handle);
  17.611 +    }
  17.612 +    break;
  17.613 +
  17.614 +  case XenbusStateClosing:
  17.615 +    break;
  17.616 +
  17.617 +  case XenbusStateClosed:
  17.618 +    break;
  17.619 +  
  17.620 +  default:
  17.621 +    break;
  17.622 +  }
  17.623 +  xvdd->backend_state = state;
  17.624 +  FUNCTION_EXIT();
  17.625 +}
  17.626 +
  17.627 +/* called in non-dump mode */
  17.628  static ULONG
  17.629  XenVbd_VirtualHwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PVOID LowerDevice, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
  17.630  {
  17.631 -//  PACCESS_RANGE AccessRange;
  17.632    PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
  17.633 -  ULONG status;
  17.634 -//  PXENPCI_XEN_DEVICE_DATA XenDeviceData;
  17.635 -  PACCESS_RANGE access_range;
  17.636  
  17.637 -  UNREFERENCED_PARAMETER(HwContext);
  17.638 +  //UNREFERENCED_PARAMETER(HwContext);
  17.639    UNREFERENCED_PARAMETER(BusInformation);
  17.640    UNREFERENCED_PARAMETER(LowerDevice);
  17.641    UNREFERENCED_PARAMETER(ArgumentString);
  17.642 @@ -658,60 +743,18 @@ XenVbd_VirtualHwStorFindAdapter(PVOID De
  17.643    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  17.644    KdPrint((__DRIVER_NAME "     xvdd = %p\n", xvdd));
  17.645  
  17.646 -  RtlZeroMemory(xvdd, sizeof(XENVBD_DEVICE_DATA));
  17.647 -  *Again = FALSE;
  17.648 -
  17.649 -  KdPrint((__DRIVER_NAME "     BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
  17.650 -  KdPrint((__DRIVER_NAME "     BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector));
  17.651 -
  17.652 -  if (!dump_mode)
  17.653 -  {
  17.654 -    KdPrint((__DRIVER_NAME "     NumberOfAccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));    
  17.655 -    if (ConfigInfo->NumberOfAccessRanges != 1 && ConfigInfo->NumberOfAccessRanges != 2)
  17.656 -    {
  17.657 -      return SP_RETURN_BAD_CONFIG;
  17.658 -    }
  17.659 +  if (XnGetVersion() != 1) {
  17.660 +    FUNCTION_MSG("Wrong XnGetVersion\n");
  17.661 +    FUNCTION_EXIT();
  17.662 +    return SP_RETURN_BAD_CONFIG;
  17.663 +  }
  17.664  
  17.665 -    access_range = &((*(ConfigInfo->AccessRanges))[0]);
  17.666 -    KdPrint((__DRIVER_NAME "     RangeStart = %08x, RangeLength = %08x\n",
  17.667 -      access_range->RangeStart.LowPart, access_range->RangeLength));
  17.668 -    xvdd->device_base = StorPortGetDeviceBase(
  17.669 -      DeviceExtension,
  17.670 -      PNPBus, //AdapterInterfaceType,
  17.671 -      ConfigInfo->SystemIoBusNumber,
  17.672 -      access_range->RangeStart,
  17.673 -      access_range->RangeLength,
  17.674 -      !access_range->RangeInMemory);
  17.675 -    if (!xvdd->device_base)
  17.676 -    {
  17.677 -      KdPrint((__DRIVER_NAME "     StorPortGetDeviceBase failed\n"));
  17.678 -      FUNCTION_EXIT(); 
  17.679 -      return SP_RETURN_BAD_CONFIG;
  17.680 -    }
  17.681 -    status = XenVbd_InitConfig(xvdd);
  17.682 -    if (status != SP_RETURN_FOUND)
  17.683 -    {
  17.684 -      /* set inactive here so StartIo is harmless - we still get called with a PNP remove (or similar) */
  17.685 -      xvdd->inactive = TRUE;
  17.686 -      FUNCTION_EXIT();
  17.687 -      return status;
  17.688 -    }
  17.689 -    xvdd->grant_tag = (ULONG)'VBD0';
  17.690 -  }
  17.691 -  else
  17.692 -  {
  17.693 -    xvdd->device_base = ConfigInfo->Reserved;
  17.694 -    xvdd->grant_tag = (ULONG)'DUMP';
  17.695 -  }
  17.696 -  
  17.697 -  xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED;
  17.698 -  status = XenVbd_InitFromConfig(xvdd);
  17.699 -  if (status != SP_RETURN_FOUND)
  17.700 -  {
  17.701 -    /* set inactive here so StartIo is harmless - we still get called with a PNP remove (or similar) */
  17.702 -    xvdd->inactive = TRUE;
  17.703 -    FUNCTION_EXIT();
  17.704 -    return status;
  17.705 +  RtlZeroMemory(xvdd, sizeof(XENVBD_DEVICE_DATA));
  17.706 +  InitializeListHead(&xvdd->srb_list);
  17.707 +  xvdd->pdo = (PDEVICE_OBJECT)HwContext;
  17.708 +  /* this shouldn't race because nothing will be on the srb queue yet */
  17.709 +  if ((xvdd->handle = XnOpenDevice(xvdd->pdo, XenVbd_BackendStateCallback, xvdd)) == NULL) {
  17.710 +    return SP_RETURN_BAD_CONFIG;
  17.711    }
  17.712  
  17.713    xvdd->aligned_buffer_in_use = FALSE;
  17.714 @@ -722,103 +765,119 @@ XenVbd_VirtualHwStorFindAdapter(PVOID De
  17.715  
  17.716    ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
  17.717    ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
  17.718 -  KdPrint((__DRIVER_NAME "     ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength));
  17.719 -  KdPrint((__DRIVER_NAME "     ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks));
  17.720 -  if (!dump_mode)
  17.721 -  {
  17.722 +  FUNCTION_MSG("ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength);
  17.723 +  FUNCTION_MSG("ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks);
  17.724 +  if (!dump_mode) {
  17.725      ConfigInfo->VirtualDevice = TRUE;
  17.726      xvdd->aligned_buffer_size = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
  17.727 -  }
  17.728 -  else
  17.729 -  {
  17.730 +  } else {
  17.731      ConfigInfo->VirtualDevice = FALSE;
  17.732      xvdd->aligned_buffer_size = DUMP_MODE_UNALIGNED_PAGES * PAGE_SIZE;
  17.733    }
  17.734    
  17.735 -  KdPrint((__DRIVER_NAME "     ConfigInfo->VirtualDevice = %d\n", ConfigInfo->VirtualDevice));
  17.736 +  FUNCTION_MSG("ConfigInfo->VirtualDevice = %d\n", ConfigInfo->VirtualDevice);
  17.737    ConfigInfo->ScatterGather = TRUE;
  17.738    ConfigInfo->Master = TRUE;
  17.739    ConfigInfo->CachesData = FALSE;
  17.740    ConfigInfo->MapBuffers = STOR_MAP_ALL_BUFFERS;
  17.741 -  KdPrint((__DRIVER_NAME "     ConfigInfo->NeedPhysicalAddresses = %d\n", ConfigInfo->NeedPhysicalAddresses));
  17.742 +  FUNCTION_MSG("ConfigInfo->NeedPhysicalAddresses = %d\n", ConfigInfo->NeedPhysicalAddresses);
  17.743    ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
  17.744    ConfigInfo->AlignmentMask = 0;
  17.745    ConfigInfo->NumberOfBuses = 1;
  17.746    ConfigInfo->InitiatorBusId[0] = 1;
  17.747    ConfigInfo->MaximumNumberOfLogicalUnits = 1;
  17.748    ConfigInfo->MaximumNumberOfTargets = 2;
  17.749 -  //ConfigInfo->BufferAccessScsiPortControlled = FALSE;
  17.750 -  if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
  17.751 -  {
  17.752 +  if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) {
  17.753      ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
  17.754 -    //ConfigInfo->Dma32BitAddresses = FALSE;
  17.755 -    KdPrint((__DRIVER_NAME "     Dma64BitAddresses supported\n"));
  17.756 +    FUNCTION_MSG("Dma64BitAddresses supported\n");
  17.757 +  } else {
  17.758 +    FUNCTION_MSG("Dma64BitAddresses not supported\n");
  17.759    }
  17.760 -  else
  17.761 -  {
  17.762 -    //ConfigInfo->Dma32BitAddresses = TRUE;
  17.763 -    KdPrint((__DRIVER_NAME "     Dma64BitAddresses not supported\n"));
  17.764 -  }
  17.765 +  *Again = FALSE;
  17.766  
  17.767    FUNCTION_EXIT();
  17.768  
  17.769    return SP_RETURN_FOUND;
  17.770  }
  17.771  
  17.772 +/* called in dump mode */
  17.773  static ULONG
  17.774  XenVbd_HwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
  17.775  {
  17.776 -  ULONG status;
  17.777 +  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
  17.778 +
  17.779 +  UNREFERENCED_PARAMETER(HwContext);
  17.780 +  UNREFERENCED_PARAMETER(BusInformation);
  17.781 +  UNREFERENCED_PARAMETER(ArgumentString);
  17.782    
  17.783    FUNCTION_ENTER();
  17.784 -  status = XenVbd_VirtualHwStorFindAdapter(DeviceExtension, HwContext, BusInformation, NULL, ArgumentString, ConfigInfo, Again);
  17.785 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  17.786 +  KdPrint((__DRIVER_NAME "     xvdd = %p\n", xvdd));
  17.787 +
  17.788 +  memcpy(xvdd, ConfigInfo->Reserved, FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data));
  17.789 +  xvdd->aligned_buffer_in_use = FALSE;
  17.790 +  /* align the buffer to PAGE_SIZE */
  17.791 +  xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
  17.792 +  KdPrint((__DRIVER_NAME "     aligned_buffer_data = %p\n", xvdd->aligned_buffer_data));
  17.793 +  KdPrint((__DRIVER_NAME "     aligned_buffer = %p\n", xvdd->aligned_buffer));
  17.794 +
  17.795 +  ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024;
  17.796 +  ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT;
  17.797 +  FUNCTION_MSG("ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength);
  17.798 +  FUNCTION_MSG("ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks);
  17.799 +  ConfigInfo->VirtualDevice = FALSE;
  17.800 +  xvdd->aligned_buffer_size = DUMP_MODE_UNALIGNED_PAGES * PAGE_SIZE;
  17.801 +  ConfigInfo->ScatterGather = TRUE;
  17.802 +  ConfigInfo->Master = TRUE;
  17.803 +  ConfigInfo->CachesData = FALSE;
  17.804 +  ConfigInfo->MapBuffers = STOR_MAP_ALL_BUFFERS;
  17.805 +  FUNCTION_MSG("ConfigInfo->NeedPhysicalAddresses = %d\n", ConfigInfo->NeedPhysicalAddresses);
  17.806 +  ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
  17.807 +  ConfigInfo->AlignmentMask = 0;
  17.808 +  ConfigInfo->NumberOfBuses = 1;
  17.809 +  ConfigInfo->InitiatorBusId[0] = 1;
  17.810 +  ConfigInfo->MaximumNumberOfLogicalUnits = 1;
  17.811 +  ConfigInfo->MaximumNumberOfTargets = 2;
  17.812 +  if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) {
  17.813 +    ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
  17.814 +    FUNCTION_MSG("Dma64BitAddresses supported\n");
  17.815 +  } else {
  17.816 +    FUNCTION_MSG("Dma64BitAddresses not supported\n");
  17.817 +  }
  17.818 +  *Again = FALSE;
  17.819 +
  17.820    FUNCTION_EXIT();
  17.821 -  return status;
  17.822 +
  17.823 +  return SP_RETURN_FOUND;
  17.824  }
  17.825  
  17.826 -//do this in StartIo instead to prevent races with the driver initialisation
  17.827 -static VOID
  17.828 -XenVbd_StartRingDetection(PXENVBD_DEVICE_DATA xvdd)
  17.829 -{
  17.830 -  blkif_request_t *req;
  17.831 -  int notify;
  17.832 -
  17.833 -  xvdd->ring_detect_state = RING_DETECT_STATE_DETECT1;
  17.834 -  RtlZeroMemory(xvdd->sring->ring, PAGE_SIZE - FIELD_OFFSET(blkif_sring_t, ring));
  17.835 -  req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
  17.836 -  req->operation = 0xff;
  17.837 -  xvdd->ring.req_prod_pvt++;
  17.838 -  req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
  17.839 -  req->operation = 0xff;
  17.840 -  xvdd->ring.req_prod_pvt++;
  17.841 -
  17.842 -  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
  17.843 -  if (notify)
  17.844 -    xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
  17.845 -}
  17.846 -
  17.847 +/* Called at PASSIVE_LEVEL for non-dump mode */
  17.848  static BOOLEAN
  17.849  XenVbd_HwStorInitialize(PVOID DeviceExtension)
  17.850  {
  17.851    PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
  17.852 +  int i;
  17.853    
  17.854    FUNCTION_ENTER();
  17.855    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  17.856    KdPrint((__DRIVER_NAME "     dump_mode = %d\n", dump_mode));
  17.857 -
  17.858 -  if (!xvdd->inactive)
  17.859 -  {
  17.860 +  
  17.861 +  xvdd->shadow_free = 0;
  17.862 +  memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
  17.863 +  for (i = 0; i < SHADOW_ENTRIES; i++) {
  17.864 +    xvdd->shadows[i].req.id = i;
  17.865 +    /* make sure leftover real requests's are never confused with dump mode requests */
  17.866      if (dump_mode)
  17.867 -    {
  17.868 -      if (xvdd->cached_use_other)
  17.869 -      {
  17.870 -        xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
  17.871 -        xvdd->use_other = TRUE;
  17.872 -      }
  17.873 -      xvdd->ring_detect_state = RING_DETECT_STATE_COMPLETE;
  17.874 -    }
  17.875 -    InitializeListHead(&xvdd->srb_list);
  17.876 +      xvdd->shadows[i].req.id |= SHADOW_ID_DUMP_FLAG;
  17.877 +    put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
  17.878    }
  17.879 +
  17.880 +  if (!dump_mode) {
  17.881 +    StorPortInitializeDpc(DeviceExtension, &xvdd->dpc, XenVbd_HandleEventDpc);
  17.882 +  } else {
  17.883 +    xvdd->grant_tag = (ULONG)'DUMP';
  17.884 +  }
  17.885 +  
  17.886    FUNCTION_EXIT();
  17.887  
  17.888    return TRUE;
  17.889 @@ -1019,8 +1078,9 @@ XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA
  17.890    srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
  17.891  }
  17.892  
  17.893 -static BOOLEAN
  17.894 -XenVbd_HandleEventSynchronised(PVOID DeviceExtension, PVOID context)
  17.895 +/* called with StartIo lock held */
  17.896 +static VOID
  17.897 +XenVbd_HandleEvent(PVOID DeviceExtension)
  17.898  {
  17.899    PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
  17.900    PSCSI_REQUEST_BLOCK srb;
  17.901 @@ -1030,13 +1090,12 @@ XenVbd_HandleEventSynchronised(PVOID Dev
  17.902    //int block_count;
  17.903    int more_to_do = TRUE;
  17.904    blkif_shadow_t *shadow;
  17.905 -  ULONG suspend_resume_state_pdo;
  17.906 +  //ULONG suspend_resume_state_pdo;
  17.907    srb_list_entry_t *srb_entry;
  17.908  
  17.909 -  UNREFERENCED_PARAMETER(context);
  17.910 -  
  17.911    //if (dump_mode) FUNCTION_ENTER();
  17.912  
  17.913 +#if 0
  17.914    suspend_resume_state_pdo = xvdd->device_state->suspend_resume_state_pdo;
  17.915    KeMemoryBarrier();
  17.916  
  17.917 @@ -1057,7 +1116,6 @@ XenVbd_HandleEventSynchronised(PVOID Dev
  17.918        case SR_STATE_RUNNING:
  17.919          KdPrint((__DRIVER_NAME "     New pdo state %d\n", suspend_resume_state_pdo));
  17.920          xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
  17.921 -        xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED; /* could be running on different hardware */
  17.922          xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
  17.923        default:
  17.924          KdPrint((__DRIVER_NAME "     New pdo state %d\n", suspend_resume_state_pdo));
  17.925 @@ -1067,11 +1125,14 @@ XenVbd_HandleEventSynchronised(PVOID Dev
  17.926      }
  17.927      KeMemoryBarrier();
  17.928    }
  17.929 +#endif
  17.930  
  17.931 +#if 0
  17.932    if (xvdd->device_state->suspend_resume_state_fdo != SR_STATE_RUNNING)
  17.933    {
  17.934      return TRUE;
  17.935    }
  17.936 +#endif
  17.937  
  17.938    while (more_to_do)
  17.939    {
  17.940 @@ -1080,104 +1141,64 @@ XenVbd_HandleEventSynchronised(PVOID Dev
  17.941      for (i = xvdd->ring.rsp_cons; i != rp; i++)
  17.942      {
  17.943        rep = XenVbd_GetResponse(xvdd, i);
  17.944 -/*
  17.945 -* This code is to automatically detect if the backend is using the same
  17.946 -* bit width or a different bit width to us. Later versions of Xen do this
  17.947 -* via a xenstore value, but not all. That 0x0fffffff (notice
  17.948 -* that the msb is not actually set, so we don't have any problems with
  17.949 -* sign extending) is to signify the last entry on the right, which is
  17.950 -* different under 32 and 64 bits, and that is why we set it up there.
  17.951 -
  17.952 -* To do the detection, we put two initial entries on the ring, with an op
  17.953 -* of 0xff (which is invalid). The first entry is mostly okay, but the
  17.954 -* second will be grossly misaligned if the backend bit width is different,
  17.955 -* and we detect this and switch frontend structures.
  17.956 -*/
  17.957 -      switch (xvdd->ring_detect_state)
  17.958 +      shadow = &xvdd->shadows[rep->id & SHADOW_ID_ID_MASK];
  17.959 +      if (shadow->reset)
  17.960        {
  17.961 -      case RING_DETECT_STATE_NOT_STARTED:
  17.962 -        KdPrint((__DRIVER_NAME "     premature IRQ\n"));
  17.963 -        break;
  17.964 -      case RING_DETECT_STATE_DETECT1:
  17.965 -        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));
  17.966 -        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));
  17.967 -        xvdd->ring_detect_state = RING_DETECT_STATE_DETECT2;
  17.968 -        break;
  17.969 -      case RING_DETECT_STATE_DETECT2:
  17.970 -        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));
  17.971 -        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));
  17.972 -        *xvdd->event_channel_ptr |= 0x80000000;
  17.973 -        if (rep->operation != 0xff)
  17.974 +        KdPrint((__DRIVER_NAME "     discarding reset shadow\n"));
  17.975 +        for (j = 0; j < shadow->req.nr_segments; j++)
  17.976          {
  17.977 -          KdPrint((__DRIVER_NAME "     switching to 'other' ring size\n"));
  17.978 -          xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
  17.979 -          xvdd->use_other = TRUE;
  17.980 -          *xvdd->event_channel_ptr |= 0x40000000;
  17.981 +          XnEndAccess(xvdd->handle,
  17.982 +            shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
  17.983          }
  17.984 -        xvdd->ring_detect_state = RING_DETECT_STATE_COMPLETE;
  17.985 -        break;
  17.986 -      case RING_DETECT_STATE_COMPLETE:
  17.987 -        shadow = &xvdd->shadows[rep->id & SHADOW_ID_ID_MASK];
  17.988 -        if (shadow->reset)
  17.989 -        {
  17.990 -          KdPrint((__DRIVER_NAME "     discarding reset shadow\n"));
  17.991 -          for (j = 0; j < shadow->req.nr_segments; j++)
  17.992 -          {
  17.993 -            xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
  17.994 -              shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
  17.995 -          }
  17.996 -        }
  17.997 -        else if (dump_mode && !(rep->id & SHADOW_ID_DUMP_FLAG))
  17.998 -        {
  17.999 -          KdPrint((__DRIVER_NAME "     discarding stale (non-dump-mode) shadow\n"));
 17.1000 -        }
 17.1001 +      }
 17.1002 +      else if (dump_mode && !(rep->id & SHADOW_ID_DUMP_FLAG))
 17.1003 +      {
 17.1004 +        KdPrint((__DRIVER_NAME "     discarding stale (non-dump-mode) shadow\n"));
 17.1005 +      }
 17.1006 +      else
 17.1007 +      {
 17.1008 +        srb = shadow->srb;
 17.1009 +        NT_ASSERT(srb);
 17.1010 +        srb_entry = srb->SrbExtension;
 17.1011 +        NT_ASSERT(srb_entry);
 17.1012 +        /* 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 */
 17.1013 +        if (rep->status == BLKIF_RSP_OKAY || (dump_mode &&  dump_mode_errors++ < DUMP_MODE_ERROR_LIMIT))
 17.1014 +          srb->SrbStatus = SRB_STATUS_SUCCESS;
 17.1015          else
 17.1016          {
 17.1017 -          srb = shadow->srb;
 17.1018 -          NT_ASSERT(srb);
 17.1019 -          srb_entry = srb->SrbExtension;
 17.1020 -          NT_ASSERT(srb_entry);
 17.1021 -          /* 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 */
 17.1022 -          if (rep->status == BLKIF_RSP_OKAY || (dump_mode &&  dump_mode_errors++ < DUMP_MODE_ERROR_LIMIT))
 17.1023 -            srb->SrbStatus = SRB_STATUS_SUCCESS;
 17.1024 +          KdPrint((__DRIVER_NAME "     Xen Operation returned error\n"));
 17.1025 +          if (decode_cdb_is_read(srb))
 17.1026 +            KdPrint((__DRIVER_NAME "     Operation = Read\n"));
 17.1027            else
 17.1028 -          {
 17.1029 -            KdPrint((__DRIVER_NAME "     Xen Operation returned error\n"));
 17.1030 -            if (decode_cdb_is_read(srb))
 17.1031 -              KdPrint((__DRIVER_NAME "     Operation = Read\n"));
 17.1032 -            else
 17.1033 -              KdPrint((__DRIVER_NAME "     Operation = Write\n"));
 17.1034 -            srb_entry->error = TRUE;
 17.1035 -          }
 17.1036 -          if (shadow->aligned_buffer_in_use)
 17.1037 +            KdPrint((__DRIVER_NAME "     Operation = Write\n"));
 17.1038 +          srb_entry->error = TRUE;
 17.1039 +        }
 17.1040 +        if (shadow->aligned_buffer_in_use)
 17.1041 +        {
 17.1042 +          NT_ASSERT(xvdd->aligned_buffer_in_use);
 17.1043 +          xvdd->aligned_buffer_in_use = FALSE;
 17.1044 +          if (srb->SrbStatus == SRB_STATUS_SUCCESS && decode_cdb_is_read(srb))
 17.1045 +            memcpy((PUCHAR)shadow->system_address, xvdd->aligned_buffer, shadow->length);
 17.1046 +        }
 17.1047 +        for (j = 0; j < shadow->req.nr_segments; j++)
 17.1048 +        {
 17.1049 +          XnEndAccess(xvdd->handle, shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
 17.1050 +        }
 17.1051 +        srb_entry->outstanding_requests--;
 17.1052 +        if (!srb_entry->outstanding_requests && srb_entry->offset == srb_entry->length)
 17.1053 +        {
 17.1054 +          if (srb_entry->error)
 17.1055            {
 17.1056 -            NT_ASSERT(xvdd->aligned_buffer_in_use);
 17.1057 -            xvdd->aligned_buffer_in_use = FALSE;
 17.1058 -            if (srb->SrbStatus == SRB_STATUS_SUCCESS && decode_cdb_is_read(srb))
 17.1059 -              memcpy((PUCHAR)shadow->system_address, xvdd->aligned_buffer, shadow->length);
 17.1060 -          }
 17.1061 -          for (j = 0; j < shadow->req.nr_segments; j++)
 17.1062 -          {
 17.1063 -            xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
 17.1064 -              shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
 17.1065 -          }
 17.1066 -          srb_entry->outstanding_requests--;
 17.1067 -          if (!srb_entry->outstanding_requests && srb_entry->offset == srb_entry->length)
 17.1068 -          {
 17.1069 -            if (srb_entry->error)
 17.1070 -            {
 17.1071 -              srb->SrbStatus = SRB_STATUS_ERROR;
 17.1072 -              srb->ScsiStatus = 0x02;
 17.1073 -              xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
 17.1074 -              xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
 17.1075 -              XenVbd_MakeAutoSense(xvdd, srb);
 17.1076 -            }        
 17.1077 -            StorPortNotification(RequestComplete, xvdd, srb);
 17.1078 -          }
 17.1079 +            srb->SrbStatus = SRB_STATUS_ERROR;
 17.1080 +            srb->ScsiStatus = 0x02;
 17.1081 +            xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
 17.1082 +            xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
 17.1083 +            XenVbd_MakeAutoSense(xvdd, srb);
 17.1084 +          }        
 17.1085 +          StorPortNotification(RequestComplete, xvdd, srb);
 17.1086          }
 17.1087 -        put_shadow_on_freelist(xvdd, shadow);
 17.1088 -        break;
 17.1089        }
 17.1090 +      put_shadow_on_freelist(xvdd, shadow);
 17.1091      }
 17.1092  
 17.1093      xvdd->ring.rsp_cons = i;
 17.1094 @@ -1192,11 +1213,11 @@ XenVbd_HandleEventSynchronised(PVOID Dev
 17.1095      }
 17.1096    }
 17.1097  
 17.1098 -  XenVbd_PutQueuedSrbsOnRing(xvdd);
 17.1099 -
 17.1100 +  XenVbd_ProcessSrbList(xvdd);
 17.1101 +#if 0
 17.1102    if (suspend_resume_state_pdo == SR_STATE_SUSPENDING)
 17.1103    {
 17.1104 -    if (xvdd->inactive || xvdd->shadow_free == SHADOW_ENTRIES)
 17.1105 +    if ((xvdd->vbd_status == VBD_STATUS_ACTIVE) || xvdd->shadow_free == SHADOW_ENTRIES)
 17.1106      {
 17.1107        /* all entries are purged from the list (or we are inactive). ready to suspend */
 17.1108        xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
 17.1109 @@ -1207,34 +1228,39 @@ XenVbd_HandleEventSynchronised(PVOID Dev
 17.1110      }
 17.1111    }
 17.1112    //if (dump_mode) FUNCTION_EXIT();
 17.1113 -
 17.1114 -  return TRUE;
 17.1115 +#endif
 17.1116 +  return;
 17.1117  }
 17.1118  
 17.1119 -static BOOLEAN
 17.1120 -XenVbd_HandleEvent(PVOID DeviceExtension)
 17.1121 -{
 17.1122 -  BOOLEAN retval;
 17.1123 +static VOID
 17.1124 +XenVbd_HandleEventDpc(PSTOR_DPC dpc, PVOID DeviceExtension, PVOID arg1, PVOID arg2) {
 17.1125    STOR_LOCK_HANDLE lock_handle;
 17.1126 +  UNREFERENCED_PARAMETER(dpc);
 17.1127 +  UNREFERENCED_PARAMETER(arg1);
 17.1128 +  UNREFERENCED_PARAMETER(arg2);
 17.1129    
 17.1130 -  //if (dump_mode) FUNCTION_ENTER();
 17.1131    StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
 17.1132 -  retval = StorPortSynchronizeAccess(DeviceExtension, XenVbd_HandleEventSynchronised, NULL);
 17.1133 -  StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
 17.1134 +  XenVbd_HandleEvent(DeviceExtension);
 17.1135 +  StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
 17.1136 +}
 17.1137 +
 17.1138 +static VOID
 17.1139 +XenVbd_HandleEventDIRQL(PVOID DeviceExtension) {
 17.1140 +  PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
 17.1141 +  //if (dump_mode) FUNCTION_ENTER();
 17.1142 +  StorPortIssueDpc(DeviceExtension, &xvdd->dpc, NULL, NULL);
 17.1143    //if (dump_mode) FUNCTION_EXIT();
 17.1144 -  return retval;
 17.1145 +  return;
 17.1146  }
 17.1147  
 17.1148  /* this is only used during hiber and dump */
 17.1149  static BOOLEAN
 17.1150  XenVbd_HwStorInterrupt(PVOID DeviceExtension)
 17.1151  {
 17.1152 -  BOOLEAN retval;
 17.1153 -  
 17.1154    //FUNCTION_ENTER();
 17.1155 -  retval = XenVbd_HandleEventSynchronised(DeviceExtension, NULL);
 17.1156 +  XenVbd_HandleEvent(DeviceExtension);
 17.1157    //FUNCTION_EXIT();
 17.1158 -  return retval;
 17.1159 +  return TRUE;
 17.1160  }
 17.1161  
 17.1162  static BOOLEAN
 17.1163 @@ -1251,19 +1277,24 @@ XenVbd_HwStorResetBus(PVOID DeviceExtens
 17.1164    UNREFERENCED_PARAMETER(PathId);
 17.1165  
 17.1166    FUNCTION_ENTER();
 17.1167 +  
 17.1168 +  if (dump_mode) {
 17.1169 +    FUNCTION_MSG("dump mode - doing nothing\n");
 17.1170 +    FUNCTION_EXIT();
 17.1171 +    return TRUE;
 17.1172 +  }
 17.1173  
 17.1174    /* It appears that the StartIo spinlock is already held at this point */
 17.1175  
 17.1176    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 17.1177  
 17.1178 -  if (xvdd->ring_detect_state == RING_DETECT_STATE_COMPLETE && xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
 17.1179 -  {
 17.1180 +//  if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
 17.1181 +//  {
 17.1182      xvdd->aligned_buffer_in_use = FALSE;
 17.1183      
 17.1184      InitializeListHead(&srb_reset_list);
 17.1185      
 17.1186 -    while((list_entry = RemoveHeadList(&xvdd->srb_list)) != &xvdd->srb_list)
 17.1187 -    {
 17.1188 +    while((list_entry = RemoveHeadList(&xvdd->srb_list)) != &xvdd->srb_list) {
 17.1189        #if DBG
 17.1190        srb_list_entry_t *srb_entry = CONTAINING_RECORD(list_entry, srb_list_entry_t, list_entry);
 17.1191        KdPrint((__DRIVER_NAME "     adding queued SRB %p to reset list\n", srb_entry->srb));
 17.1192 @@ -1271,18 +1302,14 @@ XenVbd_HwStorResetBus(PVOID DeviceExtens
 17.1193        InsertTailList(&srb_reset_list, list_entry);
 17.1194      }
 17.1195      
 17.1196 -    for (i = 0; i < MAX_SHADOW_ENTRIES; i++)
 17.1197 -    {
 17.1198 -      if (xvdd->shadows[i].srb)
 17.1199 -      {
 17.1200 +    for (i = 0; i < MAX_SHADOW_ENTRIES; i++) {
 17.1201 +      if (xvdd->shadows[i].srb) {
 17.1202          srb_list_entry_t *srb_entry = xvdd->shadows[i].srb->SrbExtension;
 17.1203 -        for (list_entry = srb_reset_list.Flink; list_entry != &srb_reset_list; list_entry = list_entry->Flink)
 17.1204 -        {
 17.1205 +        for (list_entry = srb_reset_list.Flink; list_entry != &srb_reset_list; list_entry = list_entry->Flink) {
 17.1206            if (list_entry == &srb_entry->list_entry)
 17.1207              break;
 17.1208          }
 17.1209 -        if (list_entry == &srb_reset_list)
 17.1210 -        {
 17.1211 +        if (list_entry == &srb_reset_list) {
 17.1212            KdPrint((__DRIVER_NAME "     adding in-flight SRB %p to reset list\n", srb_entry->srb));
 17.1213            InsertTailList(&srb_reset_list, &srb_entry->list_entry);
 17.1214          }
 17.1215 @@ -1293,19 +1320,18 @@ XenVbd_HwStorResetBus(PVOID DeviceExtens
 17.1216        }
 17.1217      }
 17.1218  
 17.1219 -    while((list_entry = RemoveHeadList(&srb_reset_list)) != &srb_reset_list)
 17.1220 -    {
 17.1221 +    while((list_entry = RemoveHeadList(&srb_reset_list)) != &srb_reset_list) {
 17.1222        srb_list_entry_t *srb_entry = CONTAINING_RECORD(list_entry, srb_list_entry_t, list_entry);
 17.1223        srb_entry->srb->SrbStatus = SRB_STATUS_BUS_RESET;
 17.1224        KdPrint((__DRIVER_NAME "     completing SRB %p with status SRB_STATUS_BUS_RESET\n", srb_entry->srb));
 17.1225        StorPortNotification(RequestComplete, xvdd, srb_entry->srb);
 17.1226      }
 17.1227  
 17.1228 -    /* send a notify to Dom0 just in case it was missed for some reason (which should _never_ happen) */
 17.1229 -    xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
 17.1230 +    /* send a notify to Dom0 just in case it was missed for some reason (which should _never_ happen normally but could in dump mode) */
 17.1231 +    XnNotify(xvdd->handle, xvdd->event_channel);
 17.1232    
 17.1233      StorPortNotification(NextRequest, DeviceExtension);
 17.1234 -  }
 17.1235 +//  }
 17.1236  
 17.1237    //StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
 17.1238  
 17.1239 @@ -1314,17 +1340,592 @@ XenVbd_HwStorResetBus(PVOID DeviceExtens
 17.1240    return TRUE;
 17.1241  }
 17.1242  
 17.1243 -static BOOLEAN
 17.1244 -XenVbd_HwStorStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK srb)
 17.1245 -{
 17.1246 +/* called with StartIo lock held */
 17.1247 +VOID
 17.1248 +XenVbd_ProcessSrbList(PXENVBD_DEVICE_DATA xvdd) {
 17.1249    PUCHAR data_buffer;
 17.1250    PSCSI_PNP_REQUEST_BLOCK sprb;
 17.1251    PSCSI_POWER_REQUEST_BLOCK spwrb;
 17.1252    PMINIPORT_DUMP_POINTERS dump_pointers;
 17.1253    PCDB cdb;
 17.1254 -  PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
 17.1255    ULONG data_transfer_length;
 17.1256    UCHAR srb_status = SRB_STATUS_PENDING;
 17.1257 +  BOOLEAN notify = FALSE;
 17.1258 +  PSCSI_REQUEST_BLOCK srb;
 17.1259 +  srb_list_entry_t *srb_entry;
 17.1260 +
 17.1261 +  if (xvdd->vbd_status != VBD_STATUS_ACTIVE) {
 17.1262 +    FUNCTION_MSG("Not yet active\n");
 17.1263 +    return;
 17.1264 +  }
 17.1265 +
 17.1266 +  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) {
 17.1267 +    srb = srb_entry->srb;
 17.1268 +
 17.1269 +    if (xvdd->vbd_status == VBD_STATUS_INACTIVE) {
 17.1270 +      /* need to check again as may have been initialising when this srb was put on the list */
 17.1271 +      FUNCTION_MSG("HwStorStartIo Inactive Device (in ProcessSrbList)\n");
 17.1272 +      srb->SrbStatus = SRB_STATUS_NO_DEVICE;
 17.1273 +      StorPortNotification(RequestComplete, xvdd, srb);
 17.1274 +      continue;
 17.1275 +    }
 17.1276 +
 17.1277 +    data_transfer_length = srb->DataTransferLength;
 17.1278 +    
 17.1279 +    switch (srb->Function)
 17.1280 +    {
 17.1281 +    case SRB_FUNCTION_EXECUTE_SCSI:
 17.1282 +      cdb = (PCDB)srb->Cdb;
 17.1283 +
 17.1284 +      switch(cdb->CDB6GENERIC.OperationCode)
 17.1285 +      {
 17.1286 +      case SCSIOP_TEST_UNIT_READY:
 17.1287 +        if (dump_mode)
 17.1288 +          KdPrint((__DRIVER_NAME "     Command = TEST_UNIT_READY\n"));
 17.1289 +        srb_status = SRB_STATUS_SUCCESS;
 17.1290 +        srb->ScsiStatus = 0;
 17.1291 +        break;
 17.1292 +      case SCSIOP_INQUIRY:
 17.1293 +        if (dump_mode)
 17.1294 +          KdPrint((__DRIVER_NAME "     Command = INQUIRY\n"));
 17.1295 +  //      KdPrint((__DRIVER_NAME "     (LUN = %d, EVPD = %d, Page Code = %02X)\n", srb->Cdb[1] >> 5, srb->Cdb[1] & 1, srb->Cdb[2]));
 17.1296 +  //      KdPrint((__DRIVER_NAME "     (Length = %d)\n", srb->DataTransferLength));
 17.1297 +        
 17.1298 +        data_buffer = srb->DataBuffer;
 17.1299 +        RtlZeroMemory(data_buffer, srb->DataTransferLength);
 17.1300 +        srb_status = SRB_STATUS_SUCCESS;
 17.1301 +        switch (xvdd->device_type)
 17.1302 +        {
 17.1303 +        case XENVBD_DEVICETYPE_DISK:
 17.1304 +          if ((srb->Cdb[1] & 1) == 0) {
 17.1305 +            if (srb->Cdb[2]) {
 17.1306 +              srb_status = SRB_STATUS_ERROR;
 17.1307 +            } else {
 17.1308 +              PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
 17.1309 +              id->DeviceType = DIRECT_ACCESS_DEVICE;
 17.1310 +              id->Versions = 5; /* SPC-3 */
 17.1311 +              id->ResponseDataFormat = 2; /* not sure about this but WHQL complains otherwise */
 17.1312 +              id->HiSupport = 1; /* WHQL test says we should set this */
 17.1313 +              //id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
 17.1314 +              id->AdditionalLength = sizeof(INQUIRYDATA) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength) - 1;
 17.1315 +              id->CommandQueue = 1;
 17.1316 +              memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
 17.1317 +              memcpy(id->ProductId, scsi_disk_model, 16); // product id
 17.1318 +              memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
 17.1319 +              data_transfer_length = FIELD_OFFSET(INQUIRYDATA, VendorSpecific);
 17.1320 +            }
 17.1321 +          } else {
 17.1322 +            switch (srb->Cdb[2]) {
 17.1323 +            case VPD_SUPPORTED_PAGES: /* list of pages we support */
 17.1324 +              FUNCTION_MSG("VPD_SUPPORTED_PAGES\n");
 17.1325 +              data_buffer[0] = DIRECT_ACCESS_DEVICE;
 17.1326 +              data_buffer[1] = VPD_SUPPORTED_PAGES;
 17.1327 +              data_buffer[2] = 0x00;
 17.1328 +              data_buffer[3] = 4;
 17.1329 +              data_buffer[4] = VPD_SUPPORTED_PAGES;
 17.1330 +              data_buffer[5] = VPD_SERIAL_NUMBER;
 17.1331 +              data_buffer[6] = VPD_DEVICE_IDENTIFIERS;
 17.1332 +              data_buffer[7] = VPD_BLOCK_LIMITS;
 17.1333 +              data_transfer_length = 8;
 17.1334 +              break;
 17.1335 +            case VPD_SERIAL_NUMBER: /* serial number */
 17.1336 +              FUNCTION_MSG("VPD_SERIAL_NUMBER\n");
 17.1337 +              data_buffer[0] = DIRECT_ACCESS_DEVICE;
 17.1338 +              data_buffer[1] = VPD_SERIAL_NUMBER;
 17.1339 +              data_buffer[2] = 0x00;
 17.1340 +              data_buffer[3] = 8;
 17.1341 +              memset(&data_buffer[4], ' ', 8);
 17.1342 +              data_transfer_length = 12;
 17.1343 +              break;
 17.1344 +            case VPD_DEVICE_IDENTIFIERS: /* identification - we don't support any so just return zero */
 17.1345 +              FUNCTION_MSG("VPD_DEVICE_IDENTIFIERS\n");
 17.1346 +              data_buffer[0] = DIRECT_ACCESS_DEVICE;
 17.1347 +              data_buffer[1] = VPD_DEVICE_IDENTIFIERS;
 17.1348 +              data_buffer[2] = 0x00;
 17.1349 +              //data_buffer[3] = 4 + (UCHAR)strlen(xvdd->vectors.path); /* length */
 17.1350 +              data_buffer[4] = 2; /* ASCII */
 17.1351 +              data_buffer[5] = 1; /* VendorId */
 17.1352 +              data_buffer[6] = 0;
 17.1353 +              //data_buffer[7] = (UCHAR)strlen(xvdd->vectors.path);
 17.1354 +              //memcpy(&data_buffer[8], xvdd->vectors.path, strlen(xvdd->vectors.path));
 17.1355 +              //data_transfer_length = (ULONG)(8 + strlen(xvdd->vectors.path));
 17.1356 +              break;
 17.1357 +            case VPD_BLOCK_LIMITS: /* to indicate support for UNMAP (TRIM/DISCARD) */
 17.1358 +              FUNCTION_MSG("VPD_BLOCK_LIMITS\n");
 17.1359 +              // max descriptors = 1
 17.1360 +              // max sectors = 0xFFFFFFFF
 17.1361 +              // granularity = from xenbus
 17.1362 +              // alignment = from xenbus(?)
 17.1363 +              srb_status = SRB_STATUS_ERROR;
 17.1364 +              break;
 17.1365 +            default:
 17.1366 +              FUNCTION_MSG("Unknown Page %02x requested\n", srb->Cdb[2]);
 17.1367 +              srb_status = SRB_STATUS_ERROR;
 17.1368 +              break;
 17.1369 +            }
 17.1370 +          }
 17.1371 +          break;
 17.1372 +        case XENVBD_DEVICETYPE_CDROM:
 17.1373 +          if ((srb->Cdb[1] & 1) == 0)
 17.1374 +          {
 17.1375 +            PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
 17.1376 +            id->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
 17.1377 +            id->RemovableMedia = 1;
 17.1378 +            id->Versions = 3;
 17.1379 +            id->ResponseDataFormat = 0;
 17.1380 +            id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
 17.1381 +            id->CommandQueue = 1;
 17.1382 +            memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
 17.1383 +            memcpy(id->ProductId, scsi_cdrom_model, 16); // product id
 17.1384 +            memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
 17.1385 +            data_transfer_length = sizeof(INQUIRYDATA);
 17.1386 +          }
 17.1387 +          else
 17.1388 +          {
 17.1389 +            switch (srb->Cdb[2])
 17.1390 +            {
 17.1391 +            case 0x00:
 17.1392 +              data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
 17.1393 +              data_buffer[1] = 0x00;
 17.1394 +              data_buffer[2] = 0x00;
 17.1395 +              data_buffer[3] = 2;
 17.1396 +              data_buffer[4] = 0x00;
 17.1397 +              data_buffer[5] = 0x80;
 17.1398 +              data_transfer_length = 6;
 17.1399 +              break;
 17.1400 +            case 0x80:
 17.1401 +              data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
 17.1402 +              data_buffer[1] = 0x80;
 17.1403 +              data_buffer[2] = 0x00;
 17.1404 +              data_buffer[3] = 8;
 17.1405 +              data_buffer[4] = 0x31;
 17.1406 +              data_buffer[5] = 0x32;
 17.1407 +              data_buffer[6] = 0x33;
 17.1408 +              data_buffer[7] = 0x34;
 17.1409 +              data_buffer[8] = 0x35;
 17.1410 +              data_buffer[9] = 0x36;
 17.1411 +              data_buffer[10] = 0x37;
 17.1412 +              data_buffer[11] = 0x38;
 17.1413 +              data_transfer_length = 12;
 17.1414 +              break;
 17.1415 +            default:
 17.1416 +              //KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", srb->Cdb[2]));
 17.1417 +              srb_status = SRB_STATUS_ERROR;
 17.1418 +              break;
 17.1419 +            }
 17.1420 +          }
 17.1421 +          break;
 17.1422 +        default:
 17.1423 +          //KdPrint((__DRIVER_NAME "     Unknown DeviceType %02x requested\n", xvdd->device_type));
 17.1424 +          srb_status = SRB_STATUS_ERROR;
 17.1425 +          break;
 17.1426 +        }
 17.1427 +        break;
 17.1428 +      case SCSIOP_READ_CAPACITY:
 17.1429 +        //if (dump_mode)
 17.1430 +          KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
 17.1431 +        //KdPrint((__DRIVER_NAME "       LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
 17.1432 +        //KdPrint((__DRIVER_NAME "       LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
 17.1433 +        //KdPrint((__DRIVER_NAME "       PMI = %d\n", srb->Cdb[8] & 1));
 17.1434 +        //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
 17.1435 +        data_buffer = srb->DataBuffer;
 17.1436 +        RtlZeroMemory(data_buffer, srb->DataTransferLength);
 17.1437 +        if ((xvdd->total_sectors - 1) >> 32)
 17.1438 +        {
 17.1439 +          data_buffer[0] = 0xff;
 17.1440 +          data_buffer[1] = 0xff;
 17.1441 +          data_buffer[2] = 0xff;
 17.1442 +          data_buffer[3] = 0xff;
 17.1443 +        }
 17.1444 +        else
 17.1445 +        {
 17.1446 +          data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
 17.1447 +          data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
 17.1448 +          data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
 17.1449 +          data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
 17.1450 +        }
 17.1451 +        data_buffer[4] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
 17.1452 +        data_buffer[5] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
 17.1453 +        data_buffer[6] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
 17.1454 +        data_buffer[7] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
 17.1455 +        data_transfer_length = 8;
 17.1456 +        srb->ScsiStatus = 0;
 17.1457 +        srb_status = SRB_STATUS_SUCCESS;
 17.1458 +        break;
 17.1459 +      case SCSIOP_READ_CAPACITY16:
 17.1460 +        //if (dump_mode)
 17.1461 +          KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY16\n"));
 17.1462 +        //KdPrint((__DRIVER_NAME "       LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
 17.1463 +        //KdPrint((__DRIVER_NAME "       LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
 17.1464 +        //KdPrint((__DRIVER_NAME "       PMI = %d\n", srb->Cdb[8] & 1));
 17.1465 +        data_buffer = srb->DataBuffer;
 17.1466 +        RtlZeroMemory(data_buffer, srb->DataTransferLength);
 17.1467 +        data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 56) & 0xff;
 17.1468 +        data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 48) & 0xff;
 17.1469 +        data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 40) & 0xff;
 17.1470 +        data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 32) & 0xff;
 17.1471 +        data_buffer[4] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
 17.1472 +        data_buffer[5] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
 17.1473 +        data_buffer[6] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
 17.1474 +        data_buffer[7] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
 17.1475 +        data_buffer[8] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
 17.1476 +        data_buffer[9] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
 17.1477 +        data_buffer[10] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
 17.1478 +        data_buffer[11] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
 17.1479 +        data_buffer[12] = 0;
 17.1480 +        switch (xvdd->hw_bytes_per_sector / xvdd->bytes_per_sector) {
 17.1481 +        case 1:
 17.1482 +          data_buffer[13] = 0; /* 512 byte hardware sectors */
 17.1483 +          break;
 17.1484 +        case 2:
 17.1485 +          data_buffer[13] = 1; /* 1024 byte hardware sectors */
 17.1486 +          break;
 17.1487 +        case 3:
 17.1488 +          data_buffer[13] = 2; /* 2048 byte hardware sectors */
 17.1489 +          break;
 17.1490 +        case 4:
 17.1491 +          data_buffer[13] = 3; /* 4096 byte hardware sectors */
 17.1492 +          break;
 17.1493 +        default:
 17.1494 +          data_buffer[13] = 0; /* 512 byte hardware sectors */
 17.1495 +          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));
 17.1496 +          break;
 17.1497 +        }
 17.1498 +        data_buffer[14] = 0xC0; //0;
 17.1499 +        data_buffer[15] = 0;
 17.1500 +        data_transfer_length = 16;
 17.1501 +        srb->ScsiStatus = 0;
 17.1502 +        srb_status = SRB_STATUS_SUCCESS;
 17.1503 +        break;
 17.1504 +      case SCSIOP_MODE_SENSE:
 17.1505 +      case SCSIOP_MODE_SENSE10:
 17.1506 +        if (dump_mode)
 17.1507 +          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));
 17.1508 +        data_transfer_length = XenVbd_FillModePage(xvdd, srb);
 17.1509 +        srb_status = SRB_STATUS_SUCCESS;
 17.1510 +        break;
 17.1511 +      case SCSIOP_READ:
 17.1512 +      case SCSIOP_READ16:
 17.1513 +      case SCSIOP_WRITE:
 17.1514 +      case SCSIOP_WRITE16:
 17.1515 +        //FUNCTION_MSG("srb = %p\n", srb);
 17.1516 +        if (XenVbd_PutSrbOnRing(xvdd, srb)) {
 17.1517 +          notify = TRUE;
 17.1518 +        }
 17.1519 +        break;
 17.1520 +      case SCSIOP_WRITE_SAME:
 17.1521 +      case SCSIOP_WRITE_SAME16:
 17.1522 +        /* not yet supported */
 17.1523 +        FUNCTION_MSG("WRITE_SAME\n");
 17.1524 +        break;
 17.1525 +      case SCSIOP_UNMAP:
 17.1526 +        /* not yet supported */
 17.1527 +        FUNCTION_MSG("UNMAP\n");
 17.1528 +        break;
 17.1529 +      case SCSIOP_VERIFY:
 17.1530 +      case SCSIOP_VERIFY16:
 17.1531 +        // Should we do more here?
 17.1532 +        if (dump_mode)
 17.1533 +          KdPrint((__DRIVER_NAME "     Command = VERIFY\n"));
 17.1534 +        srb_status = SRB_STATUS_SUCCESS;
 17.1535 +        break;
 17.1536 +      case SCSIOP_REPORT_LUNS:
 17.1537 +        //if (dump_mode)
 17.1538 +          FUNCTION_MSG("Command = REPORT_LUNS\n");
 17.1539 +        switch (srb->Cdb[2]) {
 17.1540 +        case 1:
 17.1541 +          FUNCTION_MSG(" SELECT REPORT = %d\n", srb->Cdb[2] & 255);
 17.1542 +          break;
 17.1543 +        default:
 17.1544 +          FUNCTION_MSG(" SELECT REPORT = %d\n", srb->Cdb[2] & 255);
 17.1545 +          break;
 17.1546 +        }
 17.1547 +        FUNCTION_MSG(" ALLOCATION LENGTH = %d\n", (srb->Cdb[6] << 24)|(srb->Cdb[7] << 16)|(srb->Cdb[8] << 8)|(srb->Cdb[9]));
 17.1548 +        data_buffer = srb->DataBuffer;
 17.1549 +        RtlZeroMemory(data_buffer, srb->DataTransferLength);
 17.1550 +        data_buffer[3] = 8; /* 1 lun */
 17.1551 +        /* rest of the data is blank */
 17.1552 +        data_transfer_length = 16;
 17.1553 +        srb->ScsiStatus = 0;
 17.1554 +        srb_status = SRB_STATUS_SUCCESS;
 17.1555 +        break;
 17.1556 +      case SCSIOP_REQUEST_SENSE:
 17.1557 +        if (dump_mode)
 17.1558 +          KdPrint((__DRIVER_NAME "     Command = REQUEST_SENSE\n"));
 17.1559 +        data_transfer_length = XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
 17.1560 +        srb_status = SRB_STATUS_SUCCESS;
 17.1561 +        break;      
 17.1562 +      case SCSIOP_READ_TOC:
 17.1563 +        if (dump_mode)
 17.1564 +          KdPrint((__DRIVER_NAME "     Command = READ_TOC\n"));
 17.1565 +        data_buffer = srb->DataBuffer;
 17.1566 +  /*
 17.1567 +  #define READ_TOC_FORMAT_TOC         0x00
 17.1568 +  #define READ_TOC_FORMAT_SESSION     0x01
 17.1569 +  #define READ_TOC_FORMAT_FULL_TOC    0x02
 17.1570 +  #define READ_TOC_FORMAT_PMA         0x03
 17.1571 +  #define READ_TOC_FORMAT_ATIP        0x04
 17.1572 +  */
 17.1573 +  //      KdPrint((__DRIVER_NAME "     Msf = %d\n", cdb->READ_TOC.Msf));
 17.1574 +  //      KdPrint((__DRIVER_NAME "     LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
 17.1575 +  //      KdPrint((__DRIVER_NAME "     Format2 = %d\n", cdb->READ_TOC.Format2));
 17.1576 +  //      KdPrint((__DRIVER_NAME "     StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
 17.1577 +  //      KdPrint((__DRIVER_NAME "     AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
 17.1578 +  //      KdPrint((__DRIVER_NAME "     Control = %d\n", cdb->READ_TOC.Control));
 17.1579 +  //      KdPrint((__DRIVER_NAME "     Format = %d\n", cdb->READ_TOC.Format));
 17.1580 +        switch (cdb->READ_TOC.Format2)
 17.1581 +        {
 17.1582 +        case READ_TOC_FORMAT_TOC:
 17.1583 +          data_buffer[0] = 0; // length MSB
 17.1584 +          data_buffer[1] = 10; // length LSB
 17.1585 +          data_buffer[2] = 1; // First Track
 17.1586 +          data_buffer[3] = 1; // Last Track
 17.1587 +          data_buffer[4] = 0; // Reserved
 17.1588 +          data_buffer[5] = 0x14; // current position data + uninterrupted data
 17.1589 +          data_buffer[6] = 1; // last complete track
 17.1590 +          data_buffer[7] = 0; // reserved
 17.1591 +          data_buffer[8] = 0; // MSB Block
 17.1592 +          data_buffer[9] = 0;
 17.1593 +          data_buffer[10] = 0;
 17.1594 +          data_buffer[11] = 0; // LSB Block
 17.1595 +          data_transfer_length = 12;
 17.1596 +          srb_status = SRB_STATUS_SUCCESS;
 17.1597 +          break;
 17.1598 +        case READ_TOC_FORMAT_SESSION:
 17.1599 +        case READ_TOC_FORMAT_FULL_TOC:
 17.1600 +        case READ_TOC_FORMAT_PMA:
 17.1601 +        case READ_TOC_FORMAT_ATIP:
 17.1602 +          srb_status = SRB_STATUS_ERROR;
 17.1603 +          break;
 17.1604 +        default:
 17.1605 +          srb_status = SRB_STATUS_ERROR;
 17.1606 +          break;
 17.1607 +        }
 17.1608 +        break;
 17.1609 +      case SCSIOP_START_STOP_UNIT:
 17.1610 +        KdPrint((__DRIVER_NAME "     Command = SCSIOP_START_STOP_UNIT\n"));
 17.1611 +        srb_status = SRB_STATUS_SUCCESS;
 17.1612 +        break;
 17.1613 +      case SCSIOP_RESERVE_UNIT:
 17.1614 +        KdPrint((__DRIVER_NAME "     Command = SCSIOP_RESERVE_UNIT\n"));
 17.1615 +        srb_status = SRB_STATUS_SUCCESS;
 17.1616 +        break;
 17.1617 +      case SCSIOP_RELEASE_UNIT:
 17.1618 +        KdPrint((__DRIVER_NAME "     Command = SCSIOP_RELEASE_UNIT\n"));
 17.1619 +        srb_status = SRB_STATUS_SUCCESS;
 17.1620 +        break;
 17.1621 +      default:
 17.1622 +        KdPrint((__DRIVER_NAME "     Unhandled EXECUTE_SCSI Command = %02X\n", srb->Cdb[0]));
 17.1623 +        xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
 17.1624 +        srb_status = SRB_STATUS_ERROR;
 17.1625 +        break;
 17.1626 +      }
 17.1627 +      if (srb_status == SRB_STATUS_ERROR)
 17.1628 +      {
 17.1629 +        KdPrint((__DRIVER_NAME "     EXECUTE_SCSI Command = %02X returned error %02x\n", srb->Cdb[0], xvdd->last_sense_key));
 17.1630 +        if (xvdd->last_sense_key == SCSI_SENSE_NO_SENSE)
 17.1631 +        {
 17.1632 +          xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
 17.1633 +          xvdd->last_additional_sense_code = SCSI_ADSENSE_INVALID_CDB;
 17.1634 +        }
 17.1635 +        srb->SrbStatus = srb_status;
 17.1636 +        srb->ScsiStatus = 0x02;
 17.1637 +        XenVbd_MakeAutoSense(xvdd, srb);
 17.1638 +        StorPortNotification(RequestComplete, xvdd, srb);
 17.1639 +      }
 17.1640 +      else if (srb_status != SRB_STATUS_PENDING)
 17.1641 +      {
 17.1642 +        if (data_transfer_length > srb->DataTransferLength)
 17.1643 +          KdPrint((__DRIVER_NAME "     data_transfer_length too big - %d > %d\n", data_transfer_length, srb->DataTransferLength));
 17.1644 +        
 17.1645 +        if (srb_status == SRB_STATUS_SUCCESS && data_transfer_length < srb->DataTransferLength)
 17.1646 +        {
 17.1647 +          srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
 17.1648 +          srb->DataTransferLength = data_transfer_length;
 17.1649 +        }
 17.1650 +        else
 17.1651 +        {
 17.1652 +          srb->SrbStatus = srb_status;
 17.1653 +        }
 17.1654 +        xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
 17.1655 +        xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
 17.1656 +        StorPortNotification(RequestComplete, xvdd, srb);
 17.1657 +      }
 17.1658 +      break;
 17.1659 +    case SRB_FUNCTION_IO_CONTROL:
 17.1660 +      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_IO_CONTROL\n"));
 17.1661 +      srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 17.1662 +      StorPortNotification(RequestComplete, xvdd, srb);
 17.1663 +      break;
 17.1664 +    case SRB_FUNCTION_FLUSH:
 17.1665 +      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
 17.1666 +      srb->SrbStatus = SRB_STATUS_SUCCESS;
 17.1667 +      StorPortNotification(RequestComplete, xvdd, srb);
 17.1668 +      break;
 17.1669 +    case SRB_FUNCTION_PNP:
 17.1670 +      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_PNP\n"));
 17.1671 +      sprb = (PSCSI_PNP_REQUEST_BLOCK)srb;
 17.1672 +      switch (sprb->PnPAction)
 17.1673 +      {
 17.1674 +      case StorStartDevice:
 17.1675 +        KdPrint((__DRIVER_NAME "      StorStartDevice\n"));
 17.1676 +        break;
 17.1677 +      case StorRemoveDevice:
 17.1678 +        KdPrint((__DRIVER_NAME "      StorRemoveDevice\n"));
 17.1679 +        break;
 17.1680 +      case StorStopDevice:
 17.1681 +        KdPrint((__DRIVER_NAME "      StorStopDevice\n"));
 17.1682 +        break;
 17.1683 +      case StorQueryCapabilities:
 17.1684 +        KdPrint((__DRIVER_NAME "      StorQueryCapabilities\n"));
 17.1685 +        break;
 17.1686 +      case StorFilterResourceRequirements:
 17.1687 +        KdPrint((__DRIVER_NAME "      StorFilterResourceRequirements\n"));
 17.1688 +        break;
 17.1689 +      default:
 17.1690 +        KdPrint((__DRIVER_NAME "      Stor%d\n", sprb->PnPAction));
 17.1691 +        break;
 17.1692 +      }
 17.1693 +      KdPrint((__DRIVER_NAME "      SrbPnPFlags = %08x\n", sprb->SrbPnPFlags));
 17.1694 +      srb->SrbStatus = SRB_STATUS_SUCCESS;
 17.1695 +      StorPortNotification(RequestComplete, xvdd, srb);
 17.1696 +      break;
 17.1697 +      
 17.1698 +    case SRB_FUNCTION_POWER:
 17.1699 +      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_POWER\n"));
 17.1700 +      spwrb = (PSCSI_POWER_REQUEST_BLOCK)srb;
 17.1701 +      switch (spwrb->PowerAction)
 17.1702 +      {
 17.1703 +      case StorPowerActionNone:
 17.1704 +        KdPrint((__DRIVER_NAME "      StorPowerActionNone\n"));
 17.1705 +        break;
 17.1706 +      case StorPowerActionReserved:
 17.1707 +        KdPrint((__DRIVER_NAME "      StorPowerActionReserved\n"));
 17.1708 +        break;
 17.1709 +      case StorPowerActionSleep:
 17.1710 +        KdPrint((__DRIVER_NAME "      StorPowerActionSleep\n"));
 17.1711 +        break;
 17.1712 +      case StorPowerActionHibernate:
 17.1713 +        KdPrint((__DRIVER_NAME "      StorPowerActionHibernate\n"));
 17.1714 +        break;
 17.1715 +      case StorPowerActionShutdown:
 17.1716 +        KdPrint((__DRIVER_NAME "      StorPowerActionShutdown\n"));
 17.1717 +        break;
 17.1718 +      case StorPowerActionShutdownReset:
 17.1719 +        KdPrint((__DRIVER_NAME "      StorPowerActionShutdownReset\n"));
 17.1720 +        break;
 17.1721 +      case StorPowerActionShutdownOff:
 17.1722 +        KdPrint((__DRIVER_NAME "      StorPowerActionShutdownOff\n"));
 17.1723 +        break;
 17.1724 +      case StorPowerActionWarmEject:
 17.1725 +        KdPrint((__DRIVER_NAME "      StorPowerActionWarmEject\n"));
 17.1726 +        break;
 17.1727 +      default:
 17.1728 +        KdPrint((__DRIVER_NAME "      Stor%d\n", spwrb->PowerAction));
 17.1729 +        break;
 17.1730 +      }
 17.1731 +      srb->SrbStatus = SRB_STATUS_SUCCESS;
 17.1732 +      StorPortNotification(RequestComplete, xvdd, srb);
 17.1733 +      break;
 17.1734 +    case SRB_FUNCTION_DUMP_POINTERS:
 17.1735 +      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_DUMP_POINTERS\n"));
 17.1736 +      KdPrint((__DRIVER_NAME "     DataTransferLength = %d\n", srb->DataTransferLength));
 17.1737 +      dump_pointers = srb->DataBuffer;
 17.1738 +      KdPrint((__DRIVER_NAME "      Version = %d\n", dump_pointers->Version));
 17.1739 +      KdPrint((__DRIVER_NAME "      Size = %d\n", dump_pointers->Size));
 17.1740 +      KdPrint((__DRIVER_NAME "      DriverName = %S\n", dump_pointers->DriverName));
 17.1741 +      KdPrint((__DRIVER_NAME "      AdapterObject = %p\n", dump_pointers->AdapterObject));
 17.1742 +      KdPrint((__DRIVER_NAME "      MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
 17.1743 +      KdPrint((__DRIVER_NAME "      CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
 17.1744 +      KdPrint((__DRIVER_NAME "      MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
 17.1745 +      KdPrint((__DRIVER_NAME "      SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
 17.1746 +      KdPrint((__DRIVER_NAME "      AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
 17.1747 +      KdPrint((__DRIVER_NAME "      MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
 17.1748 +      KdPrint((__DRIVER_NAME "      NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
 17.1749 +      KdPrint((__DRIVER_NAME "      AlignmentMask = %d\n", dump_pointers->AlignmentMask));
 17.1750 +      KdPrint((__DRIVER_NAME "      NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
 17.1751 +      KdPrint((__DRIVER_NAME "      NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
 17.1752 +      KdPrint((__DRIVER_NAME "      Master = %d\n", dump_pointers->Master));
 17.1753 +      KdPrint((__DRIVER_NAME "      MapBuffers = %d\n", dump_pointers->MapBuffers));
 17.1754 +      KdPrint((__DRIVER_NAME "      MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
 17.1755 +
 17.1756 +      dump_pointers->Version = DUMP_MINIPORT_VERSION_1;
 17.1757 +      dump_pointers->Size = sizeof(MINIPORT_DUMP_POINTERS);
 17.1758 +      RtlStringCchCopyW(dump_pointers->DriverName, DUMP_MINIPORT_NAME_LENGTH, L"xenvbd.sys");
 17.1759 +      dump_pointers->AdapterObject = NULL;
 17.1760 +      dump_pointers->MappedRegisterBase = 0;
 17.1761 +      dump_pointers->CommonBufferSize = 0;
 17.1762 +      dump_pointers->MiniportPrivateDumpData = xvdd;
 17.1763 +      dump_pointers->AdapterInterfaceType = Internal;
 17.1764 +      dump_pointers->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;;
 17.1765 +      dump_pointers->NumberOfPhysicalBreaks = dump_pointers->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
 17.1766 +      dump_pointers->AlignmentMask = 0;
 17.1767 +      dump_pointers->NumberOfAccessRanges = 1;
 17.1768 +      dump_pointers->NumberOfBuses = 1;
 17.1769 +      dump_pointers->Master = TRUE;
 17.1770 +      dump_pointers->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
 17.1771 +      dump_pointers->MaximumNumberOfTargets = 2;
 17.1772 +
 17.1773 +      KdPrint((__DRIVER_NAME "      Version = %d\n", dump_pointers->Version));
 17.1774 +      KdPrint((__DRIVER_NAME "      Size = %d\n", dump_pointers->Size));
 17.1775 +      //KdPrint((__DRIVER_NAME "      DriverName = %S\n", dump_pointers->DriverName));
 17.1776 +      KdPrint((__DRIVER_NAME "      AdapterObject = %p\n", dump_pointers->AdapterObject));
 17.1777 +      KdPrint((__DRIVER_NAME "      MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
 17.1778 +      KdPrint((__DRIVER_NAME "      CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
 17.1779 +      KdPrint((__DRIVER_NAME "      MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
 17.1780 +      KdPrint((__DRIVER_NAME "      SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
 17.1781 +      KdPrint((__DRIVER_NAME "      AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
 17.1782 +      KdPrint((__DRIVER_NAME "      MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
 17.1783 +      KdPrint((__DRIVER_NAME "      NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
 17.1784 +      KdPrint((__DRIVER_NAME "      AlignmentMask = %d\n", dump_pointers->AlignmentMask));
 17.1785 +      KdPrint((__DRIVER_NAME "      NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
 17.1786 +      KdPrint((__DRIVER_NAME "      NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
 17.1787 +      KdPrint((__DRIVER_NAME "      Master = %d\n", dump_pointers->Master));
 17.1788 +      KdPrint((__DRIVER_NAME "      MapBuffers = %d\n", dump_pointers->MapBuffers));
 17.1789 +      KdPrint((__DRIVER_NAME "      MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
 17.1790 +
 17.1791 +      srb->SrbStatus = SRB_STATUS_SUCCESS;
 17.1792 +      StorPortNotification(RequestComplete, xvdd, srb);
 17.1793 +      break;
 17.1794 +    case SRB_FUNCTION_SHUTDOWN:
 17.1795 +      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_SHUTDOWN %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
 17.1796 +      srb->SrbStatus = SRB_STATUS_SUCCESS;
 17.1797 +      StorPortNotification(RequestComplete, xvdd, srb);
 17.1798 +      break;
 17.1799 +    case SRB_FUNCTION_RESET_BUS:
 17.1800 +    case SRB_FUNCTION_RESET_DEVICE:
 17.1801 +    case SRB_FUNCTION_RESET_LOGICAL_UNIT:
 17.1802 +      /* the path doesn't matter here - only ever one device*/
 17.1803 +      XenVbd_HwStorResetBus(xvdd, 0);
 17.1804 +      srb->SrbStatus = SRB_STATUS_SUCCESS;
 17.1805 +      StorPortNotification(RequestComplete, xvdd, srb);    
 17.1806 +      break;
 17.1807 +    case SRB_FUNCTION_WMI:
 17.1808 +      srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 17.1809 +      StorPortNotification(RequestComplete, xvdd, srb);
 17.1810 +      break;
 17.1811 +
 17.1812 +    default:
 17.1813 +      KdPrint((__DRIVER_NAME "     Unhandled srb->Function = %08X\n", srb->Function));
 17.1814 +      srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 17.1815 +      StorPortNotification(RequestComplete, xvdd, srb);
 17.1816 +      break;
 17.1817 +    }
 17.1818 +  }
 17.1819 +  if (notify) {
 17.1820 +    notify = FALSE;
 17.1821 +    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
 17.1822 +    if (notify) {
 17.1823 +      XnNotify(xvdd->handle, xvdd->event_channel);
 17.1824 +    }
 17.1825 +  }
 17.1826 +  return;
 17.1827 +}
 17.1828 +
 17.1829 +static BOOLEAN
 17.1830 +XenVbd_HwStorStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK srb)
 17.1831 +{
 17.1832 +  PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
 17.1833    STOR_LOCK_HANDLE lock_handle;
 17.1834  
 17.1835    //if (dump_mode) FUNCTION_ENTER();
 17.1836 @@ -1332,597 +1933,26 @@ XenVbd_HwStorStartIo(PVOID DeviceExtensi
 17.1837  
 17.1838    StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
 17.1839  
 17.1840 -  data_transfer_length = srb->DataTransferLength;
 17.1841 -  
 17.1842 -  if (xvdd->inactive)
 17.1843 -  {
 17.1844 -    KdPrint((__DRIVER_NAME "     Inactive srb->Function = %08X\n", srb->Function));
 17.1845 +  if (xvdd->vbd_status == VBD_STATUS_INACTIVE) {
 17.1846 +    FUNCTION_MSG("HwStorStartIo Inactive Device (in StartIo)\n");
 17.1847      srb->SrbStatus = SRB_STATUS_NO_DEVICE;
 17.1848      StorPortNotification(RequestComplete, DeviceExtension, srb);
 17.1849      StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
 17.1850      return TRUE;
 17.1851    }
 17.1852  
 17.1853 -  if (xvdd->ring_detect_state == RING_DETECT_STATE_NOT_STARTED)
 17.1854 -  {
 17.1855 -    XenVbd_StartRingDetection(DeviceExtension);
 17.1856 -  }
 17.1857 -
 17.1858 -  // If we haven't enumerated all the devices yet then just defer the request
 17.1859 -  if (xvdd->ring_detect_state < RING_DETECT_STATE_COMPLETE)
 17.1860 -  {
 17.1861 -    srb->SrbStatus = SRB_STATUS_BUSY;
 17.1862 -    StorPortNotification(RequestComplete, DeviceExtension, srb);
 17.1863 -    KdPrint((__DRIVER_NAME " --- HwStorStartIo (Still figuring out ring)\n"));
 17.1864 -    StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
 17.1865 -    return TRUE;
 17.1866 -  }
 17.1867 -
 17.1868 -  if (!dump_mode && xvdd->device_state->suspend_resume_state_pdo != SR_STATE_RUNNING)
 17.1869 -  {
 17.1870 -    //KdPrint((__DRIVER_NAME " --> HwStorStartIo (Suspending/Resuming)\n"));
 17.1871 -    srb->SrbStatus = SRB_STATUS_BUSY;
 17.1872 -    StorPortNotification(RequestComplete, DeviceExtension, srb);
 17.1873 -    //KdPrint((__DRIVER_NAME " <-- HwStorStartIo (Suspending/Resuming)\n"));
 17.1874 -    StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
 17.1875 -    return TRUE;
 17.1876 -  }
 17.1877 -
 17.1878    if (srb->PathId != 0 || srb->TargetId != 0 || srb->Lun != 0)
 17.1879    {
 17.1880 +    FUNCTION_MSG("HwStorStartIo (Out of bounds - PathId = %d, TargetId = %d, Lun = %d)\n", srb->PathId, srb->TargetId, srb->Lun);
 17.1881      srb->SrbStatus = SRB_STATUS_NO_DEVICE;
 17.1882      StorPortNotification(RequestComplete, DeviceExtension, srb);
 17.1883 -    KdPrint((__DRIVER_NAME " --- HwStorStartIo (Out of bounds - PathId = %d, TargetId = %d, Lun = %d)\n", srb->PathId, srb->TargetId, srb->Lun));
 17.1884      StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
 17.1885      return TRUE;
 17.1886    }
 17.1887  
 17.1888 -  switch (srb->Function)
 17.1889 -  {
 17.1890 -  case SRB_FUNCTION_EXECUTE_SCSI:
 17.1891 -    cdb = (PCDB)srb->Cdb;
 17.1892 -
 17.1893 -    switch(cdb->CDB6GENERIC.OperationCode)
 17.1894 -    {
 17.1895 -    case SCSIOP_TEST_UNIT_READY:
 17.1896 -      if (dump_mode)
 17.1897 -        KdPrint((__DRIVER_NAME "     Command = TEST_UNIT_READY\n"));
 17.1898 -      srb_status = SRB_STATUS_SUCCESS;
 17.1899 -      srb->ScsiStatus = 0;
 17.1900 -      break;
 17.1901 -    case SCSIOP_INQUIRY:
 17.1902 -      if (dump_mode)
 17.1903 -        KdPrint((__DRIVER_NAME "     Command = INQUIRY\n"));
 17.1904 -//      KdPrint((__DRIVER_NAME "     (LUN = %d, EVPD = %d, Page Code = %02X)\n", srb->Cdb[1] >> 5, srb->Cdb[1] & 1, srb->Cdb[2]));
 17.1905 -//      KdPrint((__DRIVER_NAME "     (Length = %d)\n", srb->DataTransferLength));
 17.1906 -      
 17.1907 -      data_buffer = srb->DataBuffer;
 17.1908 -      RtlZeroMemory(data_buffer, srb->DataTransferLength);
 17.1909 -      srb_status = SRB_STATUS_SUCCESS;
 17.1910 -      switch (xvdd->device_type)
 17.1911 -      {
 17.1912 -      case XENVBD_DEVICETYPE_DISK:
 17.1913 -        if ((srb->Cdb[1] & 1) == 0) {
 17.1914 -          if (srb->Cdb[2]) {
 17.1915 -            srb_status = SRB_STATUS_ERROR;
 17.1916 -          } else {
 17.1917 -            PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
 17.1918 -            id->DeviceType = DIRECT_ACCESS_DEVICE;
 17.1919 -            id->Versions = 5; /* SPC-3 */
 17.1920 -            id->ResponseDataFormat = 2; /* not sure about this but WHQL complains otherwise */
 17.1921 -            id->HiSupport = 1; /* WHQL test says we should set this */
 17.1922 -            //id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
 17.1923 -            id->AdditionalLength = sizeof(INQUIRYDATA) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength) - 1;
 17.1924 -            id->CommandQueue = 1;
 17.1925 -            memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
 17.1926 -            memcpy(id->ProductId, scsi_disk_model, 16); // product id
 17.1927 -            memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
 17.1928 -            data_transfer_length = FIELD_OFFSET(INQUIRYDATA, VendorSpecific);
 17.1929 -          }
 17.1930 -        } else {
 17.1931 -          switch (srb->Cdb[2]) {
 17.1932 -          case VPD_SUPPORTED_PAGES: /* list of pages we support */
 17.1933 -            FUNCTION_MSG("VPD_SUPPORTED_PAGES\n");
 17.1934 -            data_buffer[0] = DIRECT_ACCESS_DEVICE;
 17.1935 -            data_buffer[1] = VPD_SUPPORTED_PAGES;
 17.1936 -            data_buffer[2] = 0x00;
 17.1937 -            data_buffer[3] = 4;
 17.1938 -            data_buffer[4] = VPD_SUPPORTED_PAGES;
 17.1939 -            data_buffer[5] = VPD_SERIAL_NUMBER;
 17.1940 -            data_buffer[6] = VPD_DEVICE_IDENTIFIERS;
 17.1941 -            data_buffer[7] = VPD_BLOCK_LIMITS;
 17.1942 -            data_transfer_length = 8;
 17.1943 -            break;
 17.1944 -          case VPD_SERIAL_NUMBER: /* serial number */
 17.1945 -            FUNCTION_MSG("VPD_SERIAL_NUMBER\n");
 17.1946 -            data_buffer[0] = DIRECT_ACCESS_DEVICE;
 17.1947 -            data_buffer[1] = VPD_SERIAL_NUMBER;
 17.1948 -            data_buffer[2] = 0x00;
 17.1949 -            data_buffer[3] = 8;
 17.1950 -            memset(&data_buffer[4], ' ', 8);
 17.1951 -            data_transfer_length = 12;
 17.1952 -            break;
 17.1953 -          case VPD_DEVICE_IDENTIFIERS: /* identification - we don't support any so just return zero */
 17.1954 -            FUNCTION_MSG("VPD_DEVICE_IDENTIFIERS\n");
 17.1955 -            data_buffer[0] = DIRECT_ACCESS_DEVICE;
 17.1956 -            data_buffer[1] = VPD_DEVICE_IDENTIFIERS;
 17.1957 -            data_buffer[2] = 0x00;
 17.1958 -            data_buffer[3] = 4 + (UCHAR)strlen(xvdd->vectors.path); /* length */
 17.1959 -            data_buffer[4] = 2; /* ASCII */
 17.1960 -            data_buffer[5] = 1; /* VendorId */
 17.1961 -            data_buffer[6] = 0;
 17.1962 -            data_buffer[7] = (UCHAR)strlen(xvdd->vectors.path);
 17.1963 -            memcpy(&data_buffer[8], xvdd->vectors.path, strlen(xvdd->vectors.path));
 17.1964 -            data_transfer_length = (ULONG)(8 + strlen(xvdd->vectors.path));
 17.1965 -            break;
 17.1966 -          case VPD_BLOCK_LIMITS: /* to indicate support for UNMAP (TRIM/DISCARD) */
 17.1967 -            FUNCTION_MSG("VPD_BLOCK_LIMITS\n");
 17.1968 -            // max descriptors = 1
 17.1969 -            // max sectors = 0xFFFFFFFF
 17.1970 -            // granularity = from xenbus
 17.1971 -            // alignment = from xenbus(?)
 17.1972 -            srb_status = SRB_STATUS_ERROR;
 17.1973 -            break;
 17.1974 -          default:
 17.1975 -            FUNCTION_MSG("Unknown Page %02x requested\n", srb->Cdb[2]);
 17.1976 -            srb_status = SRB_STATUS_ERROR;
 17.1977 -            break;
 17.1978 -          }
 17.1979 -        }
 17.1980 -        break;
 17.1981 -      case XENVBD_DEVICETYPE_CDROM:
 17.1982 -        if ((srb->Cdb[1] & 1) == 0)
 17.1983 -        {
 17.1984 -          PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
 17.1985 -          id->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
 17.1986 -          id->RemovableMedia = 1;
 17.1987 -          id->Versions = 3;
 17.1988 -          id->ResponseDataFormat = 0;
 17.1989 -          id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
 17.1990 -          id->CommandQueue = 1;
 17.1991 -          memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
 17.1992 -          memcpy(id->ProductId, scsi_cdrom_model, 16); // product id
 17.1993 -          memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
 17.1994 -          data_transfer_length = sizeof(INQUIRYDATA);
 17.1995 -        }
 17.1996 -        else
 17.1997 -        {
 17.1998 -          switch (srb->Cdb[2])
 17.1999 -          {
 17.2000 -          case 0x00:
 17.2001 -            data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
 17.2002 -            data_buffer[1] = 0x00;
 17.2003 -            data_buffer[2] = 0x00;
 17.2004 -            data_buffer[3] = 2;
 17.2005 -            data_buffer[4] = 0x00;
 17.2006 -            data_buffer[5] = 0x80;
 17.2007 -            data_transfer_length = 6;
 17.2008 -            break;
 17.2009 -          case 0x80:
 17.2010 -            data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
 17.2011 -            data_buffer[1] = 0x80;
 17.2012 -            data_buffer[2] = 0x00;
 17.2013 -            data_buffer[3] = 8;
 17.2014 -            data_buffer[4] = 0x31;
 17.2015 -            data_buffer[5] = 0x32;
 17.2016 -            data_buffer[6] = 0x33;
 17.2017 -            data_buffer[7] = 0x34;
 17.2018 -            data_buffer[8] = 0x35;
 17.2019 -            data_buffer[9] = 0x36;
 17.2020 -            data_buffer[10] = 0x37;
 17.2021 -            data_buffer[11] = 0x38;
 17.2022 -            data_transfer_length = 12;
 17.2023 -            break;
 17.2024 -          default:
 17.2025 -            //KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", srb->Cdb[2]));
 17.2026 -            srb_status = SRB_STATUS_ERROR;
 17.2027 -            break;
 17.2028 -          }
 17.2029 -        }
 17.2030 -        break;
 17.2031 -      default:
 17.2032 -        //KdPrint((__DRIVER_NAME "     Unknown DeviceType %02x requested\n", xvdd->device_type));
 17.2033 -        srb_status = SRB_STATUS_ERROR;
 17.2034 -        break;
 17.2035 -      }
 17.2036 -      break;
 17.2037 -    case SCSIOP_READ_CAPACITY:
 17.2038 -      //if (dump_mode)
 17.2039 -        KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
 17.2040 -      //KdPrint((__DRIVER_NAME "       LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
 17.2041 -      //KdPrint((__DRIVER_NAME "       LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
 17.2042 -      //KdPrint((__DRIVER_NAME "       PMI = %d\n", srb->Cdb[8] & 1));
 17.2043 -      //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
 17.2044 -      data_buffer = srb->DataBuffer;
 17.2045 -      RtlZeroMemory(data_buffer, srb->DataTransferLength);
 17.2046 -      if ((xvdd->total_sectors - 1) >> 32)
 17.2047 -      {
 17.2048 -        data_buffer[0] = 0xff;
 17.2049 -        data_buffer[1] = 0xff;
 17.2050 -        data_buffer[2] = 0xff;
 17.2051 -        data_buffer[3] = 0xff;
 17.2052 -      }
 17.2053 -      else
 17.2054 -      {
 17.2055 -        data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
 17.2056 -        data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
 17.2057 -        data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
 17.2058 -        data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
 17.2059 -      }
 17.2060 -      data_buffer[4] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
 17.2061 -      data_buffer[5] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
 17.2062 -      data_buffer[6] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
 17.2063 -      data_buffer[7] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
 17.2064 -      data_transfer_length = 8;
 17.2065 -      srb->ScsiStatus = 0;
 17.2066 -      srb_status = SRB_STATUS_SUCCESS;
 17.2067 -      break;
 17.2068 -    case SCSIOP_READ_CAPACITY16:
 17.2069 -      //if (dump_mode)
 17.2070 -        KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY16\n"));
 17.2071 -      //KdPrint((__DRIVER_NAME "       LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
 17.2072 -      //KdPrint((__DRIVER_NAME "       LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
 17.2073 -      //KdPrint((__DRIVER_NAME "       PMI = %d\n", srb->Cdb[8] & 1));
 17.2074 -      data_buffer = srb->DataBuffer;
 17.2075 -      RtlZeroMemory(data_buffer, srb->DataTransferLength);
 17.2076 -      data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 56) & 0xff;
 17.2077 -      data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 48) & 0xff;
 17.2078 -      data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 40) & 0xff;
 17.2079 -      data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 32) & 0xff;
 17.2080 -      data_buffer[4] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
 17.2081 -      data_buffer[5] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
 17.2082 -      data_buffer[6] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
 17.2083 -      data_buffer[7] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
 17.2084 -      data_buffer[8] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
 17.2085 -      data_buffer[9] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
 17.2086 -      data_buffer[10] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
 17.2087 -      data_buffer[11] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
 17.2088 -      data_buffer[12] = 0;
 17.2089 -      switch (xvdd->hw_bytes_per_sector / xvdd->bytes_per_sector) {
 17.2090 -      case 1:
 17.2091 -        data_buffer[13] = 0; /* 512 byte hardware sectors */
 17.2092 -        break;
 17.2093 -      case 2:
 17.2094 -        data_buffer[13] = 1; /* 1024 byte hardware sectors */
 17.2095 -        break;
 17.2096 -      case 3:
 17.2097 -        data_buffer[13] = 2; /* 2048 byte hardware sectors */
 17.2098 -        break;
 17.2099 -      case 4:
 17.2100 -        data_buffer[13] = 3; /* 4096 byte hardware sectors */
 17.2101 -        break;
 17.2102 -      default:
 17.2103 -        data_buffer[13] = 0; /* 512 byte hardware sectors */
 17.2104 -        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));
 17.2105 -        break;
 17.2106 -      }
 17.2107 -      data_buffer[14] = 0xC0; //0;
 17.2108 -      data_buffer[15] = 0;
 17.2109 -      data_transfer_length = 16;
 17.2110 -      srb->ScsiStatus = 0;
 17.2111 -      srb_status = SRB_STATUS_SUCCESS;
 17.2112 -      break;
 17.2113 -    case SCSIOP_MODE_SENSE:
 17.2114 -    case SCSIOP_MODE_SENSE10:
 17.2115 -      if (dump_mode)
 17.2116 -        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));
 17.2117 -      data_transfer_length = XenVbd_FillModePage(xvdd, srb);
 17.2118 -      srb_status = SRB_STATUS_SUCCESS;
 17.2119 -      break;
 17.2120 -    case SCSIOP_READ:
 17.2121 -    case SCSIOP_READ16:
 17.2122 -    case SCSIOP_WRITE:
 17.2123 -    case SCSIOP_WRITE16:
 17.2124 -      //KdPrint((__DRIVER_NAME "     srb = %p\n", srb));  
 17.2125 -      XenVbd_PutSrbOnList(xvdd, srb);
 17.2126 -      XenVbd_PutQueuedSrbsOnRing(xvdd);
 17.2127 -      break;
 17.2128 -    case SCSIOP_WRITE_SAME:
 17.2129 -    case SCSIOP_WRITE_SAME16:
 17.2130 -      /* not yet supported */
 17.2131 -      FUNCTION_MSG("WRITE_SAME\n");
 17.2132 -      break;
 17.2133 -    case SCSIOP_UNMAP:
 17.2134 -      /* not yet supported */
 17.2135 -      FUNCTION_MSG("UNMAP\n");
 17.2136 -      break;
 17.2137 -    case SCSIOP_VERIFY:
 17.2138 -    case SCSIOP_VERIFY16:
 17.2139 -      // Should we do more here?
 17.2140 -      if (dump_mode)
 17.2141 -        KdPrint((__DRIVER_NAME "     Command = VERIFY\n"));
 17.2142 -      srb_status = SRB_STATUS_SUCCESS;
 17.2143 -      break;
 17.2144 -    case SCSIOP_REPORT_LUNS:
 17.2145 -      //if (dump_mode)
 17.2146 -        FUNCTION_MSG("Command = REPORT_LUNS\n");
 17.2147 -      switch (srb->Cdb[2]) {
 17.2148 -      case 1:
 17.2149 -        FUNCTION_MSG(" SELECT REPORT = %d\n", srb->Cdb[2] & 255);
 17.2150 -        break;
 17.2151 -      default:
 17.2152 -        FUNCTION_MSG(" SELECT REPORT = %d\n", srb->Cdb[2] & 255);
 17.2153 -        break;
 17.2154 -      }
 17.2155 -      FUNCTION_MSG(" ALLOCATION LENGTH = %d\n", (srb->Cdb[6] << 24)|(srb->Cdb[7] << 16)|(srb->Cdb[8] << 8)|(srb->Cdb[9]));
 17.2156 -      data_buffer = srb->DataBuffer;
 17.2157 -      RtlZeroMemory(data_buffer, srb->DataTransferLength);
 17.2158 -      data_buffer[3] = 8; /* 1 lun */
 17.2159 -      /* rest of the data is blank */
 17.2160 -      data_transfer_length = 16;
 17.2161 -      srb->ScsiStatus = 0;
 17.2162 -      srb_status = SRB_STATUS_SUCCESS;
 17.2163 -      break;
 17.2164 -    case SCSIOP_REQUEST_SENSE:
 17.2165 -      if (dump_mode)
 17.2166 -        KdPrint((__DRIVER_NAME "     Command = REQUEST_SENSE\n"));
 17.2167 -      data_transfer_length = XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
 17.2168 -      srb_status = SRB_STATUS_SUCCESS;
 17.2169 -      break;      
 17.2170 -    case SCSIOP_READ_TOC:
 17.2171 -      if (dump_mode)
 17.2172 -        KdPrint((__DRIVER_NAME "     Command = READ_TOC\n"));
 17.2173 -      data_buffer = srb->DataBuffer;
 17.2174 -/*
 17.2175 -#define READ_TOC_FORMAT_TOC         0x00
 17.2176 -#define READ_TOC_FORMAT_SESSION     0x01
 17.2177 -#define READ_TOC_FORMAT_FULL_TOC    0x02
 17.2178 -#define READ_TOC_FORMAT_PMA         0x03
 17.2179 -#define READ_TOC_FORMAT_ATIP        0x04
 17.2180 -*/
 17.2181 -//      KdPrint((__DRIVER_NAME "     Msf = %d\n", cdb->READ_TOC.Msf));
 17.2182 -//      KdPrint((__DRIVER_NAME "     LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
 17.2183 -//      KdPrint((__DRIVER_NAME "     Format2 = %d\n", cdb->READ_TOC.Format2));
 17.2184 -//      KdPrint((__DRIVER_NAME "     StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
 17.2185 -//      KdPrint((__DRIVER_NAME "     AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
 17.2186 -//      KdPrint((__DRIVER_NAME "     Control = %d\n", cdb->READ_TOC.Control));
 17.2187 -//      KdPrint((__DRIVER_NAME "     Format = %d\n", cdb->READ_TOC.Format));
 17.2188 -      switch (cdb->READ_TOC.Format2)
 17.2189 -      {
 17.2190 -      case READ_TOC_FORMAT_TOC:
 17.2191 -        data_buffer[0] = 0; // length MSB
 17.2192 -        data_buffer[1] = 10; // length LSB
 17.2193 -        data_buffer[2] = 1; // First Track
 17.2194 -        data_buffer[3] = 1; // Last Track
 17.2195 -        data_buffer[4] = 0; // Reserved
 17.2196 -        data_buffer[5] = 0x14; // current position data + uninterrupted data
 17.2197 -        data_buffer[6] = 1; // last complete track
 17.2198 -        data_buffer[7] = 0; // reserved
 17.2199 -        data_buffer[8] = 0; // MSB Block
 17.2200 -        data_buffer[9] = 0;
 17.2201 -        data_buffer[10] = 0;
 17.2202 -        data_buffer[11] = 0; // LSB Block
 17.2203 -        data_transfer_length = 12;
 17.2204 -        srb_status = SRB_STATUS_SUCCESS;
 17.2205 -        break;
 17.2206 -      case READ_TOC_FORMAT_SESSION:
 17.2207 -      case READ_TOC_FORMAT_FULL_TOC:
 17.2208 -      case READ_TOC_FORMAT_PMA:
 17.2209 -      case READ_TOC_FORMAT_ATIP:
 17.2210 -        srb_status = SRB_STATUS_ERROR;
 17.2211 -        break;
 17.2212 -      default:
 17.2213 -        srb_status = SRB_STATUS_ERROR;
 17.2214 -        break;
 17.2215 -      }
 17.2216 -      break;
 17.2217 -    case SCSIOP_START_STOP_UNIT:
 17.2218 -      KdPrint((__DRIVER_NAME "     Command = SCSIOP_START_STOP_UNIT\n"));
 17.2219 -      srb_status = SRB_STATUS_SUCCESS;
 17.2220 -      break;
 17.2221 -    case SCSIOP_RESERVE_UNIT:
 17.2222 -      KdPrint((__DRIVER_NAME "     Command = SCSIOP_RESERVE_UNIT\n"));
 17.2223 -      srb_status = SRB_STATUS_SUCCESS;
 17.2224 -      break;
 17.2225 -    case SCSIOP_RELEASE_UNIT:
 17.2226 -      KdPrint((__DRIVER_NAME "     Command = SCSIOP_RELEASE_UNIT\n"));
 17.2227 -      srb_status = SRB_STATUS_SUCCESS;
 17.2228 -      break;
 17.2229 -    default:
 17.2230 -      KdPrint((__DRIVER_NAME "     Unhandled EXECUTE_SCSI Command = %02X\n", srb->Cdb[0]));
 17.2231 -      xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
 17.2232 -      srb_status = SRB_STATUS_ERROR;
 17.2233 -      break;
 17.2234 -    }
 17.2235 -    if (srb_status == SRB_STATUS_ERROR)
 17.2236 -    {
 17.2237 -      KdPrint((__DRIVER_NAME "     EXECUTE_SCSI Command = %02X returned error %02x\n", srb->Cdb[0], xvdd->last_sense_key));
 17.2238 -      if (xvdd->last_sense_key == SCSI_SENSE_NO_SENSE)
 17.2239 -      {
 17.2240 -        xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
 17.2241 -        xvdd->last_additional_sense_code = SCSI_ADSENSE_INVALID_CDB;
 17.2242 -      }
 17.2243 -      srb->SrbStatus = srb_status;
 17.2244 -      srb->ScsiStatus = 0x02;
 17.2245 -      XenVbd_MakeAutoSense(xvdd, srb);
 17.2246 -      StorPortNotification(RequestComplete, DeviceExtension, srb);
 17.2247 -    }
 17.2248 -    else if (srb_status != SRB_STATUS_PENDING)
 17.2249 -    {
 17.2250 -      if (data_transfer_length > srb->DataTransferLength)
 17.2251 -        KdPrint((__DRIVER_NAME "     data_transfer_length too big - %d > %d\n", data_transfer_length, srb->DataTransferLength));
 17.2252 -      
 17.2253 -      if (srb_status == SRB_STATUS_SUCCESS && data_transfer_length < srb->DataTransferLength)
 17.2254 -      {
 17.2255 -        srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
 17.2256 -        srb->DataTransferLength = data_transfer_length;
 17.2257 -      }
 17.2258 -      else
 17.2259 -      {
 17.2260 -        srb->SrbStatus = srb_status;
 17.2261 -      }
 17.2262 -      xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
 17.2263 -      xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
 17.2264 -      StorPortNotification(RequestComplete, DeviceExtension, srb);
 17.2265 -    }
 17.2266 -    break;
 17.2267 -  case SRB_FUNCTION_IO_CONTROL:
 17.2268 -    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_IO_CONTROL\n"));
 17.2269 -    srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 17.2270 -    StorPortNotification(RequestComplete, DeviceExtension, srb);
 17.2271 -    break;
 17.2272 -  case SRB_FUNCTION_FLUSH:
 17.2273 -    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
 17.2274 -    srb->SrbStatus = SRB_STATUS_SUCCESS;
 17.2275 -    StorPortNotification(RequestComplete, DeviceExtension, srb);
 17.2276 -    break;
 17.2277 -  case SRB_FUNCTION_PNP:
 17.2278 -    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_PNP\n"));
 17.2279 -    sprb = (PSCSI_PNP_REQUEST_BLOCK)srb;
 17.2280 -    switch (sprb->PnPAction)
 17.2281 -    {
 17.2282 -    case StorStartDevice:
 17.2283 -      KdPrint((__DRIVER_NAME "      StorStartDevice\n"));
 17.2284 -      break;
 17.2285 -    case StorRemoveDevice:
 17.2286 -      KdPrint((__DRIVER_NAME "      StorRemoveDevice\n"));
 17.2287 -      break;
 17.2288 -    case StorStopDevice:
 17.2289 -      KdPrint((__DRIVER_NAME "      StorStopDevice\n"));
 17.2290 -      break;
 17.2291 -    case StorQueryCapabilities:
 17.2292 -      KdPrint((__DRIVER_NAME "      StorQueryCapabilities\n"));
 17.2293 -      break;
 17.2294 -    case StorFilterResourceRequirements:
 17.2295 -      KdPrint((__DRIVER_NAME "      StorFilterResourceRequirements\n"));
 17.2296 -      break;
 17.2297 -    default:
 17.2298 -      KdPrint((__DRIVER_NAME "      Stor%d\n", sprb->PnPAction));
 17.2299 -      break;
 17.2300 -    }
 17.2301 -    KdPrint((__DRIVER_NAME "      SrbPnPFlags = %08x\n", sprb->SrbPnPFlags));
 17.2302 -    srb->SrbStatus = SRB_STATUS_SUCCESS;
 17.2303 -    StorPortNotification(RequestComplete, DeviceExtension, srb);
 17.2304 -    break;
 17.2305 -    
 17.2306 -  case SRB_FUNCTION_POWER:
 17.2307 -    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_POWER\n"));
 17.2308 -    spwrb = (PSCSI_POWER_REQUEST_BLOCK)srb;
 17.2309 -    switch (spwrb->PowerAction)
 17.2310 -    {
 17.2311 -    case StorPowerActionNone:
 17.2312 -      KdPrint((__DRIVER_NAME "      StorPowerActionNone\n"));
 17.2313 -      break;
 17.2314 -    case StorPowerActionReserved:
 17.2315 -      KdPrint((__DRIVER_NAME "      StorPowerActionReserved\n"));
 17.2316 -      break;
 17.2317 -    case StorPowerActionSleep:
 17.2318 -      KdPrint((__DRIVER_NAME "      StorPowerActionSleep\n"));
 17.2319 -      break;
 17.2320 -    case StorPowerActionHibernate:
 17.2321 -      KdPrint((__DRIVER_NAME "      StorPowerActionHibernate\n"));
 17.2322 -      break;
 17.2323 -    case StorPowerActionShutdown:
 17.2324 -      KdPrint((__DRIVER_NAME "      StorPowerActionShutdown\n"));
 17.2325 -      break;
 17.2326 -    case StorPowerActionShutdownReset:
 17.2327 -      KdPrint((__DRIVER_NAME "      StorPowerActionShutdownReset\n"));
 17.2328 -      break;
 17.2329 -    case StorPowerActionShutdownOff:
 17.2330 -      KdPrint((__DRIVER_NAME "      StorPowerActionShutdownOff\n"));
 17.2331 -      break;
 17.2332 -    case StorPowerActionWarmEject:
 17.2333 -      KdPrint((__DRIVER_NAME "      StorPowerActionWarmEject\n"));
 17.2334 -      break;
 17.2335 -    default:
 17.2336 -      KdPrint((__DRIVER_NAME "      Stor%d\n", spwrb->PowerAction));
 17.2337 -      break;
 17.2338 -    }
 17.2339 -    XenVbd_PutSrbOnList(xvdd, srb);
 17.2340 -    XenVbd_PutQueuedSrbsOnRing(xvdd);
 17.2341 -    break;
 17.2342 -  case SRB_FUNCTION_DUMP_POINTERS:
 17.2343 -    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_DUMP_POINTERS\n"));
 17.2344 -    KdPrint((__DRIVER_NAME "     DataTransferLength = %d\n", srb->DataTransferLength));
 17.2345 -    dump_pointers = srb->DataBuffer;
 17.2346 -    KdPrint((__DRIVER_NAME "      Version = %d\n", dump_pointers->Version));
 17.2347 -    KdPrint((__DRIVER_NAME "      Size = %d\n", dump_pointers->Size));
 17.2348 -    KdPrint((__DRIVER_NAME "      DriverName = %S\n", dump_pointers->DriverName));
 17.2349 -    KdPrint((__DRIVER_NAME "      AdapterObject = %p\n", dump_pointers->AdapterObject));
 17.2350 -    KdPrint((__DRIVER_NAME "      MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
 17.2351 -    KdPrint((__DRIVER_NAME "      CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
 17.2352 -    KdPrint((__DRIVER_NAME "      MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
 17.2353 -    KdPrint((__DRIVER_NAME "      SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
 17.2354 -    KdPrint((__DRIVER_NAME "      AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
 17.2355 -    KdPrint((__DRIVER_NAME "      MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
 17.2356 -    KdPrint((__DRIVER_NAME "      NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
 17.2357 -    KdPrint((__DRIVER_NAME "      AlignmentMask = %d\n", dump_pointers->AlignmentMask));
 17.2358 -    KdPrint((__DRIVER_NAME "      NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
 17.2359 -    KdPrint((__DRIVER_NAME "      NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
 17.2360 -    KdPrint((__DRIVER_NAME "      Master = %d\n", dump_pointers->Master));
 17.2361 -    KdPrint((__DRIVER_NAME "      MapBuffers = %d\n", dump_pointers->MapBuffers));
 17.2362 -    KdPrint((__DRIVER_NAME "      MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
 17.2363 -
 17.2364 -    dump_pointers->Version = DUMP_MINIPORT_VERSION_1;
 17.2365 -    dump_pointers->Size = sizeof(MINIPORT_DUMP_POINTERS);
 17.2366 -    RtlStringCchCopyW(dump_pointers->DriverName, DUMP_MINIPORT_NAME_LENGTH, L"xenvbd.sys");
 17.2367 -    dump_pointers->AdapterObject = NULL;
 17.2368 -    dump_pointers->MappedRegisterBase = 0;
 17.2369 -    dump_pointers->CommonBufferSize = 0;
 17.2370 -    dump_pointers->MiniportPrivateDumpData = (PVOID)xvdd->device_base;
 17.2371 -    //dump_pointers->SystemIoBusNumber = 0;
 17.2372 -    dump_pointers->AdapterInterfaceType = Internal;
 17.2373 -    dump_pointers->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;;
 17.2374 -    dump_pointers->NumberOfPhysicalBreaks = dump_pointers->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
 17.2375 -    dump_pointers->AlignmentMask = 0;
 17.2376 -    dump_pointers->NumberOfAccessRanges = 1;
 17.2377 -    dump_pointers->NumberOfBuses = 1;
 17.2378 -    dump_pointers->Master = TRUE;
 17.2379 -    dump_pointers->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
 17.2380 -    dump_pointers->MaximumNumberOfTargets = 2;
 17.2381 -
 17.2382 -    KdPrint((__DRIVER_NAME "      Version = %d\n", dump_pointers->Version));
 17.2383 -    KdPrint((__DRIVER_NAME "      Size = %d\n", dump_pointers->Size));
 17.2384 -    //KdPrint((__DRIVER_NAME "      DriverName = %S\n", dump_pointers->DriverName));
 17.2385 -    KdPrint((__DRIVER_NAME "      AdapterObject = %p\n", dump_pointers->AdapterObject));
 17.2386 -    KdPrint((__DRIVER_NAME "      MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
 17.2387 -    KdPrint((__DRIVER_NAME "      CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
 17.2388 -    KdPrint((__DRIVER_NAME "      MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
 17.2389 -    KdPrint((__DRIVER_NAME "      SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
 17.2390 -    KdPrint((__DRIVER_NAME "      AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
 17.2391 -    KdPrint((__DRIVER_NAME "      MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
 17.2392 -    KdPrint((__DRIVER_NAME "      NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
 17.2393 -    KdPrint((__DRIVER_NAME "      AlignmentMask = %d\n", dump_pointers->AlignmentMask));
 17.2394 -    KdPrint((__DRIVER_NAME "      NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
 17.2395 -    KdPrint((__DRIVER_NAME "      NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
 17.2396 -    KdPrint((__DRIVER_NAME "      Master = %d\n", dump_pointers->Master));
 17.2397 -    KdPrint((__DRIVER_NAME "      MapBuffers = %d\n", dump_pointers->MapBuffers));
 17.2398 -    KdPrint((__DRIVER_NAME "      MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
 17.2399 -
 17.2400 -    srb->SrbStatus = SRB_STATUS_SUCCESS;
 17.2401 -    StorPortNotification(RequestComplete, DeviceExtension, srb);
 17.2402 -    break;
 17.2403 -  case SRB_FUNCTION_SHUTDOWN:
 17.2404 -    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_SHUTDOWN %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
 17.2405 -    //ASSERT(IsListEmpty(&xvdd->srb_list));
 17.2406 -    //ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
 17.2407 -    XenVbd_PutSrbOnList(xvdd, srb);
 17.2408 -    XenVbd_PutQueuedSrbsOnRing(xvdd);
 17.2409 -    //srb->SrbStatus = SRB_STATUS_SUCCESS;
 17.2410 -    //StorPortNotification(RequestComplete, DeviceExtension, srb);
 17.2411 -    break;
 17.2412 -  case SRB_FUNCTION_RESET_BUS:
 17.2413 -  case SRB_FUNCTION_RESET_DEVICE:
 17.2414 -  case SRB_FUNCTION_RESET_LOGICAL_UNIT:
 17.2415 -    /* the path doesn't matter here - only ever one device*/
 17.2416 -    XenVbd_HwStorResetBus(DeviceExtension, 0);
 17.2417 -    srb->SrbStatus = SRB_STATUS_SUCCESS;
 17.2418 -    StorPortNotification(RequestComplete, DeviceExtension, srb);    
 17.2419 -    break;
 17.2420 -  case SRB_FUNCTION_WMI:
 17.2421 -    srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 17.2422 -    StorPortNotification(RequestComplete, DeviceExtension, srb);
 17.2423 -    break;
 17.2424 -
 17.2425 -  default:
 17.2426 -    KdPrint((__DRIVER_NAME "     Unhandled srb->Function = %08X\n", srb->Function));
 17.2427 -    srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 17.2428 -    StorPortNotification(RequestComplete, DeviceExtension, srb);
 17.2429 -    break;
 17.2430 -  }
 17.2431 -
 17.2432 -  //if (dump_mode) FUNCTION_EXIT();
 17.2433 -  StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
 17.2434 +  XenVbd_PutSrbOnList(xvdd, srb);
 17.2435 +  XenVbd_ProcessSrbList(xvdd);
 17.2436 +  StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
 17.2437    return TRUE;
 17.2438  }
 17.2439  
 17.2440 @@ -1949,7 +1979,7 @@ XenVbd_HwStorAdapterControl(PVOID Device
 17.2441      break;
 17.2442    case ScsiStopAdapter:
 17.2443      KdPrint((__DRIVER_NAME "     ScsiStopAdapter\n"));
 17.2444 -    if (xvdd->inactive)
 17.2445 +    if (xvdd->vbd_status == VBD_STATUS_INACTIVE)
 17.2446      {
 17.2447        KdPrint((__DRIVER_NAME "     inactive - nothing to do\n"));
 17.2448        break;
 17.2449 @@ -1959,20 +1989,19 @@ XenVbd_HwStorAdapterControl(PVOID Device
 17.2450      break;
 17.2451    case ScsiRestartAdapter:
 17.2452      KdPrint((__DRIVER_NAME "     ScsiRestartAdapter\n"));
 17.2453 -    if (xvdd->inactive)
 17.2454 +    if (xvdd->vbd_status == VBD_STATUS_INACTIVE)
 17.2455      {
 17.2456        KdPrint((__DRIVER_NAME "     inactive - nothing to do\n"));
 17.2457        break;
 17.2458      }
 17.2459      /* increase the tag every time we stop/start to track where the gref's came from */
 17.2460      xvdd->grant_tag++;
 17.2461 +#if 0
 17.2462      if (XenVbd_InitFromConfig(xvdd) != SP_RETURN_FOUND) {
 17.2463        #pragma warning(suppress:28159)
 17.2464        KeBugCheckEx(DATA_COHERENCY_EXCEPTION, 0, (ULONG_PTR)xvdd, 0, 0);
 17.2465      }
 17.2466 -    xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED;
 17.2467 -    
 17.2468 -    //XenVbd_StartRingDetection(xvdd);
 17.2469 +#endif    
 17.2470      break;
 17.2471    case ScsiSetBootConfig:
 17.2472      KdPrint((__DRIVER_NAME "     ScsiSetBootConfig\n"));
 17.2473 @@ -2110,12 +2139,11 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
 17.2474      status = StorPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
 17.2475    }
 17.2476    
 17.2477 -  if(!NT_SUCCESS(status))
 17.2478 -  {
 17.2479 -    KdPrint((__DRIVER_NAME " ScsiPortInitialize failed with status 0x%08x\n", status));
 17.2480 +  if(!NT_SUCCESS(status)) {
 17.2481 +    FUNCTION_MSG("ScsiPortInitialize failed with status 0x%08x\n", status);
 17.2482    }
 17.2483  
 17.2484    FUNCTION_EXIT();
 17.2485  
 17.2486    return status;
 17.2487 -}
 17.2488 +}
 17.2489 \ No newline at end of file
    18.1 --- a/xenvbd/xenvbd_storport.h	Fri Dec 14 21:44:03 2012 +1100
    18.2 +++ b/xenvbd/xenvbd_storport.h	Sun Jan 06 14:08:22 2013 +1100
    18.3 @@ -126,28 +126,27 @@ typedef enum {
    18.4  /* if this is ever increased to more than 1 then we need a way of tracking it properly */
    18.5  #define DUMP_MODE_UNALIGNED_PAGES 1 /* only for unaligned buffer use */
    18.6  
    18.7 +#define VBD_STATUS_INITIALISING 0
    18.8 +#define VBD_STATUS_INACTIVE     1
    18.9 +#define VBD_STATUS_ACTIVE       2
   18.10 +
   18.11  struct
   18.12  {
   18.13 -  BOOLEAN inactive;
   18.14 -  
   18.15 +  ULONG vbd_status;
   18.16 +  STOR_DPC dpc;
   18.17    blkif_shadow_t shadows[MAX_SHADOW_ENTRIES];
   18.18    USHORT shadow_free_list[MAX_SHADOW_ENTRIES];
   18.19    USHORT shadow_free;
   18.20    USHORT shadow_min_free;
   18.21    ULONG grant_tag;
   18.22 -
   18.23 -  PUCHAR device_base;
   18.24 -
   18.25 -  blkif_sring_t *sring;
   18.26 +  PDEVICE_OBJECT pdo;
   18.27 +  XN_HANDLE handle;
   18.28    evtchn_port_t event_channel;
   18.29 -  ULONG *event_channel_ptr;
   18.30 -  union {
   18.31 -    blkif_front_ring_t ring;
   18.32 -    blkif_other_front_ring_t other_ring;
   18.33 -  };
   18.34 -  int ring_detect_state;
   18.35 -  BOOLEAN use_other;
   18.36 -  BOOLEAN cached_use_other;
   18.37 +  blkif_front_ring_t ring;
   18.38 +  blkif_sring_t *sring;
   18.39 +  grant_ref_t sring_gref; 
   18.40 +  ULONG backend_state;
   18.41 +  ULONG frontend_state;
   18.42    UCHAR last_sense_key;
   18.43    UCHAR last_additional_sense_code;
   18.44    blkif_response_t tmp_rep;
   18.45 @@ -156,8 +155,9 @@ struct
   18.46    ULONG bytes_per_sector; /* 512 for disk, 2048 for CDROM) */
   18.47    ULONG hw_bytes_per_sector; /* underlying hardware format, eg 4K */
   18.48    ULONGLONG total_sectors;
   18.49 -  XENPCI_VECTORS vectors;
   18.50 -  PXENPCI_DEVICE_STATE device_state;
   18.51 +  ULONG feature_flush_cache;
   18.52 +  ULONG feature_discard;
   18.53 +  ULONG feature_barrier;
   18.54    LIST_ENTRY srb_list;
   18.55    BOOLEAN aligned_buffer_in_use;
   18.56    ULONG aligned_buffer_size;