win-pvdrivers

changeset 284:4954c15a4921 wdm 0.9.3

misc fixes. Mainly multiple requests per lu in xenvbd
author James Harper <james.harper@bendigoit.com.au>
date Sat May 31 22:35:41 2008 +1000 (2008-05-31)
parents 3c65d6c6453f
children e11d7173c7be
files common.inc common/include/xen_guids.h target/uninstall.bat xenenum/makefile xenenum/makefile.inc xenenum/sources xenenum/xenenum.c xenenum/xenenum.h xenenum/xenenum.inx xennet/xennet.h xenpci/hypercall.h xenpci/xenpci.c xenpci/xenpci.h xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c xenscsi/xenscsi.inx xenvbd/scsiport.c xenvbd/xenvbd.c xenvbd/xenvbd.h
line diff
     1.1 --- a/common.inc	Tue May 27 22:46:06 2008 +1000
     1.2 +++ b/common.inc	Sat May 31 22:35:41 2008 +1000
     1.3 @@ -1,4 +1,4 @@
     1.4 -VERSION=0.9.2.0
     1.5 +VERSION=0.9.3.0
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7  MSC_WARNING_LEVEL=/W4
     1.8  INCLUDES = ..\common\include;..\common\include\public
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/common/include/xen_guids.h	Sat May 31 22:35:41 2008 +1000
     2.3 @@ -0,0 +1,26 @@
     2.4 +/*
     2.5 +PV Drivers for Windows Xen HVM Domains
     2.6 +Copyright (C) 2007 James Harper
     2.7 +
     2.8 +This program is free software; you can redistribute it and/or
     2.9 +modify it under the terms of the GNU General Public License
    2.10 +as published by the Free Software Foundation; either version 2
    2.11 +of the License, or (at your option) any later version.
    2.12 +
    2.13 +This program is distributed in the hope that it will be useful,
    2.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.16 +GNU General Public License for more details.
    2.17 +
    2.18 +You should have received a copy of the GNU General Public License
    2.19 +along with this program; if not, write to the Free Software
    2.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    2.21 +*/
    2.22 +
    2.23 +#if !defined(_XEN_GUIDS_H_)
    2.24 +#define _XEN_GUIDS_H_
    2.25 +
    2.26 +//{C828ABE9-14CA-4445-BAA6-82C2376C6518}
    2.27 +DEFINE_GUID(GUID_BUS_TYPE_XEN, 0xC828ABE9, 0x14CA, 0x4445, 0xBA, 0xA6, 0x82, 0xC2, 0x37, 0x6C, 0x65, 0x18);
    2.28 +
    2.29 +#endif
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/target/uninstall.bat	Sat May 31 22:35:41 2008 +1000
     3.3 @@ -0,0 +1,112 @@
     3.4 +@ECHO OFF
     3.5 +
     3.6 +ver | find " 5.00." > nul
     3.7 +if %ERRORLEVEL% == 0 goto ver_2k
     3.8 +
     3.9 +ver | find " 5.1." > nul
    3.10 +if %ERRORLEVEL% == 0 goto ver_xp
    3.11 +
    3.12 +ver | find " 5.2." > nul
    3.13 +if %ERRORLEVEL% == 0 goto ver_2k3
    3.14 +
    3.15 +ver | find " 6.0." > nul
    3.16 +if %ERRORLEVEL% == 0 goto ver_2k8
    3.17 +
    3.18 +echo No automatic uninstall available or machine not supported.
    3.19 +goto exit
    3.20 +
    3.21 +:ver_xp
    3.22 +echo Windows XP Detected... Uninstalling...
    3.23 +shutdownmon -u
    3.24 +cd winxp
    3.25 +copy /y ..\common\i386\dpinst.exe . >nul
    3.26 +dpinst.exe /U xennet.inf
    3.27 +dpinst.exe /U xenenum.inf
    3.28 +dpinst.exe /U xenscsi.inf
    3.29 +dpinst.exe /U xenvbd.inf
    3.30 +dpinst.exe /U xenstub.inf
    3.31 +dpinst.exe /U xenpci.inf
    3.32 +cd ..
    3.33 +echo Done
    3.34 +goto exit
    3.35 +
    3.36 +:ver_2k
    3.37 +echo Windows 2000 Detected... Uninstalling...
    3.38 +shutdownmon -u
    3.39 +cd win2k
    3.40 +copy /y ..\common\i386\dpinst.exe . >nul
    3.41 +dpinst.exe /U xennet.inf
    3.42 +dpinst.exe /U xenenum.inf
    3.43 +dpinst.exe /U xenscsi.inf
    3.44 +dpinst.exe /U xenvbd.inf
    3.45 +dpinst.exe /U xenstub.inf
    3.46 +dpinst.exe /U xenpci.inf
    3.47 +cd ..
    3.48 +echo Done
    3.49 +goto exit
    3.50 +
    3.51 +
    3.52 +:ver_2k3
    3.53 +if %PROCESSOR_ARCHITECTURE% == AMD64 goto ver_2k3_amd64
    3.54 +echo Windows 2003 (i386) Detected... Uninstalling...
    3.55 +shutdownmon -u
    3.56 +cd winnet
    3.57 +copy /y ..\common\i386\dpinst.exe . >nul
    3.58 +dpinst.exe /U xennet.inf
    3.59 +dpinst.exe /U xenenum.inf
    3.60 +dpinst.exe /U xenscsi.inf
    3.61 +dpinst.exe /U xenvbd.inf
    3.62 +dpinst.exe /U xenstub.inf
    3.63 +dpinst.exe /U xenpci.inf
    3.64 +cd ..
    3.65 +echo Done
    3.66 +goto exit
    3.67 +
    3.68 +:ver_2k3_amd64
    3.69 +echo Windows 2003 (amd64) Detected... Uninstalling...
    3.70 +shutdownmon -u
    3.71 +cd winnet
    3.72 +copy /y ..\common\amd64\dpinst.exe . >nul
    3.73 +dpinst.exe /U xennet.inf
    3.74 +dpinst.exe /U xenenum.inf
    3.75 +dpinst.exe /U xenscsi.inf
    3.76 +dpinst.exe /U xenvbd.inf
    3.77 +dpinst.exe /U xenstub.inf
    3.78 +dpinst.exe /U xenpci.inf
    3.79 +cd ..
    3.80 +echo Done
    3.81 +goto exit
    3.82 +
    3.83 +:ver_2k8
    3.84 +if %PROCESSOR_ARCHITECTURE% == AMD64 goto ver_2k8_amd64
    3.85 +echo Windows Vista/2008 (i386) Detected... Uninstalling...
    3.86 +shutdownmon -u
    3.87 +cd winlh
    3.88 +copy /y ..\common\i386\dpinst.exe . >nul
    3.89 +dpinst.exe /U xennet.inf
    3.90 +dpinst.exe /U xenenum.inf
    3.91 +dpinst.exe /U xenscsi.inf
    3.92 +dpinst.exe /U xenvbd.inf
    3.93 +dpinst.exe /U xenstub.inf
    3.94 +dpinst.exe /U xenpci.inf
    3.95 +cd ..
    3.96 +echo Done
    3.97 +goto exit
    3.98 +
    3.99 +:ver_2k8_amd64
   3.100 +echo Windows Vista/2008 (amd64) Detected... Uninstalling...
   3.101 +shutdownmon -u
   3.102 +cd winlh
   3.103 +copy /y ..\common\amd64\dpinst.exe . >nul
   3.104 +dpinst.exe /U xennet.inf
   3.105 +dpinst.exe /U xenenum.inf
   3.106 +dpinst.exe /U xenscsi.inf
   3.107 +dpinst.exe /U xenvbd.inf
   3.108 +dpinst.exe /U xenstub.inf
   3.109 +dpinst.exe /U xenpci.inf
   3.110 +cd ..
   3.111 +echo Done
   3.112 +goto exit
   3.113 +
   3.114 +pause
   3.115 +:exit
   3.116 \ No newline at end of file
     4.1 --- a/xenenum/makefile	Tue May 27 22:46:06 2008 +1000
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,1 +0,0 @@
     4.4 -!INCLUDE $(NTMAKEENV)\makefile.def
     4.5 \ No newline at end of file
     5.1 --- a/xenenum/makefile.inc	Tue May 27 22:46:06 2008 +1000
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,6 +0,0 @@
     5.4 -_LNG=$(LANGUAGE)
     5.5 -STAMP=stampinf -f $@ -a $(_BUILDARCH) -d * -k $(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR) -v $(VERSION)
     5.6 -
     5.7 -..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf: $(INF_NAME).inx sources ..\common.inc
     5.8 -    copy $(@B).inx $@
     5.9 -    $(STAMP)
     6.1 --- a/xenenum/sources	Tue May 27 22:46:06 2008 +1000
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,6 +0,0 @@
     6.4 -!include "..\common.inc"
     6.5 -TARGETNAME=xenenum
     6.6 -TARGETTYPE=DRIVER
     6.7 -INF_NAME=$(TARGETNAME)
     6.8 -MISCFILES=..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf
     6.9 -SOURCES=xenenum.c
     7.1 --- a/xenenum/xenenum.c	Tue May 27 22:46:06 2008 +1000
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,484 +0,0 @@
     7.4 -#include "xenenum.h"
     7.5 -#include <io/blkif.h>
     7.6 -#include <srb.h>
     7.7 -#include <scsi.h>
     7.8 -#include <ntddscsi.h>
     7.9 -#include <ntdddisk.h>
    7.10 -#include <stdlib.h>
    7.11 -#include <xen_public.h>
    7.12 -#include <io/xenbus.h>
    7.13 -#include <ntddft.h>
    7.14 -
    7.15 -#define wmb() KeMemoryBarrier()
    7.16 -#define mb() KeMemoryBarrier()
    7.17 -
    7.18 -DRIVER_INITIALIZE DriverEntry;
    7.19 -
    7.20 -static NTSTATUS
    7.21 -XenEnum_AddDevice(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit);
    7.22 -static NTSTATUS
    7.23 -XenEnum_PrepareHardware(WDFDEVICE hDevice, WDFCMRESLIST Resources, WDFCMRESLIST ResourcesTranslated);
    7.24 -static NTSTATUS
    7.25 -XenEnum_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated);
    7.26 -static NTSTATUS
    7.27 -XenEnum_D0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
    7.28 -static NTSTATUS
    7.29 -XenEnum_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
    7.30 -static NTSTATUS
    7.31 -XenEnum_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState);
    7.32 -static NTSTATUS
    7.33 -XenEnum_DeviceUsageNotification(WDFDEVICE Device, WDF_SPECIAL_FILE_TYPE NotificationType, BOOLEAN IsInNotificationPath);
    7.34 -
    7.35 -static NTSTATUS
    7.36 -XenEnum_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit);
    7.37 -
    7.38 -static VOID
    7.39 -XenEnum_WatchHandler(char *Path, PVOID Data);
    7.40 -
    7.41 -#ifdef ALLOC_PRAGMA
    7.42 -#pragma alloc_text (INIT, DriverEntry)
    7.43 -#pragma alloc_text (PAGE, XenEnum_AddDevice)
    7.44 -#endif
    7.45 -
    7.46 -typedef struct {
    7.47 -  LIST_ENTRY DeviceListHead;
    7.48 -  XEN_IFACE XenInterface;
    7.49 -  PDEVICE_OBJECT Pdo;
    7.50 -  BOOLEAN AutoEnumerate;
    7.51 -  KGUARDED_MUTEX WatchHandlerMutex;
    7.52 -} XENENUM_DEVICE_DATA, *PXENENUM_DEVICE_DATA;
    7.53 -
    7.54 -WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENENUM_DEVICE_DATA, GetDeviceData);
    7.55 -
    7.56 -NTSTATUS
    7.57 -DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
    7.58 -{
    7.59 -  WDF_DRIVER_CONFIG config;
    7.60 -  ULONG status;
    7.61 -
    7.62 -  KdPrint((__DRIVER_NAME " --> DriverEntry\n"));
    7.63 -
    7.64 -  WDF_DRIVER_CONFIG_INIT(&config, XenEnum_AddDevice);
    7.65 -  status = WdfDriverCreate(
    7.66 -                      DriverObject,
    7.67 -                      RegistryPath,
    7.68 -                      WDF_NO_OBJECT_ATTRIBUTES,
    7.69 -                      &config,
    7.70 -                      WDF_NO_HANDLE);
    7.71 -  if(!NT_SUCCESS(status))
    7.72 -  {
    7.73 -    KdPrint((__DRIVER_NAME " WdfDriverCreate failed with status 0x%08x\n", status));
    7.74 -  }
    7.75 -
    7.76 -  KdPrint((__DRIVER_NAME " <-- DriverEntry\n"));
    7.77 -
    7.78 -  return status;
    7.79 -}
    7.80 -
    7.81 -DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC828ABE9, 0x14CA, 0x4445, 0xBA, 0xA6, 0x82, 0xC2, 0x37, 0x6C, 0x65, 0x18);
    7.82 -
    7.83 -static NTSTATUS
    7.84 -XenEnum_AddDevice(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit)
    7.85 -{
    7.86 -  WDF_CHILD_LIST_CONFIG ChildListConfig;
    7.87 -  NTSTATUS status;
    7.88 -  WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
    7.89 -  PNP_BUS_INFORMATION BusInfo;
    7.90 -  WDFDEVICE Device;
    7.91 -  WDF_OBJECT_ATTRIBUTES attributes;
    7.92 -  PXENENUM_DEVICE_DATA xedd;
    7.93 -  PDEVICE_OBJECT Pdo;
    7.94 -  
    7.95 -  UNREFERENCED_PARAMETER(Driver);
    7.96 -
    7.97 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    7.98 -
    7.99 -  Pdo = WdfFdoInitWdmGetPhysicalDevice(DeviceInit);
   7.100 -
   7.101 -  WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
   7.102 -  WDF_CHILD_LIST_CONFIG_INIT(&ChildListConfig, sizeof(XENPCI_IDENTIFICATION_DESCRIPTION), XenEnum_ChildListCreateDevice);
   7.103 -  WdfFdoInitSetDefaultChildListConfig(DeviceInit, &ChildListConfig, WDF_NO_OBJECT_ATTRIBUTES);
   7.104 -  WdfDeviceInitSetExclusive(DeviceInit, FALSE);
   7.105 -
   7.106 -  WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
   7.107 -  pnpPowerCallbacks.EvtDevicePrepareHardware = XenEnum_PrepareHardware;
   7.108 -  pnpPowerCallbacks.EvtDeviceReleaseHardware = XenEnum_ReleaseHardware;
   7.109 -  pnpPowerCallbacks.EvtDeviceD0Entry = XenEnum_D0Entry;
   7.110 -  pnpPowerCallbacks.EvtDeviceD0EntryPostInterruptsEnabled = XenEnum_D0EntryPostInterruptsEnabled;
   7.111 -  pnpPowerCallbacks.EvtDeviceD0Exit = XenEnum_D0Exit;
   7.112 -  pnpPowerCallbacks.EvtDeviceUsageNotification = XenEnum_DeviceUsageNotification;
   7.113 -  WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
   7.114 -
   7.115 -  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, XENENUM_DEVICE_DATA);
   7.116 -
   7.117 -  status = WdfDeviceCreate(&DeviceInit, &attributes, &Device);
   7.118 -  if(!NT_SUCCESS(status))
   7.119 -  {
   7.120 -    KdPrint((__DRIVER_NAME "WdfDeviceCreate failed with status 0x%08x\n", status));
   7.121 -    return status;
   7.122 -  }
   7.123 -
   7.124 -  xedd = GetDeviceData(Device);
   7.125 -
   7.126 -#if (NTDDI_VERSION >= NTDDI_WS03SP1)
   7.127 -  KeInitializeGuardedMutex(&xedd->WatchHandlerMutex);
   7.128 -#endif
   7.129 -
   7.130 -  xedd->Pdo = Pdo;
   7.131 -
   7.132 -  BusInfo.BusTypeGuid = GUID_XENPCI_DEVCLASS;
   7.133 -  BusInfo.LegacyBusType = Internal;
   7.134 -  BusInfo.BusNumber = 0;
   7.135 -
   7.136 -  WdfDeviceSetBusInformationForChildren(Device, &BusInfo);
   7.137 -
   7.138 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   7.139 -  return status;
   7.140 -}
   7.141 -
   7.142 -static NTSTATUS
   7.143 -XenEnum_PrepareHardware(
   7.144 -  IN WDFDEVICE    Device,
   7.145 -  IN WDFCMRESLIST ResourceList,
   7.146 -  IN WDFCMRESLIST ResourceListTranslated)
   7.147 -{
   7.148 -  NTSTATUS status = STATUS_SUCCESS;
   7.149 -  PXENENUM_DEVICE_DATA xedd = GetDeviceData(Device);
   7.150 -
   7.151 -  UNREFERENCED_PARAMETER(ResourceList);
   7.152 -  UNREFERENCED_PARAMETER(ResourceListTranslated);
   7.153 -
   7.154 -  KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware\n"));
   7.155 -
   7.156 -  status = WdfFdoQueryForInterface(Device, &GUID_XEN_IFACE, (PINTERFACE)&xedd->XenInterface, sizeof(XEN_IFACE), 2, NULL);
   7.157 -  if(!NT_SUCCESS(status))
   7.158 -  {
   7.159 -    KdPrint((__DRIVER_NAME "     WdfFdoQueryForInterface (EvtChn) failed with status 0x%08x\n", status));
   7.160 -  }
   7.161 -
   7.162 -  InitializeListHead(&xedd->DeviceListHead);
   7.163 -
   7.164 -  KdPrint((__DRIVER_NAME " <-- EvtDevicePrepareHardware\n"));
   7.165 -
   7.166 -  return status;
   7.167 -}
   7.168 -
   7.169 -static NTSTATUS
   7.170 -XenEnum_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated)
   7.171 -{
   7.172 -  UNREFERENCED_PARAMETER(Device);
   7.173 -  UNREFERENCED_PARAMETER(ResourcesTranslated);
   7.174 -
   7.175 -  // release interfaces here...
   7.176 -
   7.177 -  return STATUS_SUCCESS;
   7.178 -}
   7.179 -
   7.180 -static NTSTATUS
   7.181 -XenEnum_D0Entry(
   7.182 -    IN WDFDEVICE  Device,
   7.183 -    IN WDF_POWER_DEVICE_STATE PreviousState
   7.184 -    )
   7.185 -{
   7.186 -  NTSTATUS status = STATUS_SUCCESS;
   7.187 -
   7.188 -  UNREFERENCED_PARAMETER(Device);
   7.189 -  UNREFERENCED_PARAMETER(PreviousState);
   7.190 -
   7.191 -  //KdPrint((__DRIVER_NAME " --> EvtDeviceD0Entry\n"));
   7.192 -
   7.193 -  //KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Entry\n"));
   7.194 -
   7.195 -  return status;
   7.196 -}
   7.197 -
   7.198 -static NTSTATUS
   7.199 -XenEnum_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState)
   7.200 -{
   7.201 -  NTSTATUS status = STATUS_SUCCESS;
   7.202 -  PXENPCI_XEN_DEVICE_DATA PdoDeviceData;
   7.203 -  char **Devices;
   7.204 -  char *msg;
   7.205 -  char buffer[128];
   7.206 -  int i;
   7.207 -  PXENENUM_DEVICE_DATA xedd = GetDeviceData(Device);
   7.208 -
   7.209 -  UNREFERENCED_PARAMETER(Device);
   7.210 -  UNREFERENCED_PARAMETER(PreviousState);
   7.211 -
   7.212 -  KdPrint((__DRIVER_NAME " --> EvtDeviceD0EntryPostInterruptsEnabled\n"));
   7.213 -
   7.214 -  PdoDeviceData = (PXENPCI_XEN_DEVICE_DATA)xedd->Pdo->DeviceExtension; //GetXenDeviceData(Device);
   7.215 -
   7.216 -  //KdPrint((__DRIVER_NAME "     Path = %s\n", PdoDeviceData->Path));
   7.217 -  PdoDeviceData->WatchHandler = XenEnum_WatchHandler;
   7.218 -  PdoDeviceData->WatchContext = Device;
   7.219 -  xedd->AutoEnumerate = PdoDeviceData->AutoEnumerate;
   7.220 -
   7.221 -  if (xedd->AutoEnumerate)
   7.222 -  {
   7.223 -    // TODO: Should probably do this in an EvtChildListScanForChildren
   7.224 -    msg = xedd->XenInterface.XenBus_List(xedd->XenInterface.InterfaceHeader.Context, XBT_NIL, PdoDeviceData->Path, &Devices);
   7.225 -    if (!msg)
   7.226 -    {
   7.227 -      for (i = 0; Devices[i]; i++)
   7.228 -      {
   7.229 -        KdPrint((__DRIVER_NAME "     found existing device %s\n", Devices[i]));
   7.230 -        KdPrint((__DRIVER_NAME "     faking watch event for %s/%s", PdoDeviceData->Path, Devices[i]));
   7.231 -        RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "%s/%s", PdoDeviceData->Path, Devices[i]);
   7.232 -        XenEnum_WatchHandler(buffer, Device);
   7.233 -        //ExFreePoolWithTag(Devices[i], XENPCI_POOL_TAG);
   7.234 -      }
   7.235 -    }
   7.236 -  }
   7.237 -
   7.238 -  KdPrint((__DRIVER_NAME " <-- EvtDeviceD0EntryPostInterruptsEnabled\n"));
   7.239 -
   7.240 -  return status;
   7.241 -}
   7.242 -
   7.243 -static NTSTATUS
   7.244 -XenEnum_D0Exit(
   7.245 -    IN WDFDEVICE Device,
   7.246 -    IN WDF_POWER_DEVICE_STATE  TargetState
   7.247 -    )
   7.248 -{
   7.249 -  NTSTATUS status = STATUS_SUCCESS;
   7.250 -  //char *response;
   7.251 -
   7.252 -  UNREFERENCED_PARAMETER(Device);
   7.253 -  UNREFERENCED_PARAMETER(TargetState);
   7.254 -
   7.255 -  //KdPrint((__DRIVER_NAME " --> EvtDeviceD0Exit\n"));
   7.256 -
   7.257 -  //response = XenBusInterface.RemWatch(XBT_NIL, XenBusInterface.InterfaceHeader.Context, XenEnum_WatchHandler, NULL);
   7.258 -
   7.259 -  //KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Exit\n"));
   7.260 -
   7.261 -  return status;
   7.262 -}
   7.263 -
   7.264 -static NTSTATUS
   7.265 -XenEnum_DeviceUsageNotification(WDFDEVICE Device, WDF_SPECIAL_FILE_TYPE NotificationType, BOOLEAN IsInNotificationPath)
   7.266 -{
   7.267 -  UNREFERENCED_PARAMETER(Device);
   7.268 -  UNREFERENCED_PARAMETER(IsInNotificationPath);
   7.269 -
   7.270 -  KdPrint((__DRIVER_NAME " --> DeviceUsageNotification\n"));
   7.271 -
   7.272 -  switch (NotificationType)
   7.273 -  {
   7.274 -  case WdfSpecialFilePaging:
   7.275 -    KdPrint((__DRIVER_NAME "     NotificationType = WdfSpecialFilePaging, Using = %d\n", IsInNotificationPath));
   7.276 -    break;
   7.277 -  case WdfSpecialFileHibernation:
   7.278 -    KdPrint((__DRIVER_NAME "     NotificationType = WdfSpecialFileHibernation, Using = %d\n", IsInNotificationPath));
   7.279 -    break;
   7.280 -  case WdfSpecialFileDump:
   7.281 -    KdPrint((__DRIVER_NAME "     NotificationType = WdfSpecialFileDump, Using = %d\n", IsInNotificationPath));
   7.282 -    break;
   7.283 -  default:
   7.284 -    KdPrint((__DRIVER_NAME "     NotificationType = %d, Using = %d\n", NotificationType, IsInNotificationPath));
   7.285 -    break;
   7.286 -  }
   7.287 -  KdPrint((__DRIVER_NAME " <-- DeviceUsageNotification\n"));
   7.288 -
   7.289 -  return TRUE;
   7.290 -}
   7.291 -
   7.292 -static VOID 
   7.293 -XenEnum_IoDefault(
   7.294 -    IN WDFQUEUE  Queue,
   7.295 -    IN WDFREQUEST  Request
   7.296 -    )
   7.297 -{
   7.298 -  UNREFERENCED_PARAMETER(Queue);
   7.299 -
   7.300 -  //KdPrint((__DRIVER_NAME " --> EvtDeviceIoDefault\n"));
   7.301 -
   7.302 -  WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
   7.303 -
   7.304 -  //KdPrint((__DRIVER_NAME " <-- EvtDeviceIoDefault\n"));
   7.305 -}
   7.306 -
   7.307 -static VOID
   7.308 -XenEnum_WatchHandler(char *Path, PVOID Data)
   7.309 -{
   7.310 -  NTSTATUS Status;
   7.311 -  XENPCI_IDENTIFICATION_DESCRIPTION IdentificationDescription;
   7.312 -  char **Bits;
   7.313 -  int Count;
   7.314 -  WDFCHILDLIST ChildList;
   7.315 -  WDFDEVICE Device = Data;
   7.316 -  WDF_CHILD_LIST_ITERATOR ChildIterator;
   7.317 -  WDFDEVICE ChildDevice;
   7.318 -  PXENPCI_XEN_DEVICE_DATA ChildDeviceData;
   7.319 -// we only use this if we have guarded mutexes available
   7.320 -#if (NTDDI_VERSION >= NTDDI_WS03SP1)
   7.321 -  PXENENUM_DEVICE_DATA xedd = GetDeviceData(Device);
   7.322 -#endif
   7.323 -
   7.324 -  UNREFERENCED_PARAMETER(Data);  
   7.325 -
   7.326 -  KdPrint((__DRIVER_NAME " --> WatchHandler\n"));
   7.327 -
   7.328 -#if (NTDDI_VERSION >= NTDDI_WS03SP1)
   7.329 -  KeAcquireGuardedMutex(&xedd->WatchHandlerMutex);
   7.330 -#endif
   7.331 -
   7.332 -  KdPrint((__DRIVER_NAME "     Path = %s\n", Path));
   7.333 -
   7.334 -  Bits = SplitString(Path, '/', 4, &Count);
   7.335 -  if (Count == 3)
   7.336 -  {
   7.337 -    KdPrint((__DRIVER_NAME "     Creating %s\n", Bits[2]));
   7.338 -    ChildList = WdfFdoGetDefaultChildList(Device);
   7.339 -    RtlZeroMemory(&IdentificationDescription, sizeof(IdentificationDescription));
   7.340 -    WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&IdentificationDescription.Header, sizeof(IdentificationDescription));
   7.341 -    strncpy(IdentificationDescription.Path, Path, 128);
   7.342 -    strncpy(IdentificationDescription.DeviceType, Bits[1], 128);
   7.343 -    strncat(IdentificationDescription.DeviceType, "dev", 128);
   7.344 -/*
   7.345 -    RtlInitAnsiString(&AnsiBuf, Bits[1]);
   7.346 -    RtlAnsiStringToUnicodeString(&IdentificationDescription.DeviceType, &AnsiBuf, TRUE);
   7.347 -*/
   7.348 -    IdentificationDescription.DeviceIndex = atoi(Bits[2]);
   7.349 -    Status = WdfChildListAddOrUpdateChildDescriptionAsPresent(ChildList, &IdentificationDescription.Header, NULL);
   7.350 -  }
   7.351 -  else if (Count > 3)
   7.352 -  {
   7.353 -    WDF_CHILD_LIST_ITERATOR_INIT(&ChildIterator, WdfRetrievePresentChildren);
   7.354 -    ChildList = WdfFdoGetDefaultChildList(Device);
   7.355 -    WdfChildListBeginIteration(ChildList, &ChildIterator);
   7.356 -    while (NT_SUCCESS(WdfChildListRetrieveNextDevice(ChildList, &ChildIterator, &ChildDevice, NULL)))
   7.357 -    {
   7.358 -      ChildDeviceData = GetXenDeviceData(ChildDevice);
   7.359 -      if (!ChildDeviceData)
   7.360 -      {
   7.361 -        KdPrint((__FUNCTION__ " No child device data, should never happen\n"));
   7.362 -        continue;
   7.363 -      }
   7.364 -      if (strncmp(ChildDeviceData->Path, Path, strlen(ChildDeviceData->Path)) == 0 && Path[strlen(ChildDeviceData->Path)] == '/')
   7.365 -      {
   7.366 -        KdPrint((__DRIVER_NAME "     Child Path = %s (Match - WatchHandler = %08x)\n", ChildDeviceData->Path, ChildDeviceData->WatchHandler));
   7.367 -        if (ChildDeviceData->WatchHandler != NULL)
   7.368 -          ChildDeviceData->WatchHandler(Path, ChildDeviceData->WatchContext);
   7.369 -      }
   7.370 -      else
   7.371 -      {
   7.372 -        //KdPrint((__DRIVER_NAME "     Child Path = %s (No Match)\n", ChildDeviceData->Path));
   7.373 -      }
   7.374 -    }
   7.375 -    WdfChildListEndIteration(ChildList, &ChildIterator);
   7.376 -  }
   7.377 -  FreeSplitString(Bits, Count);
   7.378 -
   7.379 -#if (NTDDI_VERSION >= NTDDI_WS03SP1)
   7.380 -  KeReleaseGuardedMutex(&xedd->WatchHandlerMutex);
   7.381 -#endif
   7.382 -
   7.383 -  KdPrint((__DRIVER_NAME " <-- WatchHandler\n"));  
   7.384 -
   7.385 -  return;
   7.386 -}
   7.387 -
   7.388 -static NTSTATUS
   7.389 -XenEnum_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit)
   7.390 -{
   7.391 -  NTSTATUS status;
   7.392 -  WDFDEVICE ChildDevice;
   7.393 -  PXENPCI_IDENTIFICATION_DESCRIPTION XenIdentificationDesc;
   7.394 -  DECLARE_UNICODE_STRING_SIZE(buffer, 50);
   7.395 -  WDF_OBJECT_ATTRIBUTES PdoAttributes;
   7.396 -  DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
   7.397 -  PXENPCI_XEN_DEVICE_DATA ChildDeviceData = NULL;
   7.398 -  WDF_QUERY_INTERFACE_CONFIG  qiConfig;
   7.399 -  PXENENUM_DEVICE_DATA xedd = GetDeviceData(WdfChildListGetDevice(ChildList));
   7.400 -  UNICODE_STRING DeviceType;
   7.401 -  ANSI_STRING AnsiBuf;
   7.402 -
   7.403 -  UNREFERENCED_PARAMETER(ChildList);
   7.404 -
   7.405 -  KdPrint((__DRIVER_NAME " --> ChildListCreateDevice\n"));
   7.406 -
   7.407 -  XenIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENPCI_IDENTIFICATION_DESCRIPTION, Header);
   7.408 -
   7.409 -  RtlInitAnsiString(&AnsiBuf, XenIdentificationDesc->DeviceType);
   7.410 -  RtlAnsiStringToUnicodeString(&DeviceType, &AnsiBuf, TRUE);
   7.411 -
   7.412 -  WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_UNKNOWN);
   7.413 -
   7.414 -  status = RtlUnicodeStringPrintf(&buffer, L"XEN\\%wZ\0", &DeviceType);
   7.415 -
   7.416 -  KdPrint((__DRIVER_NAME "     %ws", buffer.Buffer));
   7.417 -
   7.418 -  status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
   7.419 -  status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
   7.420 -  status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
   7.421 -
   7.422 -  status = RtlUnicodeStringPrintf(&buffer, L"%02d\0", XenIdentificationDesc->DeviceIndex);
   7.423 -  status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
   7.424 -
   7.425 -  status = RtlUnicodeStringPrintf(&buffer, L"Xen %wZ Device (%d)", &DeviceType, XenIdentificationDesc->DeviceIndex);
   7.426 -  status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
   7.427 -  WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
   7.428 -
   7.429 -  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&PdoAttributes, XENPCI_XEN_DEVICE_DATA);
   7.430 -
   7.431 -  status = WdfDeviceCreate(&ChildInit, &PdoAttributes, &ChildDevice);
   7.432 -  if (!NT_SUCCESS(status))
   7.433 -  {
   7.434 -    KdPrint((__DRIVER_NAME "     WdfDeviceCreate status = %08X\n", status));
   7.435 -  }
   7.436 -
   7.437 -  WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFilePaging, TRUE);
   7.438 -  WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileHibernation, TRUE);
   7.439 -  WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileDump, TRUE);
   7.440 -
   7.441 -  ChildDeviceData = GetXenDeviceData(ChildDevice);
   7.442 -  ChildDeviceData->Magic = XEN_DATA_MAGIC;
   7.443 -  ChildDeviceData->AutoEnumerate = xedd->AutoEnumerate;
   7.444 -  ChildDeviceData->WatchHandler = NULL;
   7.445 -  strncpy(ChildDeviceData->Path, XenIdentificationDesc->Path, 128);
   7.446 -  
   7.447 -  ChildDeviceData->XenInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->XenInterface);
   7.448 -  ChildDeviceData->XenInterface.InterfaceHeader.Version = 2;
   7.449 -  ChildDeviceData->XenInterface.InterfaceHeader.Context = xedd->XenInterface.InterfaceHeader.Context;
   7.450 -  ChildDeviceData->XenInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
   7.451 -  ChildDeviceData->XenInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
   7.452 -
   7.453 -  ChildDeviceData->XenInterface.AllocMMIO = xedd->XenInterface.AllocMMIO;
   7.454 -  ChildDeviceData->XenInterface.FreeMem = xedd->XenInterface.FreeMem;
   7.455 -
   7.456 -  ChildDeviceData->XenInterface.EvtChn_Bind = xedd->XenInterface.EvtChn_Bind;
   7.457 -  ChildDeviceData->XenInterface.EvtChn_Unbind = xedd->XenInterface.EvtChn_Unbind;
   7.458 -  ChildDeviceData->XenInterface.EvtChn_Mask = xedd->XenInterface.EvtChn_Mask;
   7.459 -  ChildDeviceData->XenInterface.EvtChn_Unmask = xedd->XenInterface.EvtChn_Unmask;
   7.460 -  ChildDeviceData->XenInterface.EvtChn_Notify = xedd->XenInterface.EvtChn_Notify;
   7.461 -  ChildDeviceData->XenInterface.EvtChn_AllocUnbound = xedd->XenInterface.EvtChn_AllocUnbound;
   7.462 -  ChildDeviceData->XenInterface.EvtChn_BindDpc = xedd->XenInterface.EvtChn_BindDpc;
   7.463 -
   7.464 -  ChildDeviceData->XenInterface.GntTbl_GetRef = xedd->XenInterface.GntTbl_GetRef;
   7.465 -  ChildDeviceData->XenInterface.GntTbl_PutRef = xedd->XenInterface.GntTbl_PutRef;
   7.466 -  ChildDeviceData->XenInterface.GntTbl_GrantAccess = xedd->XenInterface.GntTbl_GrantAccess;
   7.467 -  ChildDeviceData->XenInterface.GntTbl_EndAccess = xedd->XenInterface.GntTbl_EndAccess;
   7.468 -
   7.469 -  ChildDeviceData->XenInterface.XenBus_Read = xedd->XenInterface.XenBus_Read;
   7.470 -  ChildDeviceData->XenInterface.XenBus_Write = xedd->XenInterface.XenBus_Write;
   7.471 -  ChildDeviceData->XenInterface.XenBus_Printf = xedd->XenInterface.XenBus_Printf;
   7.472 -  ChildDeviceData->XenInterface.XenBus_StartTransaction = xedd->XenInterface.XenBus_StartTransaction;
   7.473 -  ChildDeviceData->XenInterface.XenBus_EndTransaction = xedd->XenInterface.XenBus_EndTransaction;
   7.474 -  ChildDeviceData->XenInterface.XenBus_List = xedd->XenInterface.XenBus_List;
   7.475 -  ChildDeviceData->XenInterface.XenBus_AddWatch = xedd->XenInterface.XenBus_AddWatch;
   7.476 -  ChildDeviceData->XenInterface.XenBus_RemWatch = xedd->XenInterface.XenBus_RemWatch;
   7.477 -
   7.478 -  WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->XenInterface, &GUID_XEN_IFACE, NULL);
   7.479 -  status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
   7.480 -  if (!NT_SUCCESS(status)) {
   7.481 -    return status;
   7.482 -  }
   7.483 -
   7.484 -  KdPrint((__DRIVER_NAME " <-- ChildListCreateDevice (status = %08x)\n", status));
   7.485 -
   7.486 -  return status;
   7.487 -}
     8.1 --- a/xenenum/xenenum.h	Tue May 27 22:46:06 2008 +1000
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,27 +0,0 @@
     8.4 -#if !defined(_XENENUM_H_)
     8.5 -#define _XENENUM_H_
     8.6 -
     8.7 -#include <ntddk.h>
     8.8 -#include <wdm.h>
     8.9 -#include <wdf.h>
    8.10 -#include <initguid.h>
    8.11 -#include <ntdddisk.h>
    8.12 -
    8.13 -#define NTSTRSAFE_LIB
    8.14 -#include <ntstrsafe.h>
    8.15 -
    8.16 -#define __DRIVER_NAME "XenEnum"
    8.17 -#include <xen_windows.h>
    8.18 -#include <memory.h>
    8.19 -#include <grant_table.h>
    8.20 -#include <event_channel.h>
    8.21 -#include <hvm/params.h>
    8.22 -#include <hvm/hvm_op.h>
    8.23 -#include <xen_public.h>
    8.24 -#include <io/ring.h>
    8.25 -#include <io/blkif.h>
    8.26 -#define XENENUM_POOL_TAG (ULONG) 'XENM'
    8.27 -
    8.28 -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
    8.29 -
    8.30 -#endif
     9.1 --- a/xenenum/xenenum.inx	Tue May 27 22:46:06 2008 +1000
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,76 +0,0 @@
     9.4 -[Version]
     9.5 -Signature="$WINDOWS NT$"
     9.6 -Class=System
     9.7 -ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318}
     9.8 -Provider=%XenGplPv%
     9.9 -
    9.10 -[DestinationDirs]
    9.11 -DefaultDestDir = 12
    9.12 -ClassInstall32_CopyFiles=11
    9.13 -CoInstaller_CopyFiles = 11
    9.14 -
    9.15 -[ControlFlags]
    9.16 -ExcludeFromSelect=*
    9.17 -
    9.18 -[Manufacturer]
    9.19 -%XenGplPv%=XenGplPv,NTx86
    9.20 -%XenGplPv%=XenGplPv,NTAMD64
    9.21 -
    9.22 -[XenGplPv.NTx86]
    9.23 -%XenEnum.DRVDESC%=XenEnum_Inst, XEN\VIF
    9.24 -
    9.25 -[XenGplPv.NTAMD64]
    9.26 -%XenEnum.DRVDESC%=XenEnum_Inst, XEN\VIF
    9.27 -
    9.28 -[XenEnum_Inst.NT]
    9.29 -CopyFiles=XenEnum.CopyFiles
    9.30 -
    9.31 -[XenEnum.CopyFiles]
    9.32 -xenEnum.sys
    9.33 -
    9.34 -[XenEnum_Inst.NT.Services]
    9.35 -AddService=XenEnum,2,XenEnum_Service 
    9.36 -
    9.37 -[XenEnum_Service]
    9.38 -DisplayName    = %XenEnum.SVCDESC%                            
    9.39 -ServiceType    = 1
    9.40 -StartType      = 0
    9.41 -ErrorControl   = 1
    9.42 -LoadOrderGroup = System Bus Extender
    9.43 -ServiceBinary  = %12%\xenenum.sys                            
    9.44 -AddReg = XenEnum_Service_AddReg
    9.45 -
    9.46 -[XenEnum_Service_AddReg]
    9.47 -HKR,"Parameters\PnpInterface", "0", 0x00010001, 0x00000001
    9.48 -
    9.49 -[XenEnum_Inst.NT.CoInstallers]
    9.50 -AddReg=CoInstaller_AddReg
    9.51 -CopyFiles=CoInstaller_CopyFiles
    9.52 -
    9.53 -[XenEnum_Inst.NT.Wdf]
    9.54 -KmdfService = xenenum, xenenum_wdfsect
    9.55 -
    9.56 -[xenenum_wdfsect]
    9.57 -KmdfLibraryVersion = $KMDFVERSION$
    9.58 -
    9.59 -[SourceDisksFiles]
    9.60 -xenenum.sys=1
    9.61 -WdfCoinstaller$KMDFCOINSTALLERVERSION$.dll=1,,
    9.62 -
    9.63 -[SourceDisksNames.x86]
    9.64 -1 = %DISK_NAME%,,,\i386
    9.65 -
    9.66 -[SourceDisksNames.amd64]
    9.67 -1 = %DISK_NAME%,,,\amd64
    9.68 -
    9.69 -[CoInstaller_CopyFiles]
    9.70 -WdfCoinstaller$KMDFCOINSTALLERVERSION$.dll,,,2
    9.71 -
    9.72 -[CoInstaller_AddReg]
    9.73 -HKR,,CoInstallers32,0x00010000, "WdfCoinstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"
    9.74 -
    9.75 -[Strings]
    9.76 -XenGplPv = "Xen GPL PV Driver Developers"
    9.77 -XenEnum.SVCDESC = "Xen Enum Device Driver"
    9.78 -XenEnum.DRVDESC = "Xen Enum Device Driver"
    9.79 -DISK_NAME = "Xen Enum Device Driver Install Disk"
    10.1 --- a/xennet/xennet.h	Tue May 27 22:46:06 2008 +1000
    10.2 +++ b/xennet/xennet.h	Sat May 31 22:35:41 2008 +1000
    10.3 @@ -84,7 +84,7 @@ Foundation, Inc., 51 Franklin Street, Fi
    10.4  
    10.5  #pragma warning(disable: 4127) // conditional expression is constant
    10.6  
    10.7 -#define XEN_PROFILE
    10.8 +//#define XEN_PROFILE
    10.9  
   10.10  #define MIN_LARGE_SEND_SEGMENTS 4
   10.11  
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/xenpci/hypercall.h	Sat May 31 22:35:41 2008 +1000
    11.3 @@ -0,0 +1,115 @@
    11.4 +/*
    11.5 +PV Drivers for Windows Xen HVM Domains
    11.6 +Copyright (C) 2007 James Harper
    11.7 +
    11.8 +This program is free software; you can redistribute it and/or
    11.9 +modify it under the terms of the GNU General Public License
   11.10 +as published by the Free Software Foundation; either version 2
   11.11 +of the License, or (at your option) any later version.
   11.12 +
   11.13 +This program is distributed in the hope that it will be useful,
   11.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11.16 +GNU General Public License for more details.
   11.17 +
   11.18 +You should have received a copy of the GNU General Public License
   11.19 +along with this program; if not, write to the Free Software
   11.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   11.21 +*/
   11.22 +
   11.23 +#if defined(_X86_)
   11.24 +  #include "hypercall_x86.h"
   11.25 +#else
   11.26 +  #if defined(_AMD64_)
   11.27 +    #include "hypercall_amd64.h"
   11.28 +  #endif
   11.29 +#endif
   11.30 +
   11.31 +static NTSTATUS
   11.32 +hvm_get_stubs(PXENPCI_DEVICE_DATA xpdd)
   11.33 +{
   11.34 +  DWORD32 cpuid_output[4];
   11.35 +  char xensig[13];
   11.36 +  ULONG i;
   11.37 +  ULONG pages;
   11.38 +  ULONG msr;  
   11.39 +
   11.40 +  __cpuid(cpuid_output, 0x40000000);
   11.41 +  *(ULONG*)(xensig + 0) = cpuid_output[1];
   11.42 +  *(ULONG*)(xensig + 4) = cpuid_output[2];
   11.43 +  *(ULONG*)(xensig + 8) = cpuid_output[3];
   11.44 +  xensig[12] = '\0';
   11.45 +  KdPrint((__DRIVER_NAME " Xen Signature = %s, EAX = 0x%08x\n", xensig, cpuid_output[0]));
   11.46 +
   11.47 +  __cpuid(cpuid_output, 0x40000002);
   11.48 +  pages = cpuid_output[0];
   11.49 +  msr = cpuid_output[1];
   11.50 +  //KdPrint((__DRIVER_NAME " Hypercall area is %u pages.\n", pages));
   11.51 +
   11.52 +  xpdd->hypercall_stubs = ExAllocatePoolWithTag(NonPagedPool, pages * PAGE_SIZE, XENPCI_POOL_TAG);
   11.53 +  KdPrint((__DRIVER_NAME " Hypercall area at %p\n", xpdd->hypercall_stubs));
   11.54 +
   11.55 +  if (!xpdd->hypercall_stubs)
   11.56 +    return 1;
   11.57 +  for (i = 0; i < pages; i++) {
   11.58 +    ULONGLONG pfn;
   11.59 +    pfn = (MmGetPhysicalAddress(xpdd->hypercall_stubs + i * PAGE_SIZE).QuadPart >> PAGE_SHIFT);
   11.60 +    KdPrint((__DRIVER_NAME " pfn = %16lX\n", pfn));
   11.61 +    __writemsr(msr, (pfn << PAGE_SHIFT) + i);
   11.62 +  }
   11.63 +  return STATUS_SUCCESS;
   11.64 +}
   11.65 +
   11.66 +static NTSTATUS
   11.67 +hvm_free_stubs(PXENPCI_DEVICE_DATA xpdd)
   11.68 +{
   11.69 +  ExFreePoolWithTag(xpdd->hypercall_stubs, XENPCI_POOL_TAG);
   11.70 +
   11.71 +  return STATUS_SUCCESS;
   11.72 +}
   11.73 +
   11.74 +static __inline ULONGLONG
   11.75 +hvm_get_parameter(PXENPCI_DEVICE_DATA xpdd, int hvm_param)
   11.76 +{
   11.77 +  struct xen_hvm_param a;
   11.78 +  int retval;
   11.79 +
   11.80 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   11.81 +  a.domid = DOMID_SELF;
   11.82 +  a.index = hvm_param;
   11.83 +  //a.value = via;
   11.84 +  retval = HYPERVISOR_hvm_op(xpdd, HVMOP_get_param, &a);
   11.85 +  KdPrint((__DRIVER_NAME " HYPERVISOR_hvm_op retval = %d\n", retval));
   11.86 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   11.87 +  return a.value;
   11.88 +}
   11.89 +
   11.90 +static __inline ULONGLONG
   11.91 +hvm_set_parameter(PXENPCI_DEVICE_DATA xpdd, int hvm_param, ULONGLONG value)
   11.92 +{
   11.93 +  struct xen_hvm_param a;
   11.94 +  int retval;
   11.95 +
   11.96 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   11.97 +  a.domid = DOMID_SELF;
   11.98 +  a.index = hvm_param;
   11.99 +  a.value = value;
  11.100 +  //a.value = via;
  11.101 +  retval = HYPERVISOR_hvm_op(xpdd, HVMOP_set_param, &a);
  11.102 +  KdPrint((__DRIVER_NAME " HYPERVISOR_hvm_op retval = %d\n", retval));
  11.103 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  11.104 +  return retval;
  11.105 +}
  11.106 +
  11.107 +static __inline int
  11.108 +hvm_shutdown(PXENPCI_DEVICE_DATA xpdd, unsigned int reason)
  11.109 +{
  11.110 +  struct sched_shutdown ss;
  11.111 +  int retval;
  11.112 +
  11.113 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  11.114 +  ss.reason = reason;
  11.115 +  retval = HYPERVISOR_sched_op(xpdd, SCHEDOP_shutdown, &ss);
  11.116 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  11.117 +  return retval;
  11.118 +}
    12.1 --- a/xenpci/xenpci.c	Tue May 27 22:46:06 2008 +1000
    12.2 +++ b/xenpci/xenpci.c	Sat May 31 22:35:41 2008 +1000
    12.3 @@ -161,6 +161,11 @@ XenPci_AddDevice(PDRIVER_OBJECT DriverOb
    12.4      IoDeleteDevice(fdo);
    12.5      return STATUS_NO_SUCH_DEVICE;
    12.6    }
    12.7 +  INIT_PNP_STATE(&xpdd->common);
    12.8 +  xpdd->common.device_usage_paging = 0;
    12.9 +  xpdd->common.device_usage_dump = 0;
   12.10 +  xpdd->common.device_usage_hibernation = 0;
   12.11 +
   12.12    InitializeListHead(&xpdd->child_list);
   12.13  
   12.14    status = IoRegisterDeviceInterface(
    13.1 --- a/xenpci/xenpci.h	Tue May 27 22:46:06 2008 +1000
    13.2 +++ b/xenpci/xenpci.h	Sat May 31 22:35:41 2008 +1000
    13.3 @@ -123,11 +123,33 @@ typedef struct
    13.4    PDEVICE_OBJECT pdo;
    13.5    PDEVICE_OBJECT lower_do;
    13.6    
    13.7 -  DEVICE_PNP_STATE device_pnp_state;
    13.8 +  DEVICE_PNP_STATE current_pnp_state;
    13.9 +  DEVICE_PNP_STATE previous_pnp_state;
   13.10    DEVICE_POWER_STATE device_power_state;
   13.11 -  SYSTEM_POWER_STATE system_power_state; 
   13.12 +  SYSTEM_POWER_STATE system_power_state;
   13.13 +  
   13.14 +  ULONG device_usage_paging;
   13.15 +  ULONG device_usage_dump;
   13.16 +  ULONG device_usage_hibernation;
   13.17  } XENPCI_COMMON, *PXENPCI_COMMON;
   13.18  
   13.19 +static __inline INIT_PNP_STATE(PXENPCI_COMMON common)
   13.20 +{
   13.21 +  common->current_pnp_state = NotStarted;
   13.22 +  common->previous_pnp_state = NotStarted;
   13.23 +}
   13.24 +
   13.25 +static __inline SET_PNP_STATE(PXENPCI_COMMON common, DEVICE_PNP_STATE state)
   13.26 +{
   13.27 +  common->previous_pnp_state = common->current_pnp_state;
   13.28 +  common->current_pnp_state = state;
   13.29 +}
   13.30 +
   13.31 +static __inline REVERT_PNP_STATE(PXENPCI_COMMON common)
   13.32 +{
   13.33 +  common->current_pnp_state = common->previous_pnp_state;
   13.34 +}
   13.35 +
   13.36  #define SHUTDOWN_RING_SIZE 128
   13.37  
   13.38  typedef struct {  
    14.1 --- a/xenpci/xenpci_fdo.c	Tue May 27 22:46:06 2008 +1000
    14.2 +++ b/xenpci/xenpci_fdo.c	Sat May 31 22:35:41 2008 +1000
    14.3 @@ -681,7 +681,7 @@ XenPci_Pnp_StopDevice(PDEVICE_OBJECT dev
    14.4  }
    14.5  
    14.6  static NTSTATUS
    14.7 -XenPci_Pnp_QueryRemoveDevice(PDEVICE_OBJECT device_object, PIRP irp)
    14.8 +XenPci_Pnp_QueryStopRemoveDevice(PDEVICE_OBJECT device_object, PIRP irp)
    14.9  {
   14.10    NTSTATUS status;
   14.11    PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   14.12 @@ -690,8 +690,9 @@ XenPci_Pnp_QueryRemoveDevice(PDEVICE_OBJ
   14.13  
   14.14    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   14.15  
   14.16 -#if 0
   14.17 -  if (FALSE)
   14.18 +  if (xpdd->common.device_usage_paging
   14.19 +    || xpdd->common.device_usage_dump
   14.20 +    || xpdd->common.device_usage_hibernation)
   14.21    {
   14.22      /* We are in the paging or hibernation path - can't remove */
   14.23      status = irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
   14.24 @@ -699,13 +700,10 @@ XenPci_Pnp_QueryRemoveDevice(PDEVICE_OBJ
   14.25    }
   14.26    else
   14.27    {
   14.28 -#endif
   14.29      IoSkipCurrentIrpStackLocation(irp);
   14.30      status = IoCallDriver(xpdd->common.lower_do, irp);
   14.31 -#if 0
   14.32    }
   14.33 -#endif
   14.34 -
   14.35 +  
   14.36    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   14.37  
   14.38    return status;
   14.39 @@ -731,98 +729,12 @@ XenPci_Pnp_RemoveDevice(PDEVICE_OBJECT d
   14.40    return status;
   14.41  }
   14.42  
   14.43 -#if 0
   14.44 -static VOID
   14.45 -XenPci_XenBusWatchHandler(PVOID context, char *path)
   14.46 -{
   14.47 -  NTSTATUS status;
   14.48 -  char **bits;
   14.49 -  int count;
   14.50 -  int i;
   14.51 -//  WDFDEVICE Device = Data;
   14.52 -//  WDFCHILDLIST ChildList;
   14.53 -//  WDF_CHILD_LIST_ITERATOR ChildIterator;
   14.54 -//  WDFDEVICE ChildDevice;
   14.55 -//  PXENPCI_XEN_DEVICE_DATA ChildDeviceData;
   14.56 -//  XENPCI_IDENTIFICATION_DESCRIPTION description;
   14.57 -  PXEN_CHILD child = NULL;
   14.58 -  PXENPCI_DEVICE_DATA xpdd = context;
   14.59 -
   14.60 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   14.61 -
   14.62 -#if (NTDDI_VERSION >= NTDDI_WS03SP1)
   14.63 -  KeAcquireGuardedMutex(&xpdd->WatchHandlerMutex);
   14.64 -#endif
   14.65 -
   14.66 -  KdPrint((__DRIVER_NAME "     path = %s\n", path));
   14.67 -  bits = SplitString(path, '/', 3, &count);
   14.68 -  KdPrint((__DRIVER_NAME "     Count = %s\n", count));
   14.69 -  
   14.70 -  ASSERT(count >= 2);
   14.71 -  
   14.72 -  for (i = 0; i < 16; i++)
   14.73 -  {
   14.74 -    if (xpdd->child_devices[i].pdo != NULL && strncmp(xpdd->child_devices[i].path, path, strlen(xpdd->child_devices[i].path)) == 0 && path[strlen(xpdd->child_devices[i].path] == '/')
   14.75 -    {
   14.76 -	  child = &xpdd->child_devices[i];
   14.77 -	  break;
   14.78 -	}
   14.79 -  }
   14.80 -  
   14.81 -  if (child == NULL && count >= 2)
   14.82 -    IoInvalidateDeviceRelations(xpdd->common.fdo, BusRelations);
   14.83 -  else if (count > 2)
   14.84 -  {
   14.85 -    // forward on to the child
   14.86 -  }
   14.87 -  
   14.88 -#if 0
   14.89 -  ChildDeviceData = NULL;
   14.90 -  WDF_CHILD_LIST_ITERATOR_INIT(&ChildIterator, WdfRetrievePresentChildren);
   14.91 -  WdfChildListBeginIteration(ChildList, &ChildIterator);
   14.92 -  while (NT_SUCCESS(WdfChildListRetrieveNextDevice(ChildList, &ChildIterator, &ChildDevice, NULL)))
   14.93 -  {
   14.94 -    ChildDeviceData = GetXenDeviceData(ChildDevice);
   14.95 -    if (!ChildDeviceData)
   14.96 -    {
   14.97 -      KdPrint(("     No child device data, should never happen\n"));
   14.98 -      continue;
   14.99 -    }
  14.100 -    if (strncmp(ChildDeviceData->Path, Path, strlen(ChildDeviceData->Path)) == 0 && Path[strlen(ChildDeviceData->Path)] == '/')
  14.101 -    {
  14.102 -      if (Count == 3 && ChildDeviceData->WatchHandler != NULL)
  14.103 -        ChildDeviceData->WatchHandler(Path, ChildDeviceData->WatchContext);
  14.104 -      break;
  14.105 -    }
  14.106 -    ChildDeviceData = NULL;
  14.107 -  }
  14.108 -  WdfChildListEndIteration(ChildList, &ChildIterator);
  14.109 -  if (Count >= 2 && ChildDeviceData == NULL)
  14.110 -  {
  14.111 -    RtlZeroMemory(&description, sizeof(description));
  14.112 -    WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&description.Header, sizeof(description));
  14.113 -    strncpy(description.Path, Path, 128);
  14.114 -    strncpy(description.DeviceType, Bits[1], 128);
  14.115 -    KdPrint((__DRIVER_NAME "     Adding child for %s\n", description.DeviceType));
  14.116 -    status = WdfChildListAddOrUpdateChildDescriptionAsPresent(ChildList, &description.Header, NULL);
  14.117 -  }
  14.118 -  FreeSplitString(Bits, Count);
  14.119 -
  14.120 -#if (NTDDI_VERSION >= NTDDI_WS03SP1)
  14.121 -  KeReleaseGuardedMutex(&xpdd->WatchHandlerMutex);
  14.122 -#endif
  14.123 -
  14.124 -#endif
  14.125 -
  14.126 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  14.127 -}
  14.128 -#endif
  14.129 -
  14.130  static VOID
  14.131  XenPci_Pnp_QueryBusRelationsCallback(PDEVICE_OBJECT device_object, PVOID context)
  14.132  {
  14.133    NTSTATUS status = STATUS_SUCCESS;
  14.134    PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
  14.135 +  PXENPCI_PDO_DEVICE_DATA xppdd;
  14.136    PIRP irp = context;
  14.137    int device_count = 0;
  14.138    PDEVICE_RELATIONS dev_relations;
  14.139 @@ -886,18 +798,21 @@ XenPci_Pnp_QueryBusRelationsCallback(PDE
  14.140              if (!NT_SUCCESS(status))
  14.141                KdPrint((__DRIVER_NAME "     IoCreateDevice status = %08X\n", status));
  14.142              RtlZeroMemory(pdo->DeviceExtension, sizeof(XENPCI_PDO_DEVICE_DATA));
  14.143 -            child->context = (PXENPCI_PDO_DEVICE_DATA)pdo->DeviceExtension;
  14.144 -            child->context->common.fdo = NULL;
  14.145 -            child->context->common.pdo = pdo;
  14.146 -            child->context->common.lower_do = NULL;
  14.147 -            child->context->common.device_pnp_state = NotStarted;
  14.148 -            child->context->bus_fdo = device_object;
  14.149 -            RtlStringCbCopyA(child->context->path, ARRAY_SIZE(child->context->path), path);
  14.150 -            RtlStringCbCopyA(child->context->device, ARRAY_SIZE(child->context->device), devices[i]);
  14.151 -            child->context->index = atoi(instances[j]);
  14.152 -            KeInitializeEvent(&child->context->backend_state_event, SynchronizationEvent, FALSE);
  14.153 -            child->context->backend_state = XenbusStateUnknown;
  14.154 -            child->context->backend_path[0] = '\0';
  14.155 +            child->context = xppdd = pdo->DeviceExtension;
  14.156 +            xppdd->common.fdo = NULL;
  14.157 +            xppdd->common.pdo = pdo;
  14.158 +            xppdd->common.lower_do = NULL;
  14.159 +            INIT_PNP_STATE(&xppdd->common);
  14.160 +            xppdd->common.device_usage_paging = 0;
  14.161 +            xppdd->common.device_usage_dump = 0;
  14.162 +            xppdd->common.device_usage_hibernation = 0;
  14.163 +            xppdd->bus_fdo = device_object;
  14.164 +            RtlStringCbCopyA(xppdd->path, ARRAY_SIZE(xppdd->path), path);
  14.165 +            RtlStringCbCopyA(xppdd->device, ARRAY_SIZE(xppdd->device), devices[i]);
  14.166 +            xppdd->index = atoi(instances[j]);
  14.167 +            KeInitializeEvent(&xppdd->backend_state_event, SynchronizationEvent, FALSE);
  14.168 +            xppdd->backend_state = XenbusStateUnknown;
  14.169 +            xppdd->backend_path[0] = '\0';
  14.170              InsertTailList(&xpdd->child_list, (PLIST_ENTRY)child);
  14.171              device_count++;
  14.172            }
  14.173 @@ -1007,11 +922,65 @@ XenPci_Pnp_FilterResourceRequirements(PD
  14.174    return STATUS_PENDING;
  14.175  }
  14.176  
  14.177 +static NTSTATUS
  14.178 +XenPci_Pnp_DeviceUsageNotification(PDEVICE_OBJECT device_object, PIRP irp, PVOID context)
  14.179 +{
  14.180 +  NTSTATUS status;
  14.181 +  PXENPCI_DEVICE_DATA xpdd;
  14.182 +  PIO_STACK_LOCATION stack;
  14.183 +  
  14.184 +  UNREFERENCED_PARAMETER(context);
  14.185 +
  14.186 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__"\n"));
  14.187 +
  14.188 +  xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
  14.189 +  stack = IoGetCurrentIrpStackLocation(irp);
  14.190 +  status = irp->IoStatus.Status;
  14.191 +  
  14.192 +  if (!NT_SUCCESS(irp->IoStatus.Status))
  14.193 +  {
  14.194 +    switch (stack->Parameters.UsageNotification.Type)
  14.195 +    {
  14.196 +    case DeviceUsageTypePaging:
  14.197 +      if (stack->Parameters.UsageNotification.InPath)
  14.198 +        xpdd->common.device_usage_paging--;
  14.199 +      else
  14.200 +        xpdd->common.device_usage_paging++;      
  14.201 +      break;
  14.202 +    case DeviceUsageTypeDumpFile:
  14.203 +      if (stack->Parameters.UsageNotification.InPath)
  14.204 +        xpdd->common.device_usage_dump--;
  14.205 +      else
  14.206 +        xpdd->common.device_usage_dump++;      
  14.207 +      break;
  14.208 +    case DeviceUsageTypeHibernation:
  14.209 +      if (stack->Parameters.UsageNotification.InPath)
  14.210 +        xpdd->common.device_usage_hibernation--;
  14.211 +      else
  14.212 +        xpdd->common.device_usage_hibernation++;      
  14.213 +      break;
  14.214 +    }
  14.215 +    if (xpdd->common.device_usage_paging
  14.216 +      || xpdd->common.device_usage_dump
  14.217 +      || xpdd->common.device_usage_hibernation)
  14.218 +    {
  14.219 +      xpdd->common.fdo->Flags &= ~DO_POWER_PAGABLE;
  14.220 +    }
  14.221 +    IoInvalidateDeviceState(xpdd->common.pdo);
  14.222 +  }
  14.223 +  IoCompleteRequest(irp, IO_NO_INCREMENT);
  14.224 +
  14.225 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
  14.226 +  
  14.227 +  return status;
  14.228 +}
  14.229 +
  14.230 +
  14.231  NTSTATUS
  14.232  XenPci_Pnp_Fdo(PDEVICE_OBJECT device_object, PIRP irp)
  14.233  {
  14.234 +  NTSTATUS status;
  14.235    PIO_STACK_LOCATION stack;
  14.236 -  NTSTATUS status;
  14.237    PXENPCI_DEVICE_DATA xpdd;
  14.238  
  14.239    //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  14.240 @@ -1028,9 +997,10 @@ XenPci_Pnp_Fdo(PDEVICE_OBJECT device_obj
  14.241  
  14.242    case IRP_MN_QUERY_STOP_DEVICE:
  14.243      KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_STOP_DEVICE\n"));
  14.244 -    IoSkipCurrentIrpStackLocation(irp);
  14.245 -    irp->IoStatus.Status = STATUS_SUCCESS;
  14.246 -    break;
  14.247 +    status = XenPci_Pnp_QueryStopRemoveDevice(device_object, irp);
  14.248 +    if (NT_SUCCESS(status))
  14.249 +      SET_PNP_STATE(&xpdd->common.fdo, RemovePending);
  14.250 +    return status;
  14.251  
  14.252    case IRP_MN_STOP_DEVICE:
  14.253      KdPrint((__DRIVER_NAME "     IRP_MN_STOP_DEVICE\n"));
  14.254 @@ -1041,21 +1011,26 @@ XenPci_Pnp_Fdo(PDEVICE_OBJECT device_obj
  14.255    case IRP_MN_CANCEL_STOP_DEVICE:
  14.256      KdPrint((__DRIVER_NAME "     IRP_MN_CANCEL_STOP_DEVICE\n"));
  14.257      IoSkipCurrentIrpStackLocation(irp);
  14.258 +    REVERT_PNP_STATE(&xpdd->common);
  14.259      irp->IoStatus.Status = STATUS_SUCCESS;
  14.260      break;
  14.261  
  14.262    case IRP_MN_QUERY_REMOVE_DEVICE:
  14.263      KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_REMOVE_DEVICE\n"));
  14.264 -    return XenPci_Pnp_QueryRemoveDevice(device_object, irp);
  14.265 +    status = XenPci_Pnp_QueryStopRemoveDevice(device_object, irp);
  14.266 +    if (NT_SUCCESS(status))
  14.267 +      SET_PNP_STATE(&xpdd->common.fdo, RemovePending);
  14.268 +    return status;
  14.269  
  14.270    case IRP_MN_REMOVE_DEVICE:
  14.271      KdPrint((__DRIVER_NAME "     IRP_MN_REMOVE_DEVICE\n"));
  14.272 -    return XenPci_Pnp_QueryRemoveDevice(device_object, irp);
  14.273 +    return XenPci_Pnp_RemoveDevice(device_object, irp);
  14.274      break;
  14.275  
  14.276    case IRP_MN_CANCEL_REMOVE_DEVICE:
  14.277      KdPrint((__DRIVER_NAME "     IRP_MN_CANCEL_REMOVE_DEVICE\n"));
  14.278      IoSkipCurrentIrpStackLocation(irp);
  14.279 +    REVERT_PNP_STATE(&xpdd->common.fdo, &xpdd->common);
  14.280      irp->IoStatus.Status = STATUS_SUCCESS;
  14.281      break;
  14.282  
  14.283 @@ -1067,8 +1042,47 @@ XenPci_Pnp_Fdo(PDEVICE_OBJECT device_obj
  14.284  
  14.285    case IRP_MN_DEVICE_USAGE_NOTIFICATION:
  14.286      KdPrint((__DRIVER_NAME "     IRP_MN_DEVICE_USAGE_NOTIFICATION\n"));
  14.287 -    IoSkipCurrentIrpStackLocation(irp);
  14.288 -    irp->IoStatus.Status = STATUS_SUCCESS;
  14.289 +    switch (stack->Parameters.UsageNotification.Type)
  14.290 +    {
  14.291 +    case DeviceUsageTypePaging:
  14.292 +      KdPrint((__DRIVER_NAME "     type = DeviceUsageTypePaging = %d\n", stack->Parameters.UsageNotification.InPath));
  14.293 +      if (stack->Parameters.UsageNotification.InPath)
  14.294 +        xpdd->common.device_usage_paging++;
  14.295 +      else
  14.296 +        xpdd->common.device_usage_paging--;      
  14.297 +      irp->IoStatus.Status = STATUS_SUCCESS;
  14.298 +      break;
  14.299 +    case DeviceUsageTypeDumpFile:
  14.300 +      KdPrint((__DRIVER_NAME "     type = DeviceUsageTypeDumpFile = %d\n", stack->Parameters.UsageNotification.InPath));
  14.301 +      if (stack->Parameters.UsageNotification.InPath)
  14.302 +        xpdd->common.device_usage_dump++;
  14.303 +      else
  14.304 +        xpdd->common.device_usage_dump--;      
  14.305 +      irp->IoStatus.Status = STATUS_SUCCESS;
  14.306 +      break;
  14.307 +    case DeviceUsageTypeHibernation:
  14.308 +      KdPrint((__DRIVER_NAME "     type = DeviceUsageTypeHibernation = %d\n", stack->Parameters.UsageNotification.InPath));
  14.309 +      if (stack->Parameters.UsageNotification.InPath)
  14.310 +        xpdd->common.device_usage_hibernation++;
  14.311 +      else
  14.312 +        xpdd->common.device_usage_hibernation--;      
  14.313 +      irp->IoStatus.Status = STATUS_SUCCESS;
  14.314 +      break;
  14.315 +    default:
  14.316 +      KdPrint((__DRIVER_NAME "     type = unsupported (%d)\n", stack->Parameters.UsageNotification.Type));      
  14.317 +      irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  14.318 +      IoCompleteRequest(irp, IO_NO_INCREMENT);
  14.319 +      return STATUS_NOT_SUPPORTED;
  14.320 +    }
  14.321 +    if (!xpdd->common.device_usage_paging
  14.322 +      && !xpdd->common.device_usage_dump
  14.323 +      && !xpdd->common.device_usage_hibernation)
  14.324 +    {
  14.325 +      xpdd->common.fdo->Flags |= DO_POWER_PAGABLE;
  14.326 +    }
  14.327 +    IoInvalidateDeviceState(xpdd->common.pdo);
  14.328 +    IoCopyCurrentIrpStackLocationToNext(irp);
  14.329 +    IoSetCompletionRoutine(irp, XenPci_Pnp_DeviceUsageNotification, NULL, TRUE, TRUE, TRUE);
  14.330      break;
  14.331  
  14.332    case IRP_MN_QUERY_DEVICE_RELATIONS:
  14.333 @@ -1089,6 +1103,18 @@ XenPci_Pnp_Fdo(PDEVICE_OBJECT device_obj
  14.334      KdPrint((__DRIVER_NAME "     IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"));
  14.335      return XenPci_Pnp_FilterResourceRequirements(device_object, irp);
  14.336  
  14.337 +  case IRP_MN_QUERY_PNP_DEVICE_STATE:
  14.338 +    KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_PNP_DEVICE_STATE\n"));
  14.339 +    irp->IoStatus.Status = STATUS_SUCCESS;
  14.340 +    if (xpdd->common.device_usage_paging
  14.341 +      || xpdd->common.device_usage_dump
  14.342 +      || xpdd->common.device_usage_hibernation)
  14.343 +    {
  14.344 +      irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
  14.345 +    }
  14.346 +    IoSkipCurrentIrpStackLocation(irp);
  14.347 +    break;
  14.348 +    
  14.349    default:
  14.350      //KdPrint((__DRIVER_NAME "     Unhandled Minor = %d\n", stack->MinorFunction));
  14.351      IoSkipCurrentIrpStackLocation(irp);
    15.1 --- a/xenpci/xenpci_pdo.c	Tue May 27 22:46:06 2008 +1000
    15.2 +++ b/xenpci/xenpci_pdo.c	Sat May 31 22:35:41 2008 +1000
    15.3 @@ -205,7 +205,7 @@ XenPci_ChangeFrontendState(PXENPCI_PDO_D
    15.4  static VOID
    15.5  DUMP_CURRENT_PNP_STATE(PXENPCI_PDO_DEVICE_DATA xppdd)
    15.6  {
    15.7 -  switch (xppdd->common.device_pnp_state)
    15.8 +  switch (xppdd->common.current_pnp_state)
    15.9    {
   15.10    case Unknown:
   15.11      KdPrint((__DRIVER_NAME "     pnp_state = Unknown\n"));
   15.12 @@ -569,7 +569,7 @@ XenPci_Pnp_StartDevice(PDEVICE_OBJECT de
   15.13  
   15.14    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   15.15  
   15.16 -  xpdd->common.device_pnp_state = Started;
   15.17 +  SET_PNP_STATE(&xppdd->common, Started);
   15.18    
   15.19    return STATUS_SUCCESS;
   15.20  }
   15.21 @@ -744,25 +744,25 @@ XenPci_Pnp_Pdo(PDEVICE_OBJECT device_obj
   15.22      
   15.23    case IRP_MN_QUERY_STOP_DEVICE:
   15.24      KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
   15.25 -    xppdd->common.device_pnp_state = StopPending;
   15.26 +    SET_PNP_STATE(&xppdd->common, StopPending);
   15.27      status = STATUS_SUCCESS;
   15.28      break;
   15.29  
   15.30    case IRP_MN_STOP_DEVICE:
   15.31      KdPrint((__DRIVER_NAME "     IRP_MN_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
   15.32 -    xppdd->common.device_pnp_state = Stopped;
   15.33 +    SET_PNP_STATE(&xppdd->common, Stopped);
   15.34      status = STATUS_SUCCESS;
   15.35      break;
   15.36  
   15.37    case IRP_MN_CANCEL_STOP_DEVICE:
   15.38      KdPrint((__DRIVER_NAME "     IRP_MN_CANCEL_STOP_DEVICE (status = %08x)\n", irp->IoStatus.Status));
   15.39 -    xppdd->common.device_pnp_state = Started; /* obviously this isn't really correct :) */
   15.40 +    REVERT_PNP_STATE(&xppdd->common);
   15.41      status = STATUS_SUCCESS;
   15.42      break;
   15.43  
   15.44    case IRP_MN_QUERY_REMOVE_DEVICE:
   15.45      KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
   15.46 -    xppdd->common.device_pnp_state = RemovePending;
   15.47 +    SET_PNP_STATE(&xppdd->common, RemovePending);
   15.48      status = STATUS_SUCCESS;
   15.49      break;
   15.50  
   15.51 @@ -773,13 +773,13 @@ XenPci_Pnp_Pdo(PDEVICE_OBJECT device_obj
   15.52  
   15.53    case IRP_MN_CANCEL_REMOVE_DEVICE:
   15.54      KdPrint((__DRIVER_NAME "     IRP_MN_CANCEL_REMOVE_DEVICE (status = %08x)\n", irp->IoStatus.Status));
   15.55 -    xppdd->common.device_pnp_state = Started; /* obviously this isn't really correct :) */
   15.56 +    REVERT_PNP_STATE(&xppdd->common);
   15.57      status = STATUS_SUCCESS;
   15.58      break;
   15.59  
   15.60    case IRP_MN_SURPRISE_REMOVAL:
   15.61      KdPrint((__DRIVER_NAME "     IRP_MN_SURPRISE_REMOVAL (status = %08x)\n", irp->IoStatus.Status));
   15.62 -    xppdd->common.device_pnp_state = SurpriseRemovePending;
   15.63 +    SET_PNP_STATE(&xppdd->common, SurpriseRemovePending);
   15.64      status = STATUS_SUCCESS;
   15.65      break;
   15.66  
    16.1 --- a/xenscsi/xenscsi.inx	Tue May 27 22:46:06 2008 +1000
    16.2 +++ b/xenscsi/xenscsi.inx	Sat May 31 22:35:41 2008 +1000
    16.3 @@ -7,8 +7,6 @@ CatalogFile="XenGPLPV.cat"
    16.4  
    16.5  [DestinationDirs]
    16.6  DefaultDestDir = 12
    16.7 -ClassInstall32_CopyFiles=11
    16.8 -CoInstaller_CopyFiles = 11
    16.9  
   16.10  [ControlFlags]
   16.11  ExcludeFromSelect=*
   16.12 @@ -58,10 +56,10 @@ AddReg = XenScsi_Inst_HW_AddReg
   16.13  xenscsi.sys=1
   16.14  
   16.15  [SourceDisksNames.x86]
   16.16 -1 = %DISK_NAME%,,,\i386
   16.17 +1 = %DISK_NAME%,,,.\i386
   16.18  
   16.19  [SourceDisksNames.amd64]
   16.20 -1 = %DISK_NAME%,,,\amd64
   16.21 +1 = %DISK_NAME%,,,.\amd64
   16.22  
   16.23  [Strings]
   16.24  XenGplPv = "Xen GPL PV Driver Developers"
    17.1 --- a/xenvbd/scsiport.c	Tue May 27 22:46:06 2008 +1000
    17.2 +++ b/xenvbd/scsiport.c	Sat May 31 22:35:41 2008 +1000
    17.3 @@ -29,6 +29,12 @@ Foundation, Inc., 51 Franklin Street, Fi
    17.4  
    17.5  #pragma warning(disable: 4127)
    17.6  
    17.7 +#if defined(__x86_64__)
    17.8 +  #define GET_PAGE_ALIGNED(ptr) ((ptr + PAGE_SIZE - 1) & ~PAGE_MASK)
    17.9 +#else
   17.10 +  #define GET_PAGE_ALIGNED(ptr) UlongToPtr((PtrToUlong(ptr) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
   17.11 +#endif
   17.12 +
   17.13  static blkif_shadow_t *
   17.14  get_shadow_from_freelist(PXENVBD_DEVICE_DATA xvdd)
   17.15  {
   17.16 @@ -38,6 +44,8 @@ get_shadow_from_freelist(PXENVBD_DEVICE_
   17.17      return NULL;
   17.18    }
   17.19    xvdd->shadow_free--;
   17.20 +  if (xvdd->shadow_free < xvdd->shadow_min_free)
   17.21 +    xvdd->shadow_min_free = xvdd->shadow_free;
   17.22    return &xvdd->shadows[xvdd->shadow_free_list[xvdd->shadow_free]];
   17.23  }
   17.24  
   17.25 @@ -81,6 +89,16 @@ XenVbd_GetResponse(PXENVBD_DEVICE_DATA x
   17.26    return &xvdd->tmp_rep;
   17.27  }
   17.28  
   17.29 +static VOID
   17.30 +XenVbd_HwScsiTimer(PVOID DeviceExtension)
   17.31 +{
   17.32 +  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
   17.33 +
   17.34 +  KdPrint((__DRIVER_NAME "     shadow_min_free = %d\n", xvdd->shadow_min_free));
   17.35 +  xvdd->shadow_min_free = xvdd->shadow_free;
   17.36 +  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_HwScsiTimer, 1 * 1000 * 1000);
   17.37 +}
   17.38 +
   17.39  static ULONG
   17.40  XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
   17.41  {
   17.42 @@ -271,7 +289,6 @@ XenVbd_HwScsiInitialize(PVOID DeviceExte
   17.43    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   17.44  
   17.45    req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
   17.46 -  KdPrint((__DRIVER_NAME "     A\n"));
   17.47    req->operation = 0xff;
   17.48    req->nr_segments = 0;
   17.49    for (i = 0; i < req->nr_segments; i++)
   17.50 @@ -282,10 +299,7 @@ XenVbd_HwScsiInitialize(PVOID DeviceExte
   17.51    }
   17.52    xvdd->ring.req_prod_pvt++;
   17.53  
   17.54 -  KdPrint((__DRIVER_NAME "     B\n"));
   17.55 - 
   17.56    req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
   17.57 -  KdPrint((__DRIVER_NAME "     C\n"));
   17.58    req->operation = 0xff;
   17.59    req->nr_segments = 0;
   17.60    for (i = 0; i < req->nr_segments; i++)
   17.61 @@ -296,13 +310,13 @@ XenVbd_HwScsiInitialize(PVOID DeviceExte
   17.62    }
   17.63    xvdd->ring.req_prod_pvt++;
   17.64  
   17.65 -  KdPrint((__DRIVER_NAME "     D\n"));
   17.66 -
   17.67    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
   17.68 -  KdPrint((__DRIVER_NAME "     E\n"));
   17.69    if (notify)
   17.70      xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
   17.71  
   17.72 +  xvdd->shadow_min_free = xvdd->shadow_free;
   17.73 +  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_HwScsiTimer, 1 * 1000 * 1000);
   17.74 +
   17.75    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   17.76  
   17.77    return TRUE;
   17.78 @@ -333,7 +347,7 @@ XenVbd_PutRequest(PXENVBD_DEVICE_DATA xv
   17.79  static VOID
   17.80  XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, ULONG srb_offset)
   17.81  {
   17.82 -  int block_count;
   17.83 +  ULONG block_count, transfer_length;
   17.84    blkif_shadow_t *shadow;
   17.85    PHYSICAL_ADDRESS physical_address;
   17.86    ULONG pfn;
   17.87 @@ -345,14 +359,33 @@ XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA 
   17.88  
   17.89  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   17.90  
   17.91 +  ASSERT(!xvdd->pending_srb);
   17.92 +  
   17.93 +  block_count = (srb->Cdb[7] << 8) | srb->Cdb[8];
   17.94 +  if (PtrToUlong(srb->DataBuffer) & 511) /* use SrbExtension intead of DataBuffer if DataBuffer is not aligned to sector size */
   17.95 +  {
   17.96 +    ptr = GET_PAGE_ALIGNED(srb->SrbExtension);
   17.97 +    transfer_length = min(block_count * xvdd->bytes_per_sector - srb_offset, UNALIGNED_DOUBLE_BUFFER_SIZE);
   17.98 +  }
   17.99 +  else
  17.100 +  {
  17.101 +    ptr = srb->DataBuffer;
  17.102 +    transfer_length = block_count * xvdd->bytes_per_sector;
  17.103 +  }
  17.104 +  if (xvdd->grant_free <= ADDRESS_AND_SIZE_TO_SPAN_PAGES(ptr, transfer_length))
  17.105 +  {
  17.106 +    xvdd->pending_srb = srb;
  17.107 +    return;
  17.108 +  }
  17.109 +  
  17.110    shadow = get_shadow_from_freelist(xvdd);
  17.111 +  ASSERT(shadow);
  17.112    shadow->req.sector_number = (srb->Cdb[2] << 24) | (srb->Cdb[3] << 16) | (srb->Cdb[4] << 8) | srb->Cdb[5];
  17.113 -  block_count = (srb->Cdb[7] << 8) | srb->Cdb[8];
  17.114    shadow->req.handle = 0;
  17.115    shadow->req.operation = (srb->Cdb[0] == SCSIOP_READ)?BLKIF_OP_READ:BLKIF_OP_WRITE;
  17.116    shadow->req.nr_segments = 0;
  17.117    shadow->offset = srb_offset;
  17.118 -  shadow->length = block_count * xvdd->bytes_per_sector;
  17.119 +  shadow->length = transfer_length;
  17.120    shadow->srb = srb;
  17.121  
  17.122    //KdPrint((__DRIVER_NAME "     sector_number = %d, block_count = %d\n", (ULONG)shadow->req.sector_number, block_count));
  17.123 @@ -362,18 +395,9 @@ XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA 
  17.124    if (PtrToUlong(srb->DataBuffer) & 511) /* use SrbExtension intead of DataBuffer if DataBuffer is not aligned to sector size */
  17.125    {
  17.126      shadow->req.sector_number += srb_offset / xvdd->bytes_per_sector;
  17.127 -    shadow->length = min(shadow->length - srb_offset, UNALIGNED_DOUBLE_BUFFER_SIZE);
  17.128 -    //KdPrint((__DRIVER_NAME "     (Put) id = %d, DataBuffer = %p, SrbExtension = %p, total length = %d, offset = %d, length = %d, sector = %d\n", (ULONG)shadow->req.id, srb->DataBuffer, srb->SrbExtension, block_count * xvdd->bytes_per_sector, shadow->offset, shadow->length, shadow->req.sector_number));
  17.129 +    KdPrint((__DRIVER_NAME "     Using unaligned buffer - DataBuffer = %p, SrbExtension = %p, total length = %d, offset = %d, length = %d, sector = %d\n", srb->DataBuffer, srb->SrbExtension, block_count * xvdd->bytes_per_sector, shadow->offset, shadow->length, shadow->req.sector_number));
  17.130      if (srb->Cdb[0] == SCSIOP_WRITE)
  17.131 -    {
  17.132 -      memcpy(srb->SrbExtension, ((PUCHAR)srb->DataBuffer) + srb_offset, shadow->length);
  17.133 -      //KdPrint((__DRIVER_NAME "     (WR) memcpy(%p, %p, %d)\n", srb->SrbExtension, ((PUCHAR)srb->DataBuffer) + srb_offset, shadow->length));
  17.134 -    }
  17.135 -    else
  17.136 -    {
  17.137 -      RtlZeroMemory(srb->SrbExtension, shadow->length);
  17.138 -    }
  17.139 -    ptr = srb->SrbExtension;
  17.140 +      memcpy(ptr, ((PUCHAR)srb->DataBuffer) + srb_offset, shadow->length);
  17.141    }
  17.142    else
  17.143    {
  17.144 @@ -384,16 +408,15 @@ XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA 
  17.145    while (remaining > 0)
  17.146    {
  17.147      physical_address = MmGetPhysicalAddress(ptr);
  17.148 -    //KdPrint((__DRIVER_NAME "     ptr = %p, physical = %08x:%08x\n", ptr, physical_address.HighPart, physical_address.LowPart));
  17.149      pfn = (ULONG)(physical_address.QuadPart >> PAGE_SHIFT);
  17.150 -    shadow->req.seg[shadow->req.nr_segments].gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0, pfn, 0, get_grant_from_freelist(xvdd));
  17.151 +    shadow->req.seg[shadow->req.nr_segments].gref = get_grant_from_freelist(xvdd);
  17.152 +    ASSERT(shadow->req.seg[shadow->req.nr_segments].gref);
  17.153 +    xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0, pfn, 0, shadow->req.seg[shadow->req.nr_segments].gref);
  17.154      offset = (ULONG)(physical_address.QuadPart & (PAGE_SIZE - 1));
  17.155      ASSERT((offset & 511) == 0);
  17.156      length = min(PAGE_SIZE - offset, remaining);
  17.157      shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset >> 9);
  17.158      shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) >> 9) - 1);
  17.159 -    //KdPrint((__DRIVER_NAME "     length = %d, remaining = %d, pfn = %08x, offset = %d, first = %d, last = %d\n",
  17.160 -    //  length, remaining, pfn, offset, shadow->req.seg[shadow->req.nr_segments].first_sect, shadow->req.seg[shadow->req.nr_segments].last_sect));
  17.161      remaining -= length;
  17.162      ptr += length;
  17.163      shadow->req.nr_segments++;
  17.164 @@ -405,50 +428,79 @@ XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA 
  17.165    if (notify)
  17.166      xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
  17.167  
  17.168 +  /* we don't want another srb if we had to double buffer this one, it will put things out of order */
  17.169 +  if (xvdd->shadow_free && srb_offset + shadow->length == block_count * xvdd->bytes_per_sector )
  17.170 +  {
  17.171 +    ScsiPortNotification(NextLuRequest, xvdd, 0, 0, 0);
  17.172 +  }
  17.173 +
  17.174    //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  17.175  }
  17.176  
  17.177  static ULONG
  17.178 -XenVbd_FillModePage(PXENVBD_DEVICE_DATA DeviceData, UCHAR PageCode, PUCHAR DataBuffer, ULONG BufferLength, PULONG Offset)
  17.179 +XenVbd_FillModePage(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
  17.180  {
  17.181 -  //PMODE_RIGID_GEOMETRY_PAGE ModeRigidGeometry;
  17.182 -
  17.183 -  UNREFERENCED_PARAMETER(DeviceData);
  17.184 -  UNREFERENCED_PARAMETER(DataBuffer);
  17.185 -  UNREFERENCED_PARAMETER(BufferLength);
  17.186 -  UNREFERENCED_PARAMETER(Offset);
  17.187 +  PCDB cdb;
  17.188 +  PMODE_PARAMETER_HEADER parameter_header;
  17.189 +  UCHAR page_code;
  17.190 +  ULONG offset;
  17.191 +  UCHAR buffer[256];
  17.192  
  17.193 -  switch (PageCode)
  17.194 -  {
  17.195 -/*
  17.196 -  case MODE_PAGE_RIGID_GEOMETRY:
  17.197 -    if (DeviceData->ScsiData->DeviceType == XENVBD_DEVICETYPE_CDROM)
  17.198 -    {
  17.199 -    KdPrint((__DRIVER_NAME "     MODE_PAGE_RIGID_GEOMETRY\n"));
  17.200 -    if (*Offset + sizeof(MODE_RIGID_GEOMETRY_PAGE) > BufferLength)
  17.201 -      return 1;
  17.202 -    ModeRigidGeometry = (PMODE_RIGID_GEOMETRY_PAGE)(DataBuffer + *Offset);
  17.203 -    memset(ModeRigidGeometry, 0, sizeof(MODE_RIGID_GEOMETRY_PAGE));
  17.204 -    ModeRigidGeometry->PageCode = PageCode;
  17.205 -    ModeRigidGeometry->PageSavable = 0;
  17.206 -    ModeRigidGeometry->PageLength = sizeof(MODE_RIGID_GEOMETRY_PAGE);
  17.207 -    ModeRigidGeometry->NumberOfCylinders[0] = (DeviceData->Geometry.Cylinders.LowPart >> 16) & 0xFF;
  17.208 -    ModeRigidGeometry->NumberOfCylinders[1] = (DeviceData->Geometry.Cylinders.LowPart >> 8) & 0xFF;
  17.209 -    ModeRigidGeometry->NumberOfCylinders[2] = (DeviceData->Geometry.Cylinders.LowPart >> 0) & 0xFF;
  17.210 -    ModeRigidGeometry->NumberOfHeads = DeviceData->Geometry.TracksPerCylinder;
  17.211 -    //ModeRigidGeometry->LandZoneCyclinder = 0;
  17.212 -    ModeRigidGeometry->RoataionRate[0] = 0x05;
  17.213 -    ModeRigidGeometry->RoataionRate[0] = 0x39;
  17.214 -    *Offset += sizeof(MODE_RIGID_GEOMETRY_PAGE);
  17.215 -    }
  17.216 -    break;
  17.217 -*/
  17.218 -  case MODE_PAGE_FAULT_REPORTING:
  17.219 -    break;
  17.220 -  default:
  17.221 -    break;
  17.222 -  }
  17.223 -  return 0;
  17.224 +  UNREFERENCED_PARAMETER(xvdd);
  17.225 +
  17.226 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  17.227 +  
  17.228 +  cdb = (PCDB)srb->Cdb;
  17.229 +  page_code = cdb->MODE_SENSE.PageCode;
  17.230 +  offset = 0;
  17.231 +  RtlZeroMemory(srb->DataBuffer, srb->DataTransferLength);
  17.232 +  RtlZeroMemory(buffer, ARRAY_SIZE(buffer));
  17.233 +
  17.234 +  parameter_header = (PMODE_PARAMETER_HEADER)&buffer[offset];
  17.235 +  parameter_header->MediumType = 0;
  17.236 +  parameter_header->DeviceSpecificParameter = 0;
  17.237 +  parameter_header->BlockDescriptorLength = 0;
  17.238 +  offset += sizeof(MODE_PARAMETER_HEADER);
  17.239 +  parameter_header->ModeDataLength = (UCHAR)(offset - 4);
  17.240 +  srb->DataTransferLength = min(srb->DataTransferLength, offset);
  17.241 +  memcpy(srb->DataBuffer, buffer, srb->DataTransferLength);
  17.242 +  KdPrint((__DRIVER_NAME "     DataTransferLength = %d\n", srb->DataTransferLength));
  17.243 +  KdPrint((__DRIVER_NAME "     ModeDataLength = %d\n", parameter_header->ModeDataLength));
  17.244 +  if (offset != srb->DataTransferLength)
  17.245 +    srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
  17.246 +  else
  17.247 +    srb->SrbStatus = SRB_STATUS_SUCCESS;
  17.248 +  srb->ScsiStatus = 0;
  17.249 +  
  17.250 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  17.251 +
  17.252 +  return TRUE;
  17.253 +}
  17.254 +
  17.255 +static VOID
  17.256 +XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, BOOLEAN sense_key)
  17.257 +{
  17.258 +  PSENSE_DATA sd = srb->SenseInfoBuffer;
  17.259 + 
  17.260 +  UNREFERENCED_PARAMETER(xvdd);
  17.261 +  
  17.262 +  if (!srb->SenseInfoBuffer)
  17.263 +    return;
  17.264 +  
  17.265 +  sd->ErrorCode = 0x70;
  17.266 +  sd->Valid = 1;
  17.267 +  sd->SenseKey = sense_key;
  17.268 +  sd->AdditionalSenseLength = sizeof(SENSE_DATA) - FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
  17.269 +  return;
  17.270 +}
  17.271 +
  17.272 +static VOID
  17.273 +XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
  17.274 +{
  17.275 +  if (srb->SrbStatus == SRB_STATUS_SUCCESS || srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)
  17.276 +    return;
  17.277 +  XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key);
  17.278 +  srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
  17.279  }
  17.280  
  17.281  static BOOLEAN
  17.282 @@ -500,7 +552,7 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
  17.283            xvdd->use_other = TRUE;
  17.284          }
  17.285          xvdd->ring_detect_state = 2;
  17.286 -        ScsiPortNotification(NextRequest, xvdd);
  17.287 +        ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  17.288          break;
  17.289        case 2:
  17.290          shadow = &xvdd->shadows[rep->id];
  17.291 @@ -519,6 +571,9 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
  17.292              KdPrint((__DRIVER_NAME "     Operation = Write\n"));     
  17.293            KdPrint((__DRIVER_NAME "     Sector = %08X, Count = %d\n", shadow->req.sector_number, block_count));
  17.294            srb->SrbStatus = SRB_STATUS_ERROR;
  17.295 +          srb->ScsiStatus = 0x02;
  17.296 +          xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
  17.297 +          XenVbd_MakeAutoSense(xvdd, srb);
  17.298          }
  17.299          for (j = 0; j < shadow->req.nr_segments; j++)
  17.300          {
  17.301 @@ -539,7 +594,7 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
  17.302            if (offset == block_count * xvdd->bytes_per_sector)
  17.303            {
  17.304              ScsiPortNotification(RequestComplete, xvdd, srb);
  17.305 -            ScsiPortNotification(NextRequest, xvdd);
  17.306 +            ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  17.307            }
  17.308            else
  17.309            {
  17.310 @@ -550,7 +605,14 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
  17.311          {
  17.312            put_shadow_on_freelist(xvdd, shadow);
  17.313            ScsiPortNotification(RequestComplete, xvdd, srb);
  17.314 -          ScsiPortNotification(NextRequest, xvdd);
  17.315 +          if (xvdd->pending_srb)
  17.316 +          {
  17.317 +            srb = xvdd->pending_srb;
  17.318 +            xvdd->pending_srb = NULL;
  17.319 +            XenVbd_PutSrbOnRing(xvdd, srb, 0);
  17.320 +          }
  17.321 +          else
  17.322 +            ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  17.323          }
  17.324        }
  17.325      }
  17.326 @@ -572,19 +634,16 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
  17.327    return FALSE; /* we just don't know... */
  17.328  }
  17.329  
  17.330 -
  17.331  static BOOLEAN
  17.332  XenVbd_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
  17.333  {
  17.334    PUCHAR DataBuffer;
  17.335    PCDB cdb;
  17.336    PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
  17.337 -  unsigned int i;
  17.338  
  17.339    //KdPrint((__DRIVER_NAME " --> HwScsiStartIo PathId = %d, TargetId = %d, Lun = %d\n", Srb->PathId, Srb->TargetId, Srb->Lun));
  17.340  
  17.341    // If we haven't enumerated all the devices yet then just defer the request
  17.342 -  // A timer will issue a NextRequest to get things started again...
  17.343    if (xvdd->ring_detect_state < 2)
  17.344    {
  17.345      Srb->SrbStatus = SRB_STATUS_BUSY;
  17.346 @@ -597,7 +656,7 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  17.347    {
  17.348      Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
  17.349      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  17.350 -    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  17.351 +    ScsiPortNotification(NextRequest, DeviceExtension);
  17.352      KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Out of bounds)\n"));
  17.353      return TRUE;
  17.354    }
  17.355 @@ -614,8 +673,6 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  17.356  //      KdPrint((__DRIVER_NAME "     Command = TEST_UNIT_READY\n"));
  17.357        Srb->SrbStatus = SRB_STATUS_SUCCESS;
  17.358        Srb->ScsiStatus = 0;
  17.359 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  17.360 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  17.361        break;
  17.362      case SCSIOP_INQUIRY:
  17.363        KdPrint((__DRIVER_NAME "     Command = INQUIRY\n"));
  17.364 @@ -630,12 +687,15 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  17.365        case XENVBD_DEVICETYPE_DISK:
  17.366          if ((Srb->Cdb[1] & 1) == 0)
  17.367          {
  17.368 -          DataBuffer[0] = DIRECT_ACCESS_DEVICE;
  17.369 -          DataBuffer[1] = 0x00; // not removable
  17.370 -          DataBuffer[3] = 32;
  17.371 -          memcpy(DataBuffer + 8, "XEN     ", 8); // vendor id
  17.372 -          memcpy(DataBuffer + 16, "PV VBD          ", 16); // product id
  17.373 -          memcpy(DataBuffer + 32, "0000", 4); // product revision level
  17.374 +          PINQUIRYDATA id = (PINQUIRYDATA)DataBuffer;
  17.375 +          id->DeviceType = DIRECT_ACCESS_DEVICE;          
  17.376 +          id->ANSIVersion = 3;
  17.377 +          id->ResponseDataFormat = 0;
  17.378 +          id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
  17.379 +          id->CommandQueue = 1;
  17.380 +          memcpy(id->VendorId, "XEN     ", 8); // vendor id
  17.381 +          memcpy(id->ProductId, "PV DISK         ", 16); // product id
  17.382 +          memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
  17.383          }
  17.384          else
  17.385          {
  17.386 @@ -654,18 +714,11 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  17.387              DataBuffer[1] = 0x80;
  17.388              DataBuffer[2] = 0x00;
  17.389              DataBuffer[3] = 8;
  17.390 -            DataBuffer[4] = 0x31;
  17.391 -            DataBuffer[5] = 0x32;
  17.392 -            DataBuffer[6] = 0x33;
  17.393 -            DataBuffer[7] = 0x34;
  17.394 -            DataBuffer[8] = 0x35;
  17.395 -            DataBuffer[9] = 0x36;
  17.396 -            DataBuffer[10] = 0x37;
  17.397 -            DataBuffer[11] = 0x38;
  17.398 +            memset(&DataBuffer[4], ' ', 8);
  17.399              break;
  17.400            default:
  17.401              KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", Srb->Cdb[2]));
  17.402 -            Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  17.403 +            Srb->SrbStatus = SRB_STATUS_ERROR;
  17.404              break;
  17.405            }
  17.406          }
  17.407 @@ -673,12 +726,16 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  17.408        case XENVBD_DEVICETYPE_CDROM:
  17.409          if ((Srb->Cdb[1] & 1) == 0)
  17.410          {
  17.411 -          DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
  17.412 -          DataBuffer[1] = 0x01; // removable
  17.413 -          DataBuffer[3] = 32;
  17.414 -          memcpy(DataBuffer + 8, "XEN     ", 8); // vendor id
  17.415 -          memcpy(DataBuffer + 16, "PV VBD          ", 16); // product id
  17.416 -          memcpy(DataBuffer + 32, "0000", 4); // product revision level
  17.417 +          PINQUIRYDATA id = (PINQUIRYDATA)DataBuffer;
  17.418 +          id->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
  17.419 +          id->RemovableMedia = 1;
  17.420 +          id->ANSIVersion = 3;
  17.421 +          id->ResponseDataFormat = 0;
  17.422 +          id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
  17.423 +          id->CommandQueue = 1;
  17.424 +          memcpy(id->VendorId, "XEN     ", 8); // vendor id
  17.425 +          memcpy(id->ProductId, "PV CDROM        ", 16); // product id
  17.426 +          memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
  17.427          }
  17.428          else
  17.429          {
  17.430 @@ -708,18 +765,16 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  17.431              break;
  17.432            default:
  17.433              KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", Srb->Cdb[2]));
  17.434 -            Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  17.435 +            Srb->SrbStatus = SRB_STATUS_ERROR;
  17.436              break;
  17.437            }
  17.438          }
  17.439          break;
  17.440        default:
  17.441          KdPrint((__DRIVER_NAME "     Unknown DeviceType %02x requested\n", xvdd->device_type));
  17.442 -        Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  17.443 +        Srb->SrbStatus = SRB_STATUS_ERROR;
  17.444          break;
  17.445        }
  17.446 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  17.447 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  17.448        break;
  17.449      case SCSIOP_READ_CAPACITY:
  17.450        //KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
  17.451 @@ -735,57 +790,30 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  17.452        DataBuffer[7] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
  17.453        Srb->ScsiStatus = 0;
  17.454        Srb->SrbStatus = SRB_STATUS_SUCCESS;
  17.455 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  17.456 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  17.457        break;
  17.458      case SCSIOP_MODE_SENSE:
  17.459 -      //KdPrint((__DRIVER_NAME "     Command = MODE_SENSE (DBD = %d, PC = %d, Page Code = %02x)\n", Srb->Cdb[1] & 0x10, Srb->Cdb[2] & 0xC0, Srb->Cdb[2] & 0x3F));
  17.460 -      //KdPrint((__DRIVER_NAME "     Length = %d\n", Srb->DataTransferLength));
  17.461 -
  17.462 -      Srb->ScsiStatus = 0;
  17.463 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;
  17.464 -      Srb->DataTransferLength = 0;
  17.465 -      DataBuffer = Srb->DataBuffer;
  17.466 -      RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
  17.467 -      switch(cdb->MODE_SENSE.PageCode)
  17.468 -      {
  17.469 -      case MODE_SENSE_RETURN_ALL:
  17.470 -        //Ptr = (UCHAR *)Srb->DataBuffer;
  17.471 -        for (i = 0; i < MODE_SENSE_RETURN_ALL; i++)
  17.472 -        {
  17.473 -          if (XenVbd_FillModePage(xvdd, cdb->MODE_SENSE.PageCode, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Srb->DataTransferLength))
  17.474 -          {
  17.475 -            break;
  17.476 -          }
  17.477 -        }
  17.478 -        break;
  17.479 -      default:
  17.480 -        XenVbd_FillModePage(xvdd, cdb->MODE_SENSE.PageCode, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Srb->DataTransferLength);
  17.481 -        break;
  17.482 -      }
  17.483 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  17.484 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  17.485 +      KdPrint((__DRIVER_NAME "     Command = MODE_SENSE (DBD = %d, PC = %d, Page Code = %02x)\n", Srb->Cdb[1] & 0x10, Srb->Cdb[2] & 0xC0, Srb->Cdb[2] & 0x3F));
  17.486 +      KdPrint((__DRIVER_NAME "     Length = %d\n", Srb->DataTransferLength));
  17.487 +      XenVbd_FillModePage(xvdd, Srb);
  17.488        break;
  17.489      case SCSIOP_WRITE:
  17.490      case SCSIOP_READ:
  17.491        //KdPrint((__DRIVER_NAME "     Command = READ/WRITE\n"));
  17.492        XenVbd_PutSrbOnRing(xvdd, Srb, 0);
  17.493 -      if (!xvdd->shadow_free)
  17.494 -        ScsiPortNotification(NextRequest, DeviceExtension);
  17.495        break;
  17.496      case SCSIOP_VERIFY:
  17.497        // Should we do more here?
  17.498        KdPrint((__DRIVER_NAME "     Command = VERIFY\n"));
  17.499 -      Srb->SrbStatus = SRB_STATUS_SUCCESS; //SRB_STATUS_INVALID_REQUEST;
  17.500 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);      
  17.501 -      ScsiPortNotification(NextLuRequest, DeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun);
  17.502 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
  17.503        break;
  17.504      case SCSIOP_REPORT_LUNS:
  17.505        KdPrint((__DRIVER_NAME "     Command = REPORT_LUNS\n"));
  17.506 -      Srb->SrbStatus = SRB_STATUS_SUCCESS; //SRB_STATUS_INVALID_REQUEST;
  17.507 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  17.508 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  17.509 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;;
  17.510        break;
  17.511 +    case SCSIOP_REQUEST_SENSE:
  17.512 +      XenVbd_MakeSense(xvdd, Srb, xvdd->last_sense_key);
  17.513 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
  17.514 +      break;      
  17.515      case SCSIOP_READ_TOC:
  17.516        DataBuffer = Srb->DataBuffer;
  17.517  //      DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
  17.518 @@ -825,43 +853,60 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  17.519        case READ_TOC_FORMAT_FULL_TOC:
  17.520        case READ_TOC_FORMAT_PMA:
  17.521        case READ_TOC_FORMAT_ATIP:
  17.522 -        Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  17.523 +        Srb->SrbStatus = SRB_STATUS_ERROR;
  17.524          break;
  17.525        }
  17.526 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  17.527 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  17.528        break;
  17.529      case SCSIOP_START_STOP_UNIT:
  17.530        KdPrint((__DRIVER_NAME "     Command = SCSIOP_START_STOP_UNIT\n"));
  17.531        Srb->SrbStatus = SRB_STATUS_SUCCESS;
  17.532 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  17.533 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  17.534 +      break;
  17.535 +    case SCSIOP_RESERVE_UNIT:
  17.536 +      KdPrint((__DRIVER_NAME "     Command = SCSIOP_RESERVE_UNIT\n"));
  17.537 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
  17.538 +      break;
  17.539 +    case SCSIOP_RELEASE_UNIT:
  17.540 +      KdPrint((__DRIVER_NAME "     Command = SCSIOP_RELEASE_UNIT\n"));
  17.541 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
  17.542        break;
  17.543      default:
  17.544        KdPrint((__DRIVER_NAME "     Unhandled EXECUTE_SCSI Command = %02X\n", Srb->Cdb[0]));
  17.545 -      Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  17.546 +      Srb->SrbStatus = SRB_STATUS_ERROR;
  17.547 +      break;
  17.548 +    }
  17.549 +    if (Srb->SrbStatus == SRB_STATUS_ERROR)
  17.550 +    {
  17.551 +      if (xvdd->last_sense_key == SCSI_SENSE_NO_SENSE)
  17.552 +        xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
  17.553 +      Srb->ScsiStatus = 0x02;
  17.554 +      XenVbd_MakeAutoSense(xvdd, Srb);
  17.555        ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  17.556 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  17.557 -      break;
  17.558 +      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  17.559 +    }
  17.560 +    else if (Srb->SrbStatus != SRB_STATUS_PENDING)
  17.561 +    {
  17.562 +      xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
  17.563 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  17.564 +      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  17.565      }
  17.566      break;
  17.567    case SRB_FUNCTION_IO_CONTROL:
  17.568      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_IO_CONTROL\n"));
  17.569      Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  17.570      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  17.571 -    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  17.572 +    ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  17.573      break;
  17.574    case SRB_FUNCTION_FLUSH:
  17.575      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH\n"));
  17.576      Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  17.577      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  17.578 -    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  17.579 +    ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  17.580      break;
  17.581    default:
  17.582      KdPrint((__DRIVER_NAME "     Unhandled Srb->Function = %08X\n", Srb->Function));
  17.583      Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  17.584      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  17.585 -    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  17.586 +    ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  17.587      break;
  17.588    }
  17.589  
  17.590 @@ -917,6 +962,7 @@ XenVbd_HwScsiAdapterControl(PVOID Device
  17.591      KdPrint((__DRIVER_NAME "     ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
  17.592      SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
  17.593      SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
  17.594 +    SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
  17.595      break;
  17.596    case ScsiStopAdapter:
  17.597      KdPrint((__DRIVER_NAME "     ScsiStopAdapter\n"));
  17.598 @@ -952,6 +998,7 @@ XenVbd_FillInitCallbacks(PHW_INITIALIZAT
  17.599    HwInitializationData->HwInterrupt = XenVbd_HwScsiInterrupt;
  17.600    HwInitializationData->HwFindAdapter = XenVbd_HwScsiFindAdapter;
  17.601    HwInitializationData->HwResetBus = XenVbd_HwScsiResetBus;
  17.602 +  HwInitializationData->HwDmaStarted = NULL;
  17.603    HwInitializationData->HwAdapterState = XenVbd_HwScsiAdapterState;
  17.604    HwInitializationData->HwAdapterControl = XenVbd_HwScsiAdapterControl;
  17.605  
    18.1 --- a/xenvbd/xenvbd.c	Tue May 27 22:46:06 2008 +1000
    18.2 +++ b/xenvbd/xenvbd.c	Sat May 31 22:35:41 2008 +1000
    18.3 @@ -171,15 +171,15 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
    18.4  
    18.5    HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
    18.6    HwInitializationData.AdapterInterfaceType = Internal;
    18.7 -  HwInitializationData.HwDmaStarted = NULL;
    18.8    HwInitializationData.DeviceExtensionSize = sizeof(XENVBD_DEVICE_DATA);
    18.9    HwInitializationData.SpecificLuExtensionSize = 0;
   18.10 -  HwInitializationData.SrbExtensionSize = UNALIGNED_DOUBLE_BUFFER_SIZE;
   18.11 +  /* SrbExtension is not always aligned to a page boundary, so we add PAGE_SIZE-1 to it to make sure we have at least UNALIGNED_DOUBLE_BUFFER_SIZE bytes of page aligned memory */
   18.12 +  HwInitializationData.SrbExtensionSize = UNALIGNED_DOUBLE_BUFFER_SIZE + PAGE_SIZE - 1;
   18.13    HwInitializationData.NumberOfAccessRanges = 1;
   18.14    HwInitializationData.MapBuffers = TRUE;
   18.15    HwInitializationData.NeedPhysicalAddresses = FALSE;
   18.16 -  HwInitializationData.TaggedQueuing = TRUE;
   18.17 -  HwInitializationData.AutoRequestSense = FALSE;
   18.18 +  HwInitializationData.TaggedQueuing = FALSE;
   18.19 +  HwInitializationData.AutoRequestSense = TRUE;
   18.20    HwInitializationData.MultipleRequestPerLu = TRUE;
   18.21    HwInitializationData.ReceiveEvent = FALSE;
   18.22    HwInitializationData.VendorIdLength = 0;
    19.1 --- a/xenvbd/xenvbd.h	Tue May 27 22:46:06 2008 +1000
    19.2 +++ b/xenvbd/xenvbd.h	Sat May 31 22:35:41 2008 +1000
    19.3 @@ -95,6 +95,7 @@ struct
    19.4    blkif_shadow_t shadows[SHADOW_ENTRIES];
    19.5    USHORT shadow_free_list[SHADOW_ENTRIES];
    19.6    USHORT shadow_free;
    19.7 +  USHORT shadow_min_free;
    19.8  
    19.9    grant_ref_t grant_free_list[GRANT_ENTRIES];
   19.10    USHORT grant_free;
   19.11 @@ -106,12 +107,14 @@ struct
   19.12    };
   19.13    int ring_detect_state;
   19.14    BOOLEAN use_other;
   19.15 +  UCHAR last_sense_key;
   19.16    blkif_response_t tmp_rep;
   19.17    XENVBD_DEVICETYPE device_type;
   19.18    DISK_GEOMETRY Geometry;
   19.19    ULONG bytes_per_sector;
   19.20    ULONGLONG total_sectors;
   19.21    XENPCI_VECTORS vectors;
   19.22 +  PSCSI_REQUEST_BLOCK pending_srb;
   19.23  } typedef XENVBD_DEVICE_DATA, *PXENVBD_DEVICE_DATA;
   19.24  
   19.25  VOID