win-pvdrivers

changeset 26:d026b7958f07 scsiport

forgot to include some files!
author James Harper <james.harper@bendigoit.com.au>
date Fri Nov 30 21:33:49 2007 +1100 (2007-11-30)
parents 988042e3f1b0
children 37c64fba5fc7
files target/xenvbdbus.inf target/xenvbddev.inf xenvbdbus/makefile xenvbdbus/sources xenvbdbus/xenvbdbus.c xenvbdbus/xenvbdbus.h xenvbddev/makefile xenvbddev/sources xenvbddev/xenvbddev.c xenvbddev/xenvbddev.h
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/target/xenvbdbus.inf	Fri Nov 30 21:33:49 2007 +1100
     1.3 @@ -0,0 +1,75 @@
     1.4 +[Version]
     1.5 +Signature="$WINDOWS NT$"
     1.6 +Class=System
     1.7 +ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318}
     1.8 +Provider=%JAMESHARPER%
     1.9 +DriverVer=11/30/2007,0.3.0.114
    1.10 +
    1.11 +[DestinationDirs]
    1.12 +DefaultDestDir = 12
    1.13 +CoInstaller_CopyFiles = 11
    1.14 +
    1.15 +[ControlFlags]
    1.16 +ExcludeFromSelect=*
    1.17 +
    1.18 +[Manufacturer]
    1.19 +%JAMESHARPER%=JAMESHARPER,NTx86
    1.20 +
    1.21 +[JAMESHARPER]
    1.22 +%XenVbdBus.DRVDESC%=XenVbdBus_Inst, XEN\VBD
    1.23 +
    1.24 +[JAMESHARPER.NTx86]
    1.25 +%XenVbdBus.DRVDESC%=XenVbdBus_Inst, XEN\VBD
    1.26 +
    1.27 +[XenVbdBus_Inst.NT]
    1.28 +CopyFiles=XenVbdBus.CopyFiles
    1.29 +
    1.30 +[XenVbdBus.CopyFiles]
    1.31 +xenvbdbus.sys
    1.32 +
    1.33 +[SourceDisksFiles]
    1.34 +xenvbdbus.sys=1
    1.35 +WdfCoinstaller01005.dll=1,,
    1.36 +
    1.37 +[SourceDisksNames.x86]
    1.38 +1=%DISK_NAME%,,,\i386
    1.39 +
    1.40 +[XenVbdBus_Inst.Services]
    1.41 +AddService=XenVbdBus,2,XenVbdBus_Service 
    1.42 +
    1.43 +[XenVbdBus_Inst.NT.Services]
    1.44 +AddService=XenVbdBus,2,XenVbdBus_Service 
    1.45 +
    1.46 +[XenVbdBus_Service]
    1.47 +DisplayName    = %XenVbdBus.SVCDESC%                            
    1.48 +ServiceType    = 1
    1.49 +StartType      = 0
    1.50 +ErrorControl   = 1
    1.51 +LoadOrderGroup = WdfLoadGroup
    1.52 +ServiceBinary  = %12%\xenvbdbus.sys                            
    1.53 +AddReg = XenVbdBus_Service_AddReg
    1.54 +
    1.55 +[XenVbdBus_Service_AddReg]
    1.56 +HKR,"Parameters\PnpInterface", "15", 0x00010001, 0x00000001
    1.57 +
    1.58 +[XenVbdBus_Inst.NT.CoInstallers]
    1.59 +AddReg=CoInstaller_AddReg
    1.60 +CopyFiles=CoInstaller_CopyFiles
    1.61 +
    1.62 +[CoInstaller_CopyFiles]
    1.63 +WdfCoinstaller01005.dll,,,2
    1.64 +
    1.65 +[CoInstaller_AddReg]
    1.66 +HKR,,CoInstallers32,0x00010000, "WdfCoinstaller01005.dll,WdfCoInstaller"
    1.67 +
    1.68 +[XenVbdBus_Inst.NT.Wdf]
    1.69 +KmdfService = xenvbdbus, xenvbdbus_wdfsect
    1.70 +
    1.71 +[xenvbdbus_wdfsect]
    1.72 +KmdfLibraryVersion = 1.0
    1.73 +
    1.74 +[Strings]
    1.75 +JAMESHARPER = "James Harper"
    1.76 +XenVbdBus.SVCDESC = "Xen Block Device Bus Driver"
    1.77 +XenVbdBus.DRVDESC = "Xen Block Device Bus Driver"
    1.78 +DISK_NAME = "Xen Block Device Bus Driver Install Disk"
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/target/xenvbddev.inf	Fri Nov 30 21:33:49 2007 +1100
     2.3 @@ -0,0 +1,76 @@
     2.4 +[Version]
     2.5 +Signature="$WINDOWS NT$"
     2.6 +Class=SCSIAdapter
     2.7 +ClassGuid={4D36E97B-E325-11CE-BFC1-08002BE10318}
     2.8 +Provider=%JAMESHARPER%
     2.9 +DriverVer=11/30/2007,0.3.0.59
    2.10 +
    2.11 +[DestinationDirs]
    2.12 +DefaultDestDir = 12
    2.13 +CoInstaller_CopyFiles = 11
    2.14 +
    2.15 +[ControlFlags]
    2.16 +ExcludeFromSelect=*
    2.17 +
    2.18 +[Manufacturer]
    2.19 +%JAMESHARPER%=JAMESHARPER,NTx86
    2.20 +
    2.21 +[JAMESHARPER]
    2.22 +%XenVbdDev.DRVDESC%=XenVbdDev_Inst, XEN\VBDDEV
    2.23 +
    2.24 +[JAMESHARPER.NTx86]
    2.25 +%XenVbdDev.DRVDESC%=XenVbdDev_Inst, XEN\VBDDEV
    2.26 +
    2.27 +[XenVbdDev_Inst.NT]
    2.28 +CopyFiles=XenVbdDev.CopyFiles
    2.29 +
    2.30 +[XenVbdDev.CopyFiles]
    2.31 +XenVbdDev.sys
    2.32 +
    2.33 +[SourceDisksFiles]
    2.34 +XenVbdDev.sys=1
    2.35 +WdfCoinstaller01005.dll=1,,
    2.36 +
    2.37 +[SourceDisksNames.x86]
    2.38 +1 = %DISK_NAME%,,,\i386
    2.39 +
    2.40 +[XenVbdDev_Inst.Services]
    2.41 +AddService=XenVbdDev,2,XenVbdDev_Service 
    2.42 +
    2.43 +[XenVbdDev_Inst.NT.Services]
    2.44 +AddService=XenVbdDev,2,XenVbdDev_Service 
    2.45 +
    2.46 +[XenVbdDev_Service]
    2.47 +DisplayName    = %XenVbdDev.SVCDESC%                            
    2.48 +ServiceType    = 1
    2.49 +StartType      = 0
    2.50 +ErrorControl   = 1
    2.51 +LoadOrderGroup = WdfLoadGroup
    2.52 +ServiceBinary  = %12%\XenVbdDev.sys                            
    2.53 +AddReg = XenVbdDev_Service_AddReg
    2.54 +
    2.55 +[XenVbdDev_Service_AddReg]
    2.56 +;HKR,"Parameters\PnpInterface", "15", 0x00010001, 0x00000001
    2.57 +HKR,"Parameters\PnpInterface", "0", 0x00010001, 0x00000001
    2.58 +
    2.59 +[XenVbdBus_Inst.NT.CoInstallers]
    2.60 +AddReg=CoInstaller_AddReg
    2.61 +CopyFiles=CoInstaller_CopyFiles
    2.62 +
    2.63 +[CoInstaller_CopyFiles]
    2.64 +WdfCoinstaller01005.dll,,,2
    2.65 +
    2.66 +[CoInstaller_AddReg]
    2.67 +HKR,,CoInstallers32,0x00010000, "WdfCoinstaller01005.dll,WdfCoInstaller"
    2.68 +
    2.69 +[XenVbdBus_Inst.NT.Wdf]
    2.70 +KmdfService = xenvbdbus, xenvbdbus_wdfsect
    2.71 +
    2.72 +[xenvbdbus_wdfsect]
    2.73 +KmdfLibraryVersion = 1.0
    2.74 +
    2.75 +[Strings]
    2.76 +JAMESHARPER = "James Harper"
    2.77 +XenVbdDev.SVCDESC = "Xen Block Device Driver"
    2.78 +XenVbdDev.DRVDESC = "Xen Block Device Driver"
    2.79 +DISK_NAME = "Xen Block Device Driver Install Disk"
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xenvbdbus/makefile	Fri Nov 30 21:33:49 2007 +1100
     3.3 @@ -0,0 +1,1 @@
     3.4 +!INCLUDE $(NTMAKEENV)\makefile.def
     3.5 \ No newline at end of file
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xenvbdbus/sources	Fri Nov 30 21:33:49 2007 +1100
     4.3 @@ -0,0 +1,13 @@
     4.4 +TARGETNAME=XENVBDBUS
     4.5 +TARGETTYPE=DRIVER
     4.6 +TARGETPATH=..\Target
     4.7 +
     4.8 +MSC_WARNING_LEVEL=/W4
     4.9 +
    4.10 +INCLUDES = ..\common\include;..\common\include\public
    4.11 +
    4.12 +NO_BINPLACE=1
    4.13 +KMDF_VERSION=1
    4.14 +TARGETLIBS=$(DDK_LIB_PATH)\ntstrsafe.lib
    4.15 +
    4.16 +SOURCES=xenvbdbus.c
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xenvbdbus/xenvbdbus.c	Fri Nov 30 21:33:49 2007 +1100
     5.3 @@ -0,0 +1,942 @@
     5.4 +#include "xenvbdbus.h"
     5.5 +#include <io/blkif.h>
     5.6 +#include <srb.h>
     5.7 +#include <scsi.h>
     5.8 +#include <ntddscsi.h>
     5.9 +#include <ntdddisk.h>
    5.10 +#include <stdlib.h>
    5.11 +#include <xen_public.h>
    5.12 +#include <io/xenbus.h>
    5.13 +#include <ntddft.h>
    5.14 +
    5.15 +#define wmb() KeMemoryBarrier()
    5.16 +#define mb() KeMemoryBarrier()
    5.17 +
    5.18 +DRIVER_INITIALIZE DriverEntry;
    5.19 +
    5.20 +/*static NTSTATUS
    5.21 +XenPCI_FilterAddResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList);
    5.22 +static NTSTATUS
    5.23 +XenPCI_RemoveAddedResources(WDFDEVICE Device, WDFCMRESLIST ResourcesRaw, WDFCMRESLIST ResourcesTranslated);
    5.24 +*/
    5.25 +static NTSTATUS
    5.26 +XenVbdBus_AddDevice(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit);
    5.27 +static NTSTATUS
    5.28 +XenVbdBus_PrepareHardware(WDFDEVICE hDevice, WDFCMRESLIST Resources, WDFCMRESLIST ResourcesTranslated);
    5.29 +static NTSTATUS
    5.30 +XenVbdBus_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated);
    5.31 +static NTSTATUS
    5.32 +XenVbdBus_D0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
    5.33 +static NTSTATUS
    5.34 +XenVbdBus_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
    5.35 +static NTSTATUS
    5.36 +XenVbdBus_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState);
    5.37 +static NTSTATUS
    5.38 +XenVbdBus_DeviceUsageNotification(WDFDEVICE Device, WDF_SPECIAL_FILE_TYPE NotificationType, BOOLEAN IsInNotificationPath);
    5.39 +
    5.40 +static NTSTATUS
    5.41 +XenVbdBus_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit);
    5.42 +static NTSTATUS
    5.43 +XenVbdBus_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
    5.44 +
    5.45 +static VOID
    5.46 +XenVbdBus_HotPlugHandler(char *Path, PVOID Data);
    5.47 +
    5.48 +static NTSTATUS
    5.49 +XenVbd_Child_PreprocessWdmIrpPnp(WDFDEVICE Device, PIRP Irp);
    5.50 +
    5.51 +#ifdef ALLOC_PRAGMA
    5.52 +#pragma alloc_text (INIT, DriverEntry)
    5.53 +#pragma alloc_text (PAGE, XenVbdBus_AddDevice)
    5.54 +#endif
    5.55 +
    5.56 +LIST_ENTRY DeviceListHead;
    5.57 +XEN_IFACE_EVTCHN EvtChnInterface;
    5.58 +XEN_IFACE_XENBUS XenBusInterface;
    5.59 +XEN_IFACE_XEN XenInterface;
    5.60 +XEN_IFACE_GNTTBL GntTblInterface;
    5.61 +
    5.62 +static BOOLEAN AutoEnumerate;
    5.63 +
    5.64 +NTSTATUS
    5.65 +DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
    5.66 +{
    5.67 +  WDF_DRIVER_CONFIG config;
    5.68 +  ULONG status;
    5.69 +  UNICODE_STRING RegKeyName;
    5.70 +  UNICODE_STRING RegValueName;
    5.71 +  HANDLE RegHandle;
    5.72 +  OBJECT_ATTRIBUTES RegObjectAttributes;
    5.73 +  char Buf[200];
    5.74 +  ULONG BufLen = 200;
    5.75 +  PKEY_VALUE_PARTIAL_INFORMATION KeyPartialValue;
    5.76 +  int State = 0;
    5.77 +  int StartPos = 0;
    5.78 +  WCHAR *SystemStartOptions;
    5.79 +  size_t SystemStartOptionsLen;
    5.80 +  size_t i;
    5.81 +
    5.82 +  KdPrint((__DRIVER_NAME " --> DriverEntry\n"));
    5.83 +
    5.84 +  WDF_DRIVER_CONFIG_INIT(&config, XenVbdBus_AddDevice);
    5.85 +  status = WdfDriverCreate(
    5.86 +                      DriverObject,
    5.87 +                      RegistryPath,
    5.88 +                      WDF_NO_OBJECT_ATTRIBUTES,
    5.89 +                      &config,
    5.90 +                      WDF_NO_HANDLE);
    5.91 +  if(!NT_SUCCESS(status))
    5.92 +  {
    5.93 +    KdPrint((__DRIVER_NAME " WdfDriverCreate failed with status 0x%08x\n", status));
    5.94 +  }
    5.95 +
    5.96 +  RtlInitUnicodeString(&RegKeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
    5.97 +  InitializeObjectAttributes(&RegObjectAttributes, &RegKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
    5.98 +  status = ZwOpenKey(&RegHandle, KEY_READ, &RegObjectAttributes);
    5.99 +  if(!NT_SUCCESS(status))
   5.100 +  {
   5.101 +    KdPrint((__DRIVER_NAME "     ZwOpenKey returned %08x\n", status));
   5.102 +  }
   5.103 +
   5.104 +  RtlInitUnicodeString(&RegValueName, L"SystemStartOptions");
   5.105 +  status = ZwQueryValueKey(RegHandle, &RegValueName, KeyValuePartialInformation, Buf, BufLen, &BufLen);
   5.106 +  if(!NT_SUCCESS(status))
   5.107 +  {
   5.108 +    KdPrint((__DRIVER_NAME "     ZwQueryKeyValue returned %08x\n", status));
   5.109 +  }
   5.110 +  //KdPrint((__DRIVER_NAME "     BufLen = %d\n", BufLen));
   5.111 +  KeyPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
   5.112 +  KdPrint((__DRIVER_NAME "     Buf = %ws\n", KeyPartialValue->Data));
   5.113 +  SystemStartOptions = (WCHAR *)KeyPartialValue->Data;
   5.114 +
   5.115 +  AutoEnumerate = FALSE;
   5.116 +
   5.117 +  RtlStringCbLengthW(SystemStartOptions, KeyPartialValue->DataLength, &SystemStartOptionsLen);
   5.118 +
   5.119 +  for (i = 0; i <= SystemStartOptionsLen/2; i++)
   5.120 +  {
   5.121 +    //KdPrint((__DRIVER_NAME "     pos = %d, state = %d, char = '%wc' (%d)\n", i, State, SystemStartOptions[i], SystemStartOptions[i]));
   5.122 +    
   5.123 +    switch (State)
   5.124 +    {
   5.125 +    case 0:
   5.126 +      if (SystemStartOptions[i] == L'G')
   5.127 +      {
   5.128 +        StartPos = i;
   5.129 +        State = 2;
   5.130 +      } else if (SystemStartOptions[i] != L' ')
   5.131 +      {
   5.132 +        State = 1;
   5.133 +      }
   5.134 +      break;
   5.135 +    case 1:
   5.136 +      if (SystemStartOptions[i] == L' ')
   5.137 +        State = 0;
   5.138 +      break;
   5.139 +    case 2:
   5.140 +      if (SystemStartOptions[i] == L'P')
   5.141 +        State = 3;
   5.142 +      else
   5.143 +        State = 0;
   5.144 +      break;
   5.145 +    case 3:
   5.146 +      if (SystemStartOptions[i] == L'L')
   5.147 +        State = 4;
   5.148 +      else
   5.149 +        State = 0;
   5.150 +      break;
   5.151 +    case 4:
   5.152 +      if (SystemStartOptions[i] == L'P')
   5.153 +        State = 5;
   5.154 +      else
   5.155 +        State = 0;
   5.156 +      break;
   5.157 +    case 5:
   5.158 +      if (SystemStartOptions[i] == L'V')
   5.159 +        State = 6;
   5.160 +      else
   5.161 +        State = 0;
   5.162 +      break;
   5.163 +    case 6:
   5.164 +      if (SystemStartOptions[i] == L' ' || SystemStartOptions[i] == 0)
   5.165 +        AutoEnumerate = TRUE;
   5.166 +      State = 0;
   5.167 +      break;
   5.168 +    }
   5.169 +  }
   5.170 +
   5.171 +  KdPrint((__DRIVER_NAME "     AutoEnumerate = %d\n", AutoEnumerate));
   5.172 +
   5.173 +  KdPrint((__DRIVER_NAME " <-- DriverEntry\n"));
   5.174 +
   5.175 +  return status;
   5.176 +}
   5.177 +
   5.178 +DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC828ABE9, 0x14CA, 0x4445, 0xBA, 0xA6, 0x82, 0xC2, 0x37, 0x6C, 0x65, 0x18);
   5.179 +
   5.180 +static WDFDEVICE GlobalDevice;
   5.181 +static PDEVICE_OBJECT Pdo;
   5.182 +
   5.183 +static NTSTATUS
   5.184 +XenVbdBus_AddDevice(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit)
   5.185 +{
   5.186 +  WDF_CHILD_LIST_CONFIG ChildListConfig;
   5.187 +  NTSTATUS status;
   5.188 +  WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
   5.189 +  PNP_BUS_INFORMATION BusInfo;
   5.190 +  
   5.191 +//  PWDF_FDO_EVENT_CALLBACKS FdoCallbacks;
   5.192 +
   5.193 +  UNREFERENCED_PARAMETER(Driver);
   5.194 +
   5.195 +  KdPrint((__DRIVER_NAME " --> DeviceAdd\n"));
   5.196 +
   5.197 +  Pdo = WdfFdoInitWdmGetPhysicalDevice(DeviceInit);
   5.198 +
   5.199 +  //WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
   5.200 +  WDF_CHILD_LIST_CONFIG_INIT(&ChildListConfig, sizeof(XENVBDBUS_DEVICE_IDENTIFICATION_DESCRIPTION), XenVbdBus_ChildListCreateDevice);
   5.201 +  WdfFdoInitSetDefaultChildListConfig(DeviceInit, &ChildListConfig, WDF_NO_OBJECT_ATTRIBUTES);
   5.202 +
   5.203 +  WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_CONTROLLER);
   5.204 +  //WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);
   5.205 +  WdfDeviceInitSetExclusive(DeviceInit, FALSE);
   5.206 +
   5.207 +//  WDF_FDO_EVENT_CALLBACKS_INIT(&FdoCallbacks);
   5.208 +//  //FdoCallbacks.EvtDeviceFilterRemoveResourceRequirements = XenVbdBus_FilterRemoveResourceRequirements;
   5.209 +//  FdoCallbacks.EvtDeviceFilterAddResourceRequirements = XenVbdBus_FilterAddResourceRequirements;
   5.210 +//  FdoCallbacks.EvtDeviceRemoveAddedResources = XenVbdBus_RemoveAddedResources;
   5.211 +//  WdfFdoInitSetEventCallbacks(DeviceInit, &FdoCallbacks);
   5.212 +
   5.213 +  WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
   5.214 +  pnpPowerCallbacks.EvtDevicePrepareHardware = XenVbdBus_PrepareHardware;
   5.215 +  pnpPowerCallbacks.EvtDeviceReleaseHardware = XenVbdBus_ReleaseHardware;
   5.216 +  pnpPowerCallbacks.EvtDeviceD0Entry = XenVbdBus_D0Entry;
   5.217 +  pnpPowerCallbacks.EvtDeviceD0EntryPostInterruptsEnabled = XenVbdBus_D0EntryPostInterruptsEnabled;
   5.218 +  pnpPowerCallbacks.EvtDeviceD0Exit = XenVbdBus_D0Exit;
   5.219 +  pnpPowerCallbacks.EvtDeviceUsageNotification = XenVbdBus_DeviceUsageNotification;
   5.220 +  WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
   5.221 +
   5.222 +  /*initialize storage for the device context*/
   5.223 +  //WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, XENVBDBUS_DEVICE_DATA);
   5.224 +
   5.225 +  //WdfDeviceInitSetPowerNotPageable(DeviceInit);
   5.226 +
   5.227 +  /*create a device instance.*/
   5.228 +  status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &GlobalDevice);  
   5.229 +  if(!NT_SUCCESS(status))
   5.230 +  {
   5.231 +    KdPrint((__DRIVER_NAME "WdfDeviceCreate failed with status 0x%08x\n", status));
   5.232 +    return status;
   5.233 +  }
   5.234 +
   5.235 +  BusInfo.BusTypeGuid = GUID_XENPCI_DEVCLASS;
   5.236 +  BusInfo.LegacyBusType = Internal; //PNPBus;
   5.237 +  BusInfo.BusNumber = 0;
   5.238 +
   5.239 +  WdfDeviceSetBusInformationForChildren(GlobalDevice, &BusInfo);
   5.240 +
   5.241 +  WdfDeviceSetSpecialFileSupport(GlobalDevice, WdfSpecialFilePaging, TRUE);
   5.242 +  WdfDeviceSetSpecialFileSupport(GlobalDevice, WdfSpecialFileHibernation, TRUE);
   5.243 +  WdfDeviceSetSpecialFileSupport(GlobalDevice, WdfSpecialFileDump, TRUE);
   5.244 +  
   5.245 +  status = STATUS_SUCCESS;
   5.246 +
   5.247 +  KdPrint((__DRIVER_NAME " <-- DeviceAdd\n"));
   5.248 +  return status;
   5.249 +}
   5.250 +
   5.251 +static NTSTATUS
   5.252 +XenVbdBus_PrepareHardware(
   5.253 +  IN WDFDEVICE    Device,
   5.254 +  IN WDFCMRESLIST ResourceList,
   5.255 +  IN WDFCMRESLIST ResourceListTranslated)
   5.256 +{
   5.257 +  NTSTATUS status = STATUS_SUCCESS;
   5.258 +
   5.259 +  UNREFERENCED_PARAMETER(ResourceList);
   5.260 +  UNREFERENCED_PARAMETER(ResourceListTranslated);
   5.261 +
   5.262 +  //KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware\n"));
   5.263 +
   5.264 +  status = WdfFdoQueryForInterface(Device, &GUID_XEN_IFACE_EVTCHN, (PINTERFACE) &EvtChnInterface, sizeof(XEN_IFACE_EVTCHN), 1, NULL);
   5.265 +  if(!NT_SUCCESS(status))
   5.266 +  {
   5.267 +    KdPrint((__DRIVER_NAME "     WdfFdoQueryForInterface (EvtChn) failed with status 0x%08x\n", status));
   5.268 +  }
   5.269 +
   5.270 +  status = WdfFdoQueryForInterface(Device, &GUID_XEN_IFACE_XENBUS, (PINTERFACE)&XenBusInterface, sizeof(XEN_IFACE_XENBUS), 1, NULL);
   5.271 +  if(!NT_SUCCESS(status))
   5.272 +  {
   5.273 +    KdPrint((__DRIVER_NAME "     WdfFdoQueryForInterface (XenBus) failed with status 0x%08x\n", status));
   5.274 +  }
   5.275 +
   5.276 +  status = WdfFdoQueryForInterface(Device, &GUID_XEN_IFACE_XEN, (PINTERFACE)&XenInterface, sizeof(XEN_IFACE_XEN), 1, NULL);
   5.277 +  if(!NT_SUCCESS(status))
   5.278 +  {
   5.279 +    KdPrint((__DRIVER_NAME "     WdfFdoQueryForInterface (Xen) failed with status 0x%08x\n", status));
   5.280 +  }
   5.281 +
   5.282 +  status = WdfFdoQueryForInterface(Device, &GUID_XEN_IFACE_GNTTBL, (PINTERFACE)&GntTblInterface, sizeof(XEN_IFACE_GNTTBL), 1, NULL);
   5.283 +  if(!NT_SUCCESS(status))
   5.284 +  {
   5.285 +    KdPrint((__DRIVER_NAME "     WdfFdoQueryForInterface (GntTbl) failed with status 0x%08x\n", status));
   5.286 +  }
   5.287 +  
   5.288 +  //KdPrint((__DRIVER_NAME " <-- EvtDevicePrepareHardware\n"));
   5.289 +
   5.290 +  InitializeListHead(&DeviceListHead);
   5.291 +
   5.292 +  return status;
   5.293 +}
   5.294 +
   5.295 +static NTSTATUS
   5.296 +XenVbdBus_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated)
   5.297 +{
   5.298 +  UNREFERENCED_PARAMETER(Device);
   5.299 +  UNREFERENCED_PARAMETER(ResourcesTranslated);
   5.300 +
   5.301 +  // release interfaces here...
   5.302 +
   5.303 +  //XenVbdBus_Close();
   5.304 +
   5.305 +  return STATUS_SUCCESS;
   5.306 +}
   5.307 +
   5.308 +static NTSTATUS
   5.309 +XenVbdBus_D0Entry(
   5.310 +    IN WDFDEVICE  Device,
   5.311 +    IN WDF_POWER_DEVICE_STATE PreviousState
   5.312 +    )
   5.313 +{
   5.314 +  NTSTATUS status = STATUS_SUCCESS;
   5.315 +
   5.316 +  UNREFERENCED_PARAMETER(Device);
   5.317 +  UNREFERENCED_PARAMETER(PreviousState);
   5.318 +
   5.319 +  //KdPrint((__DRIVER_NAME " --> EvtDeviceD0Entry\n"));
   5.320 +
   5.321 +  //KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Entry\n"));
   5.322 +
   5.323 +  return status;
   5.324 +}
   5.325 +
   5.326 +static int EnumeratedDevices;
   5.327 +static KEVENT WaitDevicesEvent;
   5.328 +
   5.329 +static NTSTATUS
   5.330 +XenVbdBus_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState)
   5.331 +{
   5.332 +  //OBJECT_ATTRIBUTES oa;
   5.333 +  NTSTATUS status = STATUS_SUCCESS;
   5.334 +  //HANDLE nothing;
   5.335 +  //char *response;
   5.336 +  PXENPCI_XEN_DEVICE_DATA PdoDeviceData;
   5.337 +  char **VbdDevices;
   5.338 +  char *msg;
   5.339 +  char buffer[128];
   5.340 +  int i;
   5.341 +  LARGE_INTEGER WaitTimeout;
   5.342 +
   5.343 +  UNREFERENCED_PARAMETER(Device);
   5.344 +  UNREFERENCED_PARAMETER(PreviousState);
   5.345 +
   5.346 +  //KdPrint((__DRIVER_NAME " --> EvtDeviceD0EntryPostInterruptsEnabled\n"));
   5.347 +
   5.348 +  PdoDeviceData = (PXENPCI_XEN_DEVICE_DATA)Pdo->DeviceExtension; //GetXenDeviceData(Device);
   5.349 +
   5.350 +  //KdPrint((__DRIVER_NAME "     BasePath = %s\n", PdoDeviceData->BasePath));
   5.351 +  PdoDeviceData->WatchHandler = XenVbdBus_HotPlugHandler;
   5.352 +
   5.353 +  EnumeratedDevices = 0;
   5.354 +  KeInitializeEvent(&WaitDevicesEvent, SynchronizationEvent, FALSE);  
   5.355 +
   5.356 +  // TODO: Should probably do this in an EvtChildListScanForChildren
   5.357 +  if (AutoEnumerate)
   5.358 +  {
   5.359 +    msg = XenBusInterface.List(XBT_NIL, "device/vbd", &VbdDevices);
   5.360 +    if (!msg) {
   5.361 +      for (i = 0; VbdDevices[i]; i++)
   5.362 +      {
   5.363 +        KdPrint((__DRIVER_NAME "     found existing vbd device %s\n", VbdDevices[i]));
   5.364 +        RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/vbd/%s/state", VbdDevices[i]);
   5.365 +        XenVbdBus_HotPlugHandler(buffer, NULL);
   5.366 +        //ExFreePoolWithTag(bdDevices[i], XENPCI_POOL_TAG);
   5.367 +      }
   5.368 +      KdPrint((__DRIVER_NAME "     Waiting for devices to be enumerated\n"));
   5.369 +      while (EnumeratedDevices != i)
   5.370 +      {
   5.371 +        WaitTimeout.QuadPart = -600000000;
   5.372 +        if (KeWaitForSingleObject(&WaitDevicesEvent, Executive, KernelMode, FALSE, &WaitTimeout) == STATUS_TIMEOUT)
   5.373 +        {
   5.374 +          KdPrint((__DRIVER_NAME "     Wait timed out\n"));
   5.375 +          break;
   5.376 +        }
   5.377 +        KdPrint((__DRIVER_NAME "     %d out of %d devices enumerated\n", EnumeratedDevices, i));
   5.378 +      }  
   5.379 +    }
   5.380 +  }
   5.381 +
   5.382 +  //KdPrint((__DRIVER_NAME " <-- EvtDeviceD0EntryPostInterruptsEnabled\n"));
   5.383 +
   5.384 +  return status;
   5.385 +}
   5.386 +
   5.387 +static NTSTATUS
   5.388 +XenVbdBus_D0Exit(
   5.389 +    IN WDFDEVICE Device,
   5.390 +    IN WDF_POWER_DEVICE_STATE  TargetState
   5.391 +    )
   5.392 +{
   5.393 +  NTSTATUS status = STATUS_SUCCESS;
   5.394 +  //char *response;
   5.395 +
   5.396 +  UNREFERENCED_PARAMETER(Device);
   5.397 +  UNREFERENCED_PARAMETER(TargetState);
   5.398 +
   5.399 +  //KdPrint((__DRIVER_NAME " --> EvtDeviceD0Exit\n"));
   5.400 +
   5.401 +  //response = XenBusInterface.RemWatch(XBT_NIL, XenBusInterface.InterfaceHeader.Context, XenVbdBus_HotPlugHandler, NULL);
   5.402 +
   5.403 +  //KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Exit\n"));
   5.404 +
   5.405 +  return status;
   5.406 +}
   5.407 +
   5.408 +static NTSTATUS
   5.409 +XenVbdBus_DeviceUsageNotification(WDFDEVICE Device, WDF_SPECIAL_FILE_TYPE NotificationType, BOOLEAN IsInNotificationPath)
   5.410 +{
   5.411 +  KdPrint((__DRIVER_NAME " --> DeviceUsageNotification\n"));
   5.412 +
   5.413 +  switch (NotificationType)
   5.414 +  {
   5.415 +  case WdfSpecialFilePaging:
   5.416 +    KdPrint((__DRIVER_NAME "     NotificationType = WdfSpecialFilePaging, Using = %d\n", IsInNotificationPath));
   5.417 +    break;
   5.418 +  case WdfSpecialFileHibernation:
   5.419 +    KdPrint((__DRIVER_NAME "     NotificationType = WdfSpecialFileHibernation, Using = %d\n", IsInNotificationPath));
   5.420 +    break;
   5.421 +  case WdfSpecialFileDump:
   5.422 +    KdPrint((__DRIVER_NAME "     NotificationType = WdfSpecialFileDump, Using = %d\n", IsInNotificationPath));
   5.423 +    break;
   5.424 +  default:
   5.425 +    KdPrint((__DRIVER_NAME "     NotificationType = %d, Using = %d\n", NotificationType, IsInNotificationPath));
   5.426 +    break;
   5.427 +  }
   5.428 +  KdPrint((__DRIVER_NAME " <-- DeviceUsageNotification\n"));
   5.429 +
   5.430 +  return TRUE;
   5.431 +}
   5.432 +
   5.433 +static VOID 
   5.434 +XenVbdBus_IoDefault(
   5.435 +    IN WDFQUEUE  Queue,
   5.436 +    IN WDFREQUEST  Request
   5.437 +    )
   5.438 +{
   5.439 +  UNREFERENCED_PARAMETER(Queue);
   5.440 +
   5.441 +  //KdPrint((__DRIVER_NAME " --> EvtDeviceIoDefault\n"));
   5.442 +
   5.443 +  WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
   5.444 +
   5.445 +  //KdPrint((__DRIVER_NAME " <-- EvtDeviceIoDefault\n"));
   5.446 +}
   5.447 +
   5.448 +
   5.449 +static PMDL
   5.450 +AllocatePages(int Pages)
   5.451 +{
   5.452 +  PMDL Mdl;
   5.453 +  PVOID Buf;
   5.454 +
   5.455 +  Buf = ExAllocatePoolWithTag(NonPagedPool, Pages * PAGE_SIZE, XENVBDBUS_POOL_TAG);
   5.456 +  if (Buf == NULL)
   5.457 +  {
   5.458 +    KdPrint((__DRIVER_NAME "     AllocatePages Failed at ExAllocatePoolWithTag\n"));
   5.459 +  }
   5.460 +  Mdl = IoAllocateMdl(Buf, Pages * PAGE_SIZE, FALSE, FALSE, NULL);
   5.461 +  if (Mdl == NULL)
   5.462 +  {
   5.463 +    KdPrint((__DRIVER_NAME "     AllocatePages Failed at IoAllocateMdl\n"));
   5.464 +  }
   5.465 +  MmBuildMdlForNonPagedPool(Mdl);
   5.466 +  
   5.467 +  return Mdl;
   5.468 +}
   5.469 +
   5.470 +static PMDL
   5.471 +AllocatePage()
   5.472 +{
   5.473 +  return AllocatePages(1);
   5.474 +}
   5.475 +
   5.476 +static VOID
   5.477 +FreePages(PMDL Mdl)
   5.478 +{
   5.479 +  PVOID Buf = MmGetMdlVirtualAddress(Mdl);
   5.480 +  //KdPrint((__DRIVER_NAME "     FreePages Failed at IoAllocateMdl\n"));
   5.481 +  //KdPrint((__DRIVER_NAME "     FreePages Buf = %08x\n", Buf));
   5.482 +  IoFreeMdl(Mdl);
   5.483 +  ExFreePoolWithTag(Buf, XENVBDBUS_POOL_TAG);
   5.484 +}
   5.485 +
   5.486 +static VOID
   5.487 +XenVbdBus_Notify(PVOID Data)
   5.488 +{
   5.489 +  PXENVBDBUS_CHILD_DEVICE_DATA ChildDeviceData;
   5.490 +
   5.491 +  KdPrint((__DRIVER_NAME " --> XenVbdBus_Notify\n"));
   5.492 +
   5.493 +  ChildDeviceData = (PXENVBDBUS_CHILD_DEVICE_DATA)Data;
   5.494 +
   5.495 +  EvtChnInterface.Notify(ChildDeviceData->EventChannel);
   5.496 +
   5.497 +  KdPrint((__DRIVER_NAME " <-- XenVbdBus_Notify\n"));
   5.498 +}
   5.499 +
   5.500 +static BOOLEAN
   5.501 +XenVbdBus_Interrupt(PKINTERRUPT Interrupt, PVOID ServiceContext)
   5.502 +{
   5.503 +  PXENVBDBUS_CHILD_DEVICE_DATA ChildDeviceData;
   5.504 +
   5.505 +  UNREFERENCED_PARAMETER(Interrupt);
   5.506 +  // !!!RUNS AT DIRQL!!!
   5.507 +
   5.508 +  KdPrint((__DRIVER_NAME " --> XenVbd_Interrupt\n"));
   5.509 +
   5.510 +  ChildDeviceData = (PXENVBDBUS_CHILD_DEVICE_DATA)ServiceContext;
   5.511 +  if (ChildDeviceData->ScsiDeviceData->IsrRoutine != NULL)
   5.512 +    ChildDeviceData->ScsiDeviceData->IsrRoutine(ChildDeviceData->ScsiDeviceData->IsrContext);
   5.513 +  else
   5.514 +    KdPrint((__DRIVER_NAME "     Isr Not Set\n"));  
   5.515 +
   5.516 +  return STATUS_SUCCESS;
   5.517 +}
   5.518 +
   5.519 +static VOID
   5.520 +XenVbdBus_BackEndStateHandler(char *Path, PVOID Data)
   5.521 +{
   5.522 +  PXENVBDBUS_CHILD_DEVICE_DATA DeviceData;
   5.523 +  char TmpPath[128];
   5.524 +  char *Value;
   5.525 +  int NewState;
   5.526 +  grant_ref_t ref;
   5.527 +  blkif_sring_t *SharedRing;
   5.528 +  //ULONG PFN;
   5.529 +  XENVBDBUS_DEVICE_IDENTIFICATION_DESCRIPTION Description;
   5.530 +  NTSTATUS status;
   5.531 +
   5.532 +  DeviceData = (PXENVBDBUS_CHILD_DEVICE_DATA)Data;
   5.533 +
   5.534 +  XenBusInterface.Read(XBT_NIL, Path, &Value);
   5.535 +
   5.536 +  NewState = atoi(Value);
   5.537 +  switch (NewState)
   5.538 +  {
   5.539 +  case XenbusStateUnknown:
   5.540 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Unknown\n"));  
   5.541 +    break;
   5.542 +
   5.543 +  case XenbusStateInitialising:
   5.544 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialising\n"));  
   5.545 +    break;
   5.546 +
   5.547 +  case XenbusStateInitWait:
   5.548 +    KdPrint((__DRIVER_NAME "     Backend State Changed to InitWait\n"));  
   5.549 +
   5.550 +    // We create the Windows device node here
   5.551 +    WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&Description.Header, sizeof(Description));
   5.552 +    Description.DeviceData = DeviceData;
   5.553 +    DeviceData->EventChannel = EvtChnInterface.AllocUnbound(0);
   5.554 +    EvtChnInterface.Bind(DeviceData->EventChannel, XenVbdBus_Interrupt, DeviceData);
   5.555 +    
   5.556 +    DeviceData->SharedRingMDL = AllocatePage();
   5.557 +    SharedRing = (blkif_sring_t *)MmGetMdlVirtualAddress(DeviceData->SharedRingMDL);
   5.558 +    SHARED_RING_INIT(SharedRing);
   5.559 +
   5.560 +    DeviceData->ScsiDeviceDataMdl = AllocatePage();
   5.561 +    DeviceData->ScsiDeviceData = MmGetMdlVirtualAddress(DeviceData->ScsiDeviceDataMdl);
   5.562 +
   5.563 +    DeviceData->ScsiDeviceData->Magic = SCSI_DATA_MAGIC;
   5.564 +    FRONT_RING_INIT(&DeviceData->ScsiDeviceData->Ring, SharedRing, PAGE_SIZE);
   5.565 +    ref = GntTblInterface.GrantAccess(0, *MmGetMdlPfnArray(DeviceData->SharedRingMDL), FALSE);
   5.566 +    DeviceData->ScsiDeviceData->NotifyContext = DeviceData;
   5.567 +    DeviceData->ScsiDeviceData->NotifyRoutine = XenVbdBus_Notify;
   5.568 +    DeviceData->ScsiDeviceData->GntTblInterface = GntTblInterface;
   5.569 +
   5.570 +    RtlStringCbCopyA(TmpPath, 128, DeviceData->Path);
   5.571 +    RtlStringCbCatA(TmpPath, 128, "/ring-ref");
   5.572 +    XenBusInterface.Printf(XBT_NIL, TmpPath, "%d", ref);
   5.573 +
   5.574 +    RtlStringCbCopyA(TmpPath, 128, DeviceData->Path);
   5.575 +    RtlStringCbCatA(TmpPath, 128, "/event-channel");
   5.576 +    XenBusInterface.Printf(XBT_NIL, TmpPath, "%d", DeviceData->EventChannel);
   5.577 +  
   5.578 +    RtlStringCbCopyA(TmpPath, 128, DeviceData->Path);
   5.579 +    RtlStringCbCatA(TmpPath, 128, "/state");
   5.580 +    XenBusInterface.Printf(XBT_NIL, TmpPath, "%d", XenbusStateInitialised);
   5.581 +
   5.582 +    KdPrint((__DRIVER_NAME "     Set Frontend state to Initialised\n"));
   5.583 +    break;
   5.584 +
   5.585 +  case XenbusStateInitialised:
   5.586 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialised\n"));
   5.587 +    // create the device
   5.588 +    break;
   5.589 +
   5.590 +  case XenbusStateConnected:
   5.591 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Connected\n"));  
   5.592 +
   5.593 +    WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&Description.Header, sizeof(Description));
   5.594 +
   5.595 +    Description.DeviceData = DeviceData;
   5.596 +
   5.597 +    RtlStringCbCopyA(TmpPath, 128, DeviceData->Path);
   5.598 +    RtlStringCbCatA(TmpPath, 128, "/device-type");
   5.599 +    XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
   5.600 +    if (strcmp(Value, "disk") == 0)
   5.601 +    {
   5.602 +      KdPrint((__DRIVER_NAME "     DeviceType = Disk\n"));    
   5.603 +      DeviceData->ScsiDeviceData->DeviceType = XENVBD_DEVICETYPE_DISK;
   5.604 +    }
   5.605 +    else if (strcmp(Value, "cdrom") == 0)
   5.606 +    {
   5.607 +      KdPrint((__DRIVER_NAME "     DeviceType = CDROM\n"));    
   5.608 +      DeviceData->ScsiDeviceData->DeviceType = XENVBD_DEVICETYPE_CDROM;
   5.609 +    }
   5.610 +    else
   5.611 +    {
   5.612 +      KdPrint((__DRIVER_NAME "     DeviceType = %s (This probably won't work!)\n", Value));
   5.613 +    }
   5.614 +
   5.615 +    RtlStringCbCopyA(TmpPath, 128, DeviceData->BackendPath);
   5.616 +    RtlStringCbCatA(TmpPath, 128, "/type"); // should probably check that this is 'phy' or 'file' or at least not ''
   5.617 +    XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
   5.618 +    KdPrint((__DRIVER_NAME "     Backend Type = %s\n", Value));
   5.619 +
   5.620 +    RtlStringCbCopyA(TmpPath, 128, DeviceData->BackendPath);
   5.621 +    RtlStringCbCatA(TmpPath, 128, "/mode"); // should store this...
   5.622 +    XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
   5.623 +    KdPrint((__DRIVER_NAME "     Backend Mode = %s\n", Value));
   5.624 +
   5.625 +    RtlStringCbCopyA(TmpPath, 128, DeviceData->BackendPath);
   5.626 +    RtlStringCbCatA(TmpPath, 128, "/sector-size");
   5.627 +    XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
   5.628 +    // should complain if Value == NULL
   5.629 +    DeviceData->ScsiDeviceData->BytesPerSector = atoi(Value);
   5.630 +
   5.631 +    KdPrint((__DRIVER_NAME "     BytesPerSector = %d\n", DeviceData->ScsiDeviceData->BytesPerSector));    
   5.632 +
   5.633 +    RtlStringCbCopyA(TmpPath, 128, DeviceData->BackendPath);
   5.634 +    RtlStringCbCatA(TmpPath, 128, "/sectors");
   5.635 +    XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
   5.636 +    // should complain if Value == NULL
   5.637 +    DeviceData->ScsiDeviceData->TotalSectors = (ULONGLONG)atol(Value);
   5.638 +
   5.639 +    KdPrint((__DRIVER_NAME "     TotalSectors = %d\n", DeviceData->ScsiDeviceData->TotalSectors));    
   5.640 +
   5.641 +/*
   5.642 +    // should probably use the partition table (if one exists) here for the sectorspertrack and trackspercylinder values
   5.643 +    DeviceData->Geometry.MediaType = FixedMedia;
   5.644 +    DeviceData->Geometry.BytesPerSector = DeviceData->BytesPerSector;
   5.645 +    DeviceData->Geometry.SectorsPerTrack = 63;
   5.646 +    DeviceData->Geometry.TracksPerCylinder = 255;
   5.647 +    DeviceData->Geometry.Cylinders.QuadPart = DeviceData->TotalSectors / DeviceData->Geometry.SectorsPerTrack / DeviceData->Geometry.TracksPerCylinder;
   5.648 +    KdPrint((__DRIVER_NAME "     Geometry C/H/S = %d/%d/%d\n", DeviceData->Geometry.Cylinders.LowPart, DeviceData->Geometry.TracksPerCylinder, DeviceData->Geometry.SectorsPerTrack));
   5.649 +*/
   5.650 +    // if we detected something wrong, we should not enumerate the device and should instead initiate a close
   5.651 +
   5.652 +    status = WdfChildListAddOrUpdateChildDescriptionAsPresent(WdfFdoGetDefaultChildList(GlobalDevice), &Description.Header, NULL);
   5.653 +    if (!NT_SUCCESS(status))
   5.654 +    {
   5.655 +      KdPrint((__DRIVER_NAME "     WdfChildListAddOrUpdateChildDescriptionAsPresent failed %08x\n", status));
   5.656 +    } 
   5.657 +
   5.658 +    RtlStringCbCopyA(TmpPath, 128, DeviceData->Path);
   5.659 +    RtlStringCbCatA(TmpPath, 128, "/state");
   5.660 +    XenBusInterface.Printf(XBT_NIL, TmpPath, "%d", XenbusStateConnected);
   5.661 +
   5.662 +    KdPrint((__DRIVER_NAME "     Set Frontend state to Connected\n"));
   5.663 +    InterlockedIncrement(&EnumeratedDevices);
   5.664 +    KdPrint((__DRIVER_NAME "     Added a controller, notifying\n"));
   5.665 +    KeSetEvent(&WaitDevicesEvent, 1, FALSE);
   5.666 +    break;
   5.667 +
   5.668 +  case XenbusStateClosing:
   5.669 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Closing\n"));  
   5.670 +    break;
   5.671 +
   5.672 +  case XenbusStateClosed:
   5.673 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Closed\n"));  
   5.674 +    break;
   5.675 +
   5.676 +  default:
   5.677 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Undefined = %d\n", NewState));
   5.678 +    break;
   5.679 +  }
   5.680 +}
   5.681 +
   5.682 +static VOID
   5.683 +XenVbdBus_HotPlugHandler(char *Path, PVOID Data)
   5.684 +{
   5.685 +  PXENVBDBUS_CHILD_DEVICE_DATA DeviceData;
   5.686 +  char **Bits;
   5.687 +  int Count;
   5.688 +  char TmpPath[128];
   5.689 +  char *Value;
   5.690 +
   5.691 +  UNREFERENCED_PARAMETER(Data);  
   5.692 +
   5.693 +  //KdPrint((__DRIVER_NAME " --> HotPlugHandler\n"));
   5.694 +
   5.695 +  KdPrint((__DRIVER_NAME "     Path = %s\n", Path));
   5.696 +
   5.697 +  Bits = SplitString(Path, '/', 4, &Count);
   5.698 +  switch (Count)
   5.699 +  {
   5.700 +  case 0:
   5.701 +  case 1:
   5.702 +  case 2:
   5.703 +    break; // should never happen
   5.704 +  case 3:
   5.705 +    break;
   5.706 +  case 4:
   5.707 +    if (strcmp(Bits[3], "state") != 0) // we only care when the state appears
   5.708 +      break;
   5.709 +    KdPrint((__DRIVER_NAME "     Bits[0] = %s\n", Bits[0]));
   5.710 +    KdPrint((__DRIVER_NAME "     Bits[1] = %s\n", Bits[1]));
   5.711 +    KdPrint((__DRIVER_NAME "     Bits[2] = %s\n", Bits[2]));
   5.712 +    for (DeviceData = (PXENVBDBUS_CHILD_DEVICE_DATA)DeviceListHead.Flink; DeviceData != (PXENVBDBUS_CHILD_DEVICE_DATA)&DeviceListHead; DeviceData = (PXENVBDBUS_CHILD_DEVICE_DATA)DeviceData->Entry.Flink)
   5.713 +    {
   5.714 +
   5.715 +      KdPrint((__DRIVER_NAME "     Comparing '%s' and '%s'\n", DeviceData->Path, Path));
   5.716 +      if (strncmp(DeviceData->Path, Path, strlen(DeviceData->Path)) == 0 && Path[strlen(DeviceData->Path)] == '/')
   5.717 +      {
   5.718 +        KdPrint((__DRIVER_NAME "     Matched\n"));
   5.719 +        break;
   5.720 +      }
   5.721 +    }
   5.722 +    if (DeviceData == (PXENVBDBUS_CHILD_DEVICE_DATA)&DeviceListHead)
   5.723 +    {
   5.724 +      DeviceData = ExAllocatePoolWithTag(NonPagedPool, sizeof(XENVBDBUS_CHILD_DEVICE_DATA), XENVBDBUS_POOL_TAG);
   5.725 +      memset(DeviceData, 0, sizeof(XENVBDBUS_CHILD_DEVICE_DATA));
   5.726 +
   5.727 +      KdPrint((__DRIVER_NAME "     Allocated ChildDeviceData = %08x\n", DeviceData));
   5.728 +      
   5.729 +      RtlStringCbCopyA(DeviceData->Path, 128, Bits[0]);
   5.730 +      RtlStringCbCatA(DeviceData->Path, 128, "/");
   5.731 +      RtlStringCbCatA(DeviceData->Path, 128, Bits[1]);
   5.732 +      RtlStringCbCatA(DeviceData->Path, 128, "/");
   5.733 +      RtlStringCbCatA(DeviceData->Path, 128, Bits[2]);
   5.734 +      InsertTailList(&DeviceListHead, &DeviceData->Entry);
   5.735 +
   5.736 +      DeviceData->DeviceIndex = atoi(Bits[2]);
   5.737 +
   5.738 +      RtlStringCbCopyA(TmpPath, 128, DeviceData->Path);
   5.739 +      RtlStringCbCatA(TmpPath, 128, "/backend");
   5.740 +      XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
   5.741 +      if (Value == NULL)
   5.742 +      {
   5.743 +        KdPrint((__DRIVER_NAME "     Read Failed\n"));
   5.744 +      }
   5.745 +      else
   5.746 +      {
   5.747 +        RtlStringCbCopyA(DeviceData->BackendPath, 128, Value);
   5.748 +      }
   5.749 +      RtlStringCbCopyA(TmpPath, 128, DeviceData->BackendPath);
   5.750 +      RtlStringCbCatA(TmpPath, 128, "/state");
   5.751 +      XenBusInterface.AddWatch(XBT_NIL, TmpPath, XenVbdBus_BackEndStateHandler, DeviceData);
   5.752 +    }
   5.753 +    break;
   5.754 +  }
   5.755 +  
   5.756 +  FreeSplitString(Bits, Count);
   5.757 +
   5.758 +  //KdPrint((__DRIVER_NAME " <-- HotPlugHandler\n"));  
   5.759 +
   5.760 +  return;
   5.761 +}
   5.762 +
   5.763 +static NTSTATUS
   5.764 +XenVbdBus_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit)
   5.765 +{
   5.766 +  NTSTATUS status;
   5.767 +  WDFDEVICE ChildDevice;
   5.768 +  PXENVBDBUS_DEVICE_IDENTIFICATION_DESCRIPTION XenVbdBusIdentificationDesc;
   5.769 +  DECLARE_UNICODE_STRING_SIZE(buffer, 50);
   5.770 +  WDF_OBJECT_ATTRIBUTES PdoAttributes;
   5.771 +  DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
   5.772 +  PXENVBDBUS_CHILD_DEVICE_DATA ChildDeviceData;
   5.773 +  WDF_PDO_EVENT_CALLBACKS PdoCallbacks;
   5.774 +  UCHAR PnpMinors[2] = { IRP_MN_START_DEVICE, IRP_MN_STOP_DEVICE };
   5.775 +
   5.776 +  UNREFERENCED_PARAMETER(ChildList);
   5.777 +
   5.778 +  KdPrint((__DRIVER_NAME " --> ChildListCreateDevice\n"));
   5.779 +
   5.780 +  XenVbdBusIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENVBDBUS_DEVICE_IDENTIFICATION_DESCRIPTION, Header);
   5.781 +
   5.782 +  ChildDeviceData = XenVbdBusIdentificationDesc->DeviceData;
   5.783 +
   5.784 +  WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_CONTROLLER);
   5.785 +
   5.786 +  status = RtlUnicodeStringPrintf(&buffer, L"XEN\\VBDDev\0");
   5.787 +  status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
   5.788 +
   5.789 +  status = RtlUnicodeStringPrintf(&buffer, L"%02d\0", ChildDeviceData->DeviceIndex);
   5.790 +  status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
   5.791 +
   5.792 +  status = RtlUnicodeStringPrintf(&buffer, L"XEN\\VBDDev\0");
   5.793 +  status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
   5.794 +  status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
   5.795 +
   5.796 +  //status = RtlUnicodeStringPrintf(&buffer, L"Xen PV Disk (%d)", ChildDeviceData->DeviceIndex);
   5.797 +  //status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
   5.798 +  //WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
   5.799 +
   5.800 +  WDF_PDO_EVENT_CALLBACKS_INIT(&PdoCallbacks);
   5.801 +  PdoCallbacks.EvtDeviceResourceRequirementsQuery = XenVbdBus_DeviceResourceRequirementsQuery;
   5.802 +  WdfPdoInitSetEventCallbacks(ChildInit, &PdoCallbacks);
   5.803 +
   5.804 +  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&PdoAttributes, PXENVBDBUS_CHILD_DEVICE_DATA);
   5.805 +
   5.806 +//  status = WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpPnp, IRP_MJ_PNP, PnpMinors, 2);
   5.807 +//  if (!NT_SUCCESS(status))
   5.808 +//    KdPrint((__DRIVER_NAME "     WdfDeviceInitAssignWdmIrpPreprocessCallback(IRP_MJ_PNP) status = %08X\n", status));
   5.809 +
   5.810 +  status = WdfDeviceCreate(&ChildInit, &PdoAttributes, &ChildDevice);
   5.811 +  if (!NT_SUCCESS(status))
   5.812 +  {
   5.813 +    KdPrint((__DRIVER_NAME "     WdfDeviceCreate status = %08X\n", status));
   5.814 +  }
   5.815 +
   5.816 +  *GetChildDeviceData(ChildDevice) = ChildDeviceData;
   5.817 +
   5.818 +  KdPrint((__DRIVER_NAME " <-- ChildListCreateDevice (status = %08x)\n", status));
   5.819 +
   5.820 +  return status;
   5.821 +}
   5.822 +
   5.823 +static NTSTATUS
   5.824 +XenVbd_Child_PreprocessWdmIrpPnp(WDFDEVICE Device, PIRP Irp)
   5.825 +{
   5.826 +  NTSTATUS Status;
   5.827 +  PIO_STACK_LOCATION IrpStackLocation;
   5.828 +  PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
   5.829 +  PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
   5.830 +  int i;  
   5.831 +
   5.832 +  KdPrint((__DRIVER_NAME " --> PreprocessWdmIrpPnp\n"));
   5.833 +
   5.834 +  IrpStackLocation = IoGetCurrentIrpStackLocation(Irp);
   5.835 +
   5.836 +  switch (IrpStackLocation->MinorFunction)
   5.837 +  {
   5.838 +  case IRP_MN_START_DEVICE:
   5.839 +    KdPrint((__DRIVER_NAME "     START_DEVICE\n"));
   5.840 +    PartialResourceList = &IrpStackLocation->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
   5.841 +    for (i = 0; i < PartialResourceList->Count; i++)
   5.842 +    {
   5.843 +      PartialDescriptor = &PartialResourceList->PartialDescriptors[i];
   5.844 +      switch (PartialDescriptor->Type)
   5.845 +      {
   5.846 +      case CmResourceTypeInterrupt:
   5.847 +        KdPrint((__DRIVER_NAME "     CmResourceTypeInterrupt\n"));
   5.848 +        KdPrint((__DRIVER_NAME "     Level = %d, Vector = %08x\n", PartialDescriptor->u.Interrupt.Level, PartialDescriptor->u.Interrupt.Vector));
   5.849 +        break;
   5.850 +      default:
   5.851 +        KdPrint((__DRIVER_NAME "     Other Resource %02X\n", PartialDescriptor->Type));
   5.852 +        break;
   5.853 +      }
   5.854 +    }
   5.855 +    PartialResourceList = &IrpStackLocation->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
   5.856 +    for (i = 0; i < PartialResourceList->Count; i++)
   5.857 +    {
   5.858 +      PartialDescriptor = &PartialResourceList->PartialDescriptors[i];
   5.859 +      switch (PartialDescriptor->Type)
   5.860 +      {
   5.861 +      case CmResourceTypeInterrupt:
   5.862 +        KdPrint((__DRIVER_NAME "     CmResourceTypeInterrupt\n"));
   5.863 +        KdPrint((__DRIVER_NAME "     Level = %d, Vector = %08x\n", PartialDescriptor->u.Interrupt.Level, PartialDescriptor->u.Interrupt.Vector));
   5.864 +        break;
   5.865 +      default:
   5.866 +        KdPrint((__DRIVER_NAME "     Other Resource %02X\n", PartialDescriptor->Type));
   5.867 +        break;
   5.868 +      }
   5.869 +    }
   5.870 +    break;
   5.871 +  case IRP_MN_STOP_DEVICE:
   5.872 +    KdPrint((__DRIVER_NAME "     STOP_DEVICE\n"));
   5.873 +    // Unbind the PIRQ here
   5.874 +    break;
   5.875 +  default:
   5.876 +    break;
   5.877 +  }
   5.878 +
   5.879 +  IoSkipCurrentIrpStackLocation(Irp);
   5.880 +
   5.881 +  Status = WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
   5.882 +
   5.883 +  KdPrint((__DRIVER_NAME " <-- PreprocessWdmIrpPnp\n"));
   5.884 +
   5.885 +  return Status;
   5.886 +}
   5.887 +
   5.888 +static NTSTATUS
   5.889 +XenVbdBus_DeviceResourceRequirementsQuery(WDFDEVICE ChildDevice, WDFIORESREQLIST IoResourceRequirementsList)
   5.890 +{
   5.891 +  NTSTATUS  status = STATUS_SUCCESS;
   5.892 +  WDFIORESLIST resourceList;
   5.893 +  IO_RESOURCE_DESCRIPTOR descriptor;
   5.894 +  PXENVBDBUS_CHILD_DEVICE_DATA ChildDeviceData;
   5.895 +
   5.896 +  ChildDeviceData = *GetChildDeviceData(ChildDevice);
   5.897 +
   5.898 +  KdPrint((__DRIVER_NAME " --> DeviceResourceRequirementsQuery\n"));
   5.899 +
   5.900 +  status = WdfIoResourceListCreate(IoResourceRequirementsList, WDF_NO_OBJECT_ATTRIBUTES, &resourceList);
   5.901 +  if (!NT_SUCCESS(status))
   5.902 +    return status;
   5.903 +
   5.904 +  RtlZeroMemory(&descriptor, sizeof(descriptor));
   5.905 +
   5.906 +  descriptor.Type = CmResourceTypeMemory;
   5.907 +  descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
   5.908 +  descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
   5.909 +  descriptor.u.Memory.Length = 0; //PAGE_SIZE;
   5.910 +  descriptor.u.Memory.Alignment = PAGE_SIZE;
   5.911 +  //descriptor.u.Memory.MinimumAddress.QuadPart = *MmGetMdlPfnArray(ChildDeviceData->ScsiDeviceDataMdl) << PAGE_SHIFT;
   5.912 +  descriptor.u.Memory.MinimumAddress.QuadPart = MmGetSystemAddressForMdlSafe(ChildDeviceData->ScsiDeviceDataMdl, NormalPagePriority);
   5.913 +  descriptor.u.Memory.MaximumAddress.QuadPart = descriptor.u.Memory.MinimumAddress.QuadPart;
   5.914 +
   5.915 +  KdPrint((__DRIVER_NAME "     MinimumAddress = %08x, MaximumAddress = %08x\n", descriptor.u.Memory.MinimumAddress.LowPart, descriptor.u.Memory.MaximumAddress.LowPart));
   5.916 +
   5.917 +  status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
   5.918 +  if (!NT_SUCCESS(status))
   5.919 +    return status;
   5.920 +/*
   5.921 +  RtlZeroMemory(&descriptor, sizeof(descriptor));
   5.922 +
   5.923 +  descriptor.Type = CmResourceTypeInterrupt;
   5.924 +  descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
   5.925 +  descriptor.Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
   5.926 +  descriptor.u.Interrupt.MinimumVector = 16;
   5.927 +  descriptor.u.Interrupt.MaximumVector = 255;
   5.928 +
   5.929 +  KdPrint((__DRIVER_NAME "     MinimumVector = %d, MaximumVector = %d\n", descriptor.u.Interrupt.MinimumVector, descriptor.u.Interrupt.MaximumVector));
   5.930 +
   5.931 +  status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
   5.932 +  if (!NT_SUCCESS(status))
   5.933 +    return status;
   5.934 +*/
   5.935 +
   5.936 +  status = WdfIoResourceRequirementsListAppendIoResList(IoResourceRequirementsList, resourceList);
   5.937 +  if (!NT_SUCCESS(status))
   5.938 +  {
   5.939 +    return status;
   5.940 +  }
   5.941 +
   5.942 +  KdPrint((__DRIVER_NAME " <-- DeviceResourceRequirementsQuery\n"));
   5.943 +
   5.944 +  return status;
   5.945 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/xenvbdbus/xenvbdbus.h	Fri Nov 30 21:33:49 2007 +1100
     6.3 @@ -0,0 +1,96 @@
     6.4 +#if !defined(_XENVBDBUS_H_)
     6.5 +#define _XENVBDBUS_H_
     6.6 +
     6.7 +#include <ntddk.h>
     6.8 +#include <wdm.h>
     6.9 +#include <wdf.h>
    6.10 +#include <initguid.h>
    6.11 +#include <ntdddisk.h>
    6.12 +
    6.13 +#define NTSTRSAFE_LIB
    6.14 +#include <ntstrsafe.h>
    6.15 +
    6.16 +#include <xen_windows.h>
    6.17 +#include <memory.h>
    6.18 +#include <grant_table.h>
    6.19 +#include <event_channel.h>
    6.20 +#include <hvm/params.h>
    6.21 +#include <hvm/hvm_op.h>
    6.22 +#include <evtchn_public.h>
    6.23 +#include <gnttbl_public.h>
    6.24 +#include <xenbus_public.h>
    6.25 +#include <io/ring.h>
    6.26 +#include <io/blkif.h>
    6.27 +#define __DRIVER_NAME "XenVbdBus"
    6.28 +#define XENVBDBUS_POOL_TAG (ULONG) 'XVBD'
    6.29 +
    6.30 +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
    6.31 +#define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
    6.32 +
    6.33 +extern XEN_IFACE_EVTCHN EvtChnInterface;
    6.34 +extern XEN_IFACE_XENBUS XenBusInterface;
    6.35 +
    6.36 +#include "..\xenvbddev\scsidata.h"
    6.37 +
    6.38 +struct
    6.39 +{
    6.40 +  LIST_ENTRY Entry;
    6.41 +  char Path[128];
    6.42 +  char BackendPath[128];
    6.43 +  ULONG DeviceIndex;
    6.44 +  evtchn_port_t EventChannel;
    6.45 +  PMDL SharedRingMDL;
    6.46 +//  ULONG BytesPerSector;
    6.47 +//  ULONGLONG TotalSectors;
    6.48 +  PMDL ScsiDeviceDataMdl;
    6.49 +  PXENVBDDEV_SCSI_DATA ScsiDeviceData;
    6.50 +/*
    6.51 +  KSPIN_LOCK Lock;
    6.52 +  WDFQUEUE IoDefaultQueue;
    6.53 +  WDFDEVICE Device;
    6.54 +*/
    6.55 +
    6.56 +//  int TmpCount;
    6.57 +/*
    6.58 +  int BackendState;
    6.59 +  int FrontendState;
    6.60 +*/
    6.61 +  
    6.62 +/*
    6.63 +  blkif_shadow_t *shadow;
    6.64 +  uint64_t shadow_free;
    6.65 +
    6.66 +  LIST_ENTRY IrpListHead;
    6.67 +  KSPIN_LOCK IrpListLock;
    6.68 +
    6.69 +  WDFDPC Dpc;
    6.70 +*/
    6.71 +/*
    6.72 +  DISK_GEOMETRY Geometry;
    6.73 +*/
    6.74 +/*
    6.75 +  int IrpAddedToList;
    6.76 +  int IrpRemovedFromList;
    6.77 +  int IrpAddedToRing;
    6.78 +  int IrpAddedToRingAtLastNotify;
    6.79 +  int IrpAddedToRingAtLastInterrupt;
    6.80 +  int IrpAddedToRingAtLastDpc;
    6.81 +  int IrpRemovedFromRing;
    6.82 +  int IrpCompleted;
    6.83 +
    6.84 +  int FastPathUsed;
    6.85 +  int SlowPathUsed;
    6.86 +*/
    6.87 +} typedef XENVBDBUS_CHILD_DEVICE_DATA, *PXENVBDBUS_CHILD_DEVICE_DATA, **PPXENVBDBUS_CHILD_DEVICE_DATA;
    6.88 +
    6.89 +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(PXENVBDBUS_CHILD_DEVICE_DATA, GetChildDeviceData);
    6.90 +
    6.91 +typedef struct _XENVBDBUS_DEVICE_IDENTIFICATION_DESCRIPTION
    6.92 +{
    6.93 +  WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Header;
    6.94 +  PXENVBDBUS_CHILD_DEVICE_DATA DeviceData;
    6.95 +  //ULONG DeviceIndex;
    6.96 +  //char Path[128];
    6.97 +} XENVBDBUS_DEVICE_IDENTIFICATION_DESCRIPTION, *PXENVBDBUS_DEVICE_IDENTIFICATION_DESCRIPTION;
    6.98 +
    6.99 +#endif
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/xenvbddev/makefile	Fri Nov 30 21:33:49 2007 +1100
     7.3 @@ -0,0 +1,1 @@
     7.4 +!INCLUDE $(NTMAKEENV)\makefile.def
     7.5 \ No newline at end of file
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/xenvbddev/sources	Fri Nov 30 21:33:49 2007 +1100
     8.3 @@ -0,0 +1,13 @@
     8.4 +TARGETNAME=XENVBDDEV
     8.5 +TARGETTYPE=DRIVER
     8.6 +TARGETPATH=..\Target
     8.7 +
     8.8 +MSC_WARNING_LEVEL=/W4
     8.9 +
    8.10 +INCLUDES = ..\common\include;..\common\include\public
    8.11 +
    8.12 +NO_BINPLACE=1
    8.13 +KMDF_VERSION=1
    8.14 +TARGETLIBS=$(DDK_LIB_PATH)\ntstrsafe.lib $(DDK_LIB_PATH)\scsiport.lib
    8.15 +
    8.16 +SOURCES=xenvbddev.c
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/xenvbddev/xenvbddev.c	Fri Nov 30 21:33:49 2007 +1100
     9.3 @@ -0,0 +1,775 @@
     9.4 +#include "xenvbddev.h"
     9.5 +#include <io/blkif.h>
     9.6 +#include <scsi.h>
     9.7 +#include <ntddscsi.h>
     9.8 +#include <ntdddisk.h>
     9.9 +#include <stdlib.h>
    9.10 +#include <xen_public.h>
    9.11 +#include <io/xenbus.h>
    9.12 +#include <ntddft.h>
    9.13 +
    9.14 +#define wmb() KeMemoryBarrier()
    9.15 +#define mb() KeMemoryBarrier()
    9.16 +
    9.17 +DRIVER_INITIALIZE DriverEntry;
    9.18 +
    9.19 +static ULONG
    9.20 +XenVbdDev_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again);
    9.21 +static BOOLEAN
    9.22 +XenVbdDev_HwScsiInitialize(PVOID DeviceExtension);
    9.23 +static BOOLEAN
    9.24 +XenVbdDev_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb);
    9.25 +//static BOOLEAN
    9.26 +//XenVbdDev_HwScsiInterrupt(PVOID DeviceExtension);
    9.27 +static BOOLEAN
    9.28 +XenVbdDev_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId);
    9.29 +static BOOLEAN
    9.30 +XenVbdDev_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState);
    9.31 +static SCSI_ADAPTER_CONTROL_STATUS
    9.32 +XenVbdDev_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters);
    9.33 +
    9.34 +#ifdef ALLOC_PRAGMA
    9.35 +#pragma alloc_text (INIT, DriverEntry)
    9.36 +#endif
    9.37 +
    9.38 +LIST_ENTRY DeviceListHead;
    9.39 +//XEN_IFACE_EVTCHN EvtChnInterface;
    9.40 +//XEN_IFACE_XENBUS XenBusInterface;
    9.41 +//XEN_IFACE_XEN XenInterface;
    9.42 +XEN_IFACE_GNTTBL GntTblInterface;
    9.43 +
    9.44 +static BOOLEAN AutoEnumerate;
    9.45 +
    9.46 +NTSTATUS
    9.47 +DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
    9.48 +{
    9.49 +  ULONG Status;
    9.50 +  HW_INITIALIZATION_DATA HwInitializationData;
    9.51 +
    9.52 +  KdPrint((__DRIVER_NAME " --> DriverEntry\n"));
    9.53 +
    9.54 +  RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
    9.55 +
    9.56 +  HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
    9.57 +  HwInitializationData.AdapterInterfaceType = Internal; //PNPBus;
    9.58 +  HwInitializationData.HwInitialize = XenVbdDev_HwScsiInitialize;
    9.59 +  HwInitializationData.HwStartIo = XenVbdDev_HwScsiStartIo;
    9.60 +  //HwInitializationData.HwInterrupt = XenVbdDev_HwScsiInterrupt;
    9.61 +  HwInitializationData.HwFindAdapter = XenVbdDev_HwScsiFindAdapter;
    9.62 +  HwInitializationData.HwResetBus = XenVbdDev_HwScsiResetBus;
    9.63 +  HwInitializationData.HwDmaStarted = NULL;
    9.64 +  HwInitializationData.HwAdapterState = NULL;
    9.65 +  HwInitializationData.DeviceExtensionSize = sizeof(XENVBDDEV_DEVICE_DATA);
    9.66 +  HwInitializationData.SpecificLuExtensionSize = 0;
    9.67 +  HwInitializationData.SrbExtensionSize = 0;
    9.68 +  HwInitializationData.NumberOfAccessRanges = 1;
    9.69 +  HwInitializationData.MapBuffers = TRUE; //FALSE;
    9.70 +  HwInitializationData.NeedPhysicalAddresses = FALSE; //TRUE;
    9.71 +  //HwInitializationData.TaggedQueueing = FALSE;
    9.72 +  HwInitializationData.AutoRequestSense = FALSE;
    9.73 +  HwInitializationData.MultipleRequestPerLu = FALSE;
    9.74 +  HwInitializationData.ReceiveEvent = FALSE; // check this
    9.75 +  HwInitializationData.VendorIdLength = 0;
    9.76 +  HwInitializationData.VendorId = NULL;
    9.77 +  HwInitializationData.DeviceIdLength = 0;
    9.78 +  HwInitializationData.DeviceId = NULL;
    9.79 +  HwInitializationData.HwAdapterControl = XenVbdDev_HwScsiAdapterControl;
    9.80 +
    9.81 +  Status = ScsiPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
    9.82 +
    9.83 +  if(!NT_SUCCESS(Status))
    9.84 +  {
    9.85 +    KdPrint((__DRIVER_NAME " ScsiPortInitialize failed with status 0x%08x\n", Status));
    9.86 +  }
    9.87 +
    9.88 +  KdPrint((__DRIVER_NAME " <-- DriverEntry\n"));
    9.89 +
    9.90 +  return Status;
    9.91 +}
    9.92 +
    9.93 +static PMDL
    9.94 +AllocatePages(int Pages)
    9.95 +{
    9.96 +  PMDL Mdl;
    9.97 +  PVOID Buf;
    9.98 +
    9.99 +  Buf = ExAllocatePoolWithTag(NonPagedPool, Pages * PAGE_SIZE, XENVBDDEV_POOL_TAG);
   9.100 +  if (Buf == NULL)
   9.101 +  {
   9.102 +    KdPrint((__DRIVER_NAME "     AllocatePages Failed at ExAllocatePoolWithTag\n"));
   9.103 +  }
   9.104 +  Mdl = IoAllocateMdl(Buf, Pages * PAGE_SIZE, FALSE, FALSE, NULL);
   9.105 +  if (Mdl == NULL)
   9.106 +  {
   9.107 +    KdPrint((__DRIVER_NAME "     AllocatePages Failed at IoAllocateMdl\n"));
   9.108 +  }
   9.109 +  MmBuildMdlForNonPagedPool(Mdl);
   9.110 +  
   9.111 +  return Mdl;
   9.112 +}
   9.113 +
   9.114 +static PMDL
   9.115 +AllocatePage()
   9.116 +{
   9.117 +  return AllocatePages(1);
   9.118 +}
   9.119 +
   9.120 +static VOID
   9.121 +FreePages(PMDL Mdl)
   9.122 +{
   9.123 +  PVOID Buf = MmGetMdlVirtualAddress(Mdl);
   9.124 +  //KdPrint((__DRIVER_NAME "     FreePages Failed at IoAllocateMdl\n"));
   9.125 +  //KdPrint((__DRIVER_NAME "     FreePages Buf = %08x\n", Buf));
   9.126 +  IoFreeMdl(Mdl);
   9.127 +  ExFreePoolWithTag(Buf, XENVBDDEV_POOL_TAG);
   9.128 +}
   9.129 +
   9.130 +static ULONG
   9.131 +XenVbdDev_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
   9.132 +{
   9.133 +  NTSTATUS Status = SP_RETURN_FOUND;
   9.134 +  ULONG i;
   9.135 +  PACCESS_RANGE AccessRange;
   9.136 +  PXENVBDDEV_DEVICE_DATA DeviceData = (PXENVBDDEV_DEVICE_DATA)DeviceExtension;
   9.137 +
   9.138 +  KdPrint((__DRIVER_NAME " --> HwScsiFindAdapter\n"));
   9.139 +
   9.140 +  KdPrint((__DRIVER_NAME "     BusInterruptVector = %d\n", ConfigInfo->BusInterruptVector));
   9.141 +
   9.142 +  KdPrint((__DRIVER_NAME "     AccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));
   9.143 +
   9.144 +  for (i = 0; i < ConfigInfo->NumberOfAccessRanges; i++)
   9.145 +  {
   9.146 +    AccessRange = &(*(ConfigInfo->AccessRanges))[i];
   9.147 +    KdPrint((__DRIVER_NAME "     AccessRange %2d: RangeStart = %08x, RangeLength = %08x, RangeInMemory = %d\n", i, AccessRange->RangeStart.LowPart, AccessRange->RangeLength, AccessRange->RangeInMemory));
   9.148 +    switch (i)
   9.149 +    {
   9.150 +    case 0:
   9.151 +      //DeviceData->ScsiData = ScsiPortGetDeviceBase(DeviceExtension, ConfigInfo->AdapterInterfaceType, ConfigInfo->SystemIoBusNumber, AccessRange->RangeStart, PAGE_SIZE, FALSE);
   9.152 +      //DeviceData->ScsiData = MmMapIoSpace(AccessRange->RangeStart, PAGE_SIZE, MmCached);
   9.153 +      DeviceData->ScsiData = (PXENVBDDEV_SCSI_DATA)AccessRange->RangeStart.LowPart;
   9.154 +      KdPrint((__DRIVER_NAME "     Mapped to virtual address %08x\n", DeviceData->ScsiData));
   9.155 +      if (DeviceData->ScsiData->Magic == SCSI_DATA_MAGIC)
   9.156 +      {
   9.157 +      }
   9.158 +      KdPrint((__DRIVER_NAME "     Magic = %08x\n", DeviceData->ScsiData->Magic));
   9.159 +      break;
   9.160 +    default:
   9.161 +      break;
   9.162 +    }
   9.163 +  }
   9.164 +
   9.165 +  ConfigInfo->NumberOfBuses = 1;
   9.166 +  ConfigInfo->MaximumTransferLength = 45056;
   9.167 +  ConfigInfo->NumberOfPhysicalBreaks = 11 - 1;
   9.168 +  ConfigInfo->ScatterGather = FALSE;
   9.169 +  ConfigInfo->Master = TRUE;
   9.170 +  ConfigInfo->AlignmentMask =  0;
   9.171 +  ConfigInfo->MaximumNumberOfLogicalUnits = 1; 
   9.172 +  ConfigInfo->MaximumNumberOfTargets = 2;
   9.173 +
   9.174 +  *Again = FALSE;
   9.175 +
   9.176 +  KdPrint((__DRIVER_NAME " <-- HwScsiFindAdapter\n"));  
   9.177 +
   9.178 +  return Status;
   9.179 +}
   9.180 +
   9.181 +static __inline uint64_t
   9.182 +GET_ID_FROM_FREELIST(PXENVBDDEV_DEVICE_DATA DeviceData)
   9.183 +{
   9.184 +  uint64_t free;
   9.185 +  free = DeviceData->shadow_free;
   9.186 +  DeviceData->shadow_free = DeviceData->shadow[free].req.id;
   9.187 +  DeviceData->shadow[free].req.id = 0x0fffffee; /* debug */
   9.188 +  return free;
   9.189 +}
   9.190 +
   9.191 +static __inline VOID
   9.192 +ADD_ID_TO_FREELIST(PXENVBDDEV_DEVICE_DATA DeviceData, uint64_t Id)
   9.193 +{
   9.194 +  DeviceData->shadow[Id].req.id  = DeviceData->shadow_free;
   9.195 +  DeviceData->shadow[Id].Srb = NULL;
   9.196 +  DeviceData->shadow_free = Id;
   9.197 +}
   9.198 +
   9.199 +static HANDLE XenVbdDev_ScsiPortThreadHandle;
   9.200 +static KEVENT XenVbdDev_ScsiPortThreadEvent;
   9.201 +
   9.202 +static VOID
   9.203 +XenVbdDev_Interrupt(PVOID DeviceExtension)
   9.204 +{
   9.205 +  KdPrint((__DRIVER_NAME " --> Interrupt\n"));
   9.206 +
   9.207 +  KeSetEvent(&XenVbdDev_ScsiPortThreadEvent, 1, FALSE);
   9.208 +
   9.209 +  KdPrint((__DRIVER_NAME " <-- Interrupt\n"));
   9.210 +/*
   9.211 +  PXENVBDDEV_DEVICE_DATA DeviceData = (PXENVBDDEV_DEVICE_DATA)DeviceExtension;
   9.212 +  PSCSI_REQUEST_BLOCK Srb;
   9.213 +  RING_IDX i, rp;
   9.214 +  int j;
   9.215 +  blkif_response_t *rep;
   9.216 +  char *DataBuffer;
   9.217 +  int more_to_do;
   9.218 +  int BlockCount;
   9.219 +  KIRQL KIrql;
   9.220 +  int notify;
   9.221 +
   9.222 +  //!!!IRQL_DISPATCH!!!
   9.223 +
   9.224 +  KdPrint((__DRIVER_NAME " --> Interrupt\n"));
   9.225 +
   9.226 +  more_to_do = TRUE;
   9.227 +//  KeAcquireSpinLock(&DeviceData->Lock, &KIrql);
   9.228 +
   9.229 +  while (more_to_do)
   9.230 +  {
   9.231 +    rp = DeviceData->ScsiData->Ring.sring->rsp_prod;
   9.232 +    KeMemoryBarrier();
   9.233 +    for (i = DeviceData->ScsiData->Ring.rsp_cons; i != rp; i++)
   9.234 +    {
   9.235 +      rep = RING_GET_RESPONSE(&DeviceData->ScsiData->Ring, i);
   9.236 +      Srb = DeviceData->shadow[rep->id].Srb;
   9.237 +
   9.238 +      KdPrint((__DRIVER_NAME "     Response Id = %d\n", rep->id));
   9.239 +
   9.240 +      if (rep->status != BLKIF_RSP_OKAY)
   9.241 +      {
   9.242 +        KdPrint((__DRIVER_NAME "     Xen Operation returned error\n"));
   9.243 +      }
   9.244 +      for (j = 0; j < DeviceData->shadow[rep->id].req.nr_segments; j++)
   9.245 +      {
   9.246 +        GntTblInterface.EndAccess(DeviceData->shadow[rep->id].req.seg[j].gref);
   9.247 +      }
   9.248 +      BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
   9.249 +      if (Srb->Cdb[0] == SCSIOP_READ)
   9.250 +      {
   9.251 +        memcpy(Srb->DataBuffer, DeviceData->shadow[rep->id].Buf, BlockCount * DeviceData->ScsiData->BytesPerSector);
   9.252 +        KdPrint((__DRIVER_NAME "     Read Sector = %08X, Sectors = %d\n", (int)DeviceData->shadow[rep->id].req.sector_number, BlockCount));
   9.253 +        KdPrint((__DRIVER_NAME "     (504-511 = %02X%02X%02X%02X%02X%02X%02X%02X)\n", ((PUCHAR)Srb->DataBuffer)[504], ((PUCHAR)Srb->DataBuffer)[505], ((PUCHAR)Srb->DataBuffer)[506], ((PUCHAR)Srb->DataBuffer)[507], ((PUCHAR)Srb->DataBuffer)[508], ((PUCHAR)Srb->DataBuffer)[509], ((PUCHAR)Srb->DataBuffer)[510], ((PUCHAR)Srb->DataBuffer)[511])); 
   9.254 +      }
   9.255 +      else
   9.256 +      {
   9.257 +        KdPrint((__DRIVER_NAME "     Write Sector = %08X, Sectors = %d\n", (int)DeviceData->shadow[rep->id].req.sector_number, BlockCount));
   9.258 +      }
   9.259 +
   9.260 +      FreePages(DeviceData->shadow[rep->id].Mdl);
   9.261 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
   9.262 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   9.263 +
   9.264 +      ADD_ID_TO_FREELIST(DeviceData, rep->id);
   9.265 +    }
   9.266 +
   9.267 +    DeviceData->ScsiData->Ring.rsp_cons = i;
   9.268 +    if (i != DeviceData->ScsiData->Ring.req_prod_pvt)
   9.269 +    {
   9.270 +      RING_FINAL_CHECK_FOR_RESPONSES(&DeviceData->ScsiData->Ring, more_to_do);
   9.271 +    }
   9.272 +    else
   9.273 +    {
   9.274 +      DeviceData->ScsiData->Ring.sring->rsp_event = i + 1;
   9.275 +      more_to_do = FALSE;
   9.276 +    }
   9.277 +  }
   9.278 +
   9.279 +//  ScsiPortNotification(NextRequest, DeviceExtension, NULL);
   9.280 +
   9.281 +//  KeReleaseSpinLock(&DeviceData->Lock, KIrql);
   9.282 +
   9.283 +  KdPrint((__DRIVER_NAME " <-- Interrupt\n"));
   9.284 +*/
   9.285 +  return;
   9.286 +}
   9.287 +
   9.288 +static void
   9.289 +XenVbdDev_ScsiPortThreadProc(PVOID DeviceExtension)
   9.290 +{
   9.291 +  PXENVBDDEV_DEVICE_DATA DeviceData = (PXENVBDDEV_DEVICE_DATA)DeviceExtension;
   9.292 +  PSCSI_REQUEST_BLOCK Srb;
   9.293 +  RING_IDX i, rp;
   9.294 +  int j;
   9.295 +  blkif_response_t *rep;
   9.296 +  char *DataBuffer;
   9.297 +  int more_to_do;
   9.298 +  int BlockCount;
   9.299 +  KIRQL KIrql;
   9.300 +  int notify;
   9.301 +
   9.302 +  //!!!IRQL_DISPATCH!!!
   9.303 +
   9.304 +  KdPrint((__DRIVER_NAME " --> Interrupt\n"));
   9.305 +
   9.306 +  for(;;)
   9.307 +  {
   9.308 +    KeWaitForSingleObject(&XenVbdDev_ScsiPortThreadEvent, Executive, KernelMode, FALSE, NULL);
   9.309 +    KdPrint((__DRIVER_NAME " --- Thread woke up\n"));
   9.310 +    more_to_do = TRUE;
   9.311 +//  KeAcquireSpinLock(&DeviceData->Lock, &KIrql);
   9.312 +
   9.313 +    while (more_to_do)
   9.314 +    {
   9.315 +      rp = DeviceData->ScsiData->Ring.sring->rsp_prod;
   9.316 +      KeMemoryBarrier();
   9.317 +      for (i = DeviceData->ScsiData->Ring.rsp_cons; i != rp; i++)
   9.318 +      {
   9.319 +        rep = RING_GET_RESPONSE(&DeviceData->ScsiData->Ring, i);
   9.320 +        Srb = DeviceData->shadow[rep->id].Srb;
   9.321 +  
   9.322 +        KdPrint((__DRIVER_NAME "     Response Id = %d\n", rep->id));
   9.323 +  
   9.324 +        if (rep->status != BLKIF_RSP_OKAY)
   9.325 +        {
   9.326 +          KdPrint((__DRIVER_NAME "     Xen Operation returned error\n"));
   9.327 +        }
   9.328 +        for (j = 0; j < DeviceData->shadow[rep->id].req.nr_segments; j++)
   9.329 +        {
   9.330 +          GntTblInterface.EndAccess(DeviceData->shadow[rep->id].req.seg[j].gref);
   9.331 +        }
   9.332 +        BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
   9.333 +        if (Srb->Cdb[0] == SCSIOP_READ)
   9.334 +        {
   9.335 +          memcpy(Srb->DataBuffer, DeviceData->shadow[rep->id].Buf, BlockCount * DeviceData->ScsiData->BytesPerSector);
   9.336 +          KdPrint((__DRIVER_NAME "     Read Sector = %08X, Sectors = %d\n", (int)DeviceData->shadow[rep->id].req.sector_number, BlockCount));
   9.337 +          KdPrint((__DRIVER_NAME "     (504-511 = %02X%02X%02X%02X%02X%02X%02X%02X)\n", ((PUCHAR)Srb->DataBuffer)[504], ((PUCHAR)Srb->DataBuffer)[505], ((PUCHAR)Srb->DataBuffer)[506], ((PUCHAR)Srb->DataBuffer)[507], ((PUCHAR)Srb->DataBuffer)[508], ((PUCHAR)Srb->DataBuffer)[509], ((PUCHAR)Srb->DataBuffer)[510], ((PUCHAR)Srb->DataBuffer)[511])); 
   9.338 +        }
   9.339 +        else
   9.340 +        {
   9.341 +          KdPrint((__DRIVER_NAME "     Write Sector = %08X, Sectors = %d\n", (int)DeviceData->shadow[rep->id].req.sector_number, BlockCount));
   9.342 +        }
   9.343 +  
   9.344 +        FreePages(DeviceData->shadow[rep->id].Mdl);
   9.345 +        Srb->SrbStatus = SRB_STATUS_SUCCESS;
   9.346 +        ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   9.347 +  
   9.348 +        ADD_ID_TO_FREELIST(DeviceData, rep->id);
   9.349 +      }
   9.350 +  
   9.351 +      DeviceData->ScsiData->Ring.rsp_cons = i;
   9.352 +      if (i != DeviceData->ScsiData->Ring.req_prod_pvt)
   9.353 +      {
   9.354 +        RING_FINAL_CHECK_FOR_RESPONSES(&DeviceData->ScsiData->Ring, more_to_do);
   9.355 +      }
   9.356 +      else
   9.357 +      {
   9.358 +        DeviceData->ScsiData->Ring.sring->rsp_event = i + 1;
   9.359 +        more_to_do = FALSE;
   9.360 +      }
   9.361 +    }
   9.362 +  }
   9.363 +}
   9.364 +
   9.365 +static BOOLEAN
   9.366 +XenVbdDev_HwScsiInitialize(PVOID DeviceExtension)
   9.367 +{
   9.368 +  PXENVBDDEV_DEVICE_DATA DeviceData = (PXENVBDDEV_DEVICE_DATA)DeviceExtension;
   9.369 +  unsigned int i;
   9.370 +  OBJECT_ATTRIBUTES oa;
   9.371 +  NTSTATUS Status;
   9.372 +
   9.373 +  GntTblInterface = DeviceData->ScsiData->GntTblInterface;
   9.374 +
   9.375 +  DeviceData->ScsiData->IsrContext = DeviceExtension;
   9.376 +// might we need a barrier here???
   9.377 +  DeviceData->ScsiData->IsrRoutine = XenVbdDev_Interrupt;
   9.378 +
   9.379 +  DeviceData->shadow = ExAllocatePoolWithTag(NonPagedPool, sizeof(blkif_shadow_t) * BLK_RING_SIZE, XENVBDDEV_POOL_TAG);
   9.380 +  memset(DeviceData->shadow, 0, sizeof(blkif_shadow_t) * BLK_RING_SIZE);
   9.381 +  for (i = 0; i < BLK_RING_SIZE; i++)
   9.382 +    DeviceData->shadow[i].req.id = i + 1;
   9.383 +  DeviceData->shadow_free = 0;
   9.384 +  DeviceData->shadow[BLK_RING_SIZE - 1].req.id = 0x0fffffff;
   9.385 +
   9.386 +  KeInitializeSpinLock(&DeviceData->Lock);
   9.387 +
   9.388 +  KeInitializeEvent(&XenVbdDev_ScsiPortThreadEvent, SynchronizationEvent, FALSE);
   9.389 +
   9.390 +  InitializeObjectAttributes(&oa, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
   9.391 +  Status = PsCreateSystemThread(&XenVbdDev_ScsiPortThreadHandle, THREAD_ALL_ACCESS, &oa, NULL, NULL, XenVbdDev_ScsiPortThreadProc, DeviceExtension);
   9.392 +
   9.393 +  return TRUE;
   9.394 +}
   9.395 +
   9.396 +static ULONG
   9.397 +XenVbdDev_FillModePage(PXENVBDDEV_DEVICE_DATA DeviceData, UCHAR PageCode, PUCHAR DataBuffer, ULONG BufferLength, PULONG Offset)
   9.398 +{
   9.399 +  PMODE_RIGID_GEOMETRY_PAGE ModeRigidGeometry;
   9.400 +
   9.401 +  switch (PageCode)
   9.402 +  {
   9.403 +/*
   9.404 +  case MODE_PAGE_RIGID_GEOMETRY:
   9.405 +    if (DeviceData->ScsiData->DeviceType == XENVBD_DEVICETYPE_CDROM)
   9.406 +    {
   9.407 +    KdPrint((__DRIVER_NAME "     MODE_PAGE_RIGID_GEOMETRY\n"));
   9.408 +    if (*Offset + sizeof(MODE_RIGID_GEOMETRY_PAGE) > BufferLength)
   9.409 +      return 1;
   9.410 +    ModeRigidGeometry = (PMODE_RIGID_GEOMETRY_PAGE)(DataBuffer + *Offset);
   9.411 +    memset(ModeRigidGeometry, 0, sizeof(MODE_RIGID_GEOMETRY_PAGE));
   9.412 +    ModeRigidGeometry->PageCode = PageCode;
   9.413 +    ModeRigidGeometry->PageSavable = 0;
   9.414 +    ModeRigidGeometry->PageLength = sizeof(MODE_RIGID_GEOMETRY_PAGE);
   9.415 +    ModeRigidGeometry->NumberOfCylinders[0] = (DeviceData->Geometry.Cylinders.LowPart >> 16) & 0xFF;
   9.416 +    ModeRigidGeometry->NumberOfCylinders[1] = (DeviceData->Geometry.Cylinders.LowPart >> 8) & 0xFF;
   9.417 +    ModeRigidGeometry->NumberOfCylinders[2] = (DeviceData->Geometry.Cylinders.LowPart >> 0) & 0xFF;
   9.418 +    ModeRigidGeometry->NumberOfHeads = DeviceData->Geometry.TracksPerCylinder;
   9.419 +    //ModeRigidGeometry->LandZoneCyclinder = 0;
   9.420 +    ModeRigidGeometry->RoataionRate[0] = 0x05;
   9.421 +    ModeRigidGeometry->RoataionRate[0] = 0x39;
   9.422 +    *Offset += sizeof(MODE_RIGID_GEOMETRY_PAGE);
   9.423 +    }
   9.424 +    break;
   9.425 +*/
   9.426 +  case MODE_PAGE_FAULT_REPORTING:
   9.427 +    break;
   9.428 +  default:
   9.429 +    break;
   9.430 +  }
   9.431 +  return 0;
   9.432 +}
   9.433 +
   9.434 +// Call with device lock held
   9.435 +static VOID
   9.436 +XenVbdDev_PutSrbOnRing(PXENVBDDEV_DEVICE_DATA DeviceData, PSCSI_REQUEST_BLOCK Srb)
   9.437 +{
   9.438 +  //PUCHAR DataBuffer;
   9.439 +  blkif_request_t *req;
   9.440 +  int i;
   9.441 +  int j;
   9.442 +  int BlockCount;
   9.443 +  int sect_offset;
   9.444 +
   9.445 +// can use SRB_STATUS_BUSY to push the SRB back to windows...
   9.446 +
   9.447 +  KdPrint((__DRIVER_NAME " --> PutSrbOnRing\n"));
   9.448 +
   9.449 +  if (RING_FULL(&DeviceData->ScsiData->Ring))
   9.450 +  {
   9.451 +    KdPrint((__DRIVER_NAME "     RING IS FULL - EXPECT BADNESS\n"));
   9.452 +    // TODO: Fail badly here
   9.453 +  }
   9.454 +
   9.455 +  req = RING_GET_REQUEST(&DeviceData->ScsiData->Ring, DeviceData->ScsiData->Ring.req_prod_pvt);
   9.456 +
   9.457 +  //KdPrint((__DRIVER_NAME "     req = %08x\n", req));
   9.458 +
   9.459 +  req->sector_number = (Srb->Cdb[2] << 24) | (Srb->Cdb[3] << 16) | (Srb->Cdb[4] << 8) | Srb->Cdb[5];
   9.460 +  BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
   9.461 +
   9.462 +  req->id = GET_ID_FROM_FREELIST(DeviceData);
   9.463 +
   9.464 +  KdPrint((__DRIVER_NAME "     Request Id = %d\n", req->id));
   9.465 +
   9.466 +  if (req->id == 0x0fffffff)
   9.467 +  {
   9.468 +    KdPrint((__DRIVER_NAME "     Something is horribly wrong in PutSrbOnRing\n"));
   9.469 +  }
   9.470 +
   9.471 +  req->handle = 0;
   9.472 +  req->operation = (Srb->Cdb[0] == SCSIOP_READ)?BLKIF_OP_READ:BLKIF_OP_WRITE;
   9.473 +  DeviceData->shadow[req->id].Srb = Srb;
   9.474 +
   9.475 +  DeviceData->shadow[req->id].Mdl = AllocatePages((BlockCount * DeviceData->ScsiData->BytesPerSector + PAGE_SIZE - 1) / PAGE_SIZE);
   9.476 +  DeviceData->shadow[req->id].Buf = MmGetMdlVirtualAddress(DeviceData->shadow[req->id].Mdl);
   9.477 +  if (DeviceData->shadow[req->id].Buf == NULL)
   9.478 +  {
   9.479 +    KdPrint((__DRIVER_NAME "     MmGetMdlVirtualAddress returned NULL in PutSrbOnRing\n"));
   9.480 +  }
   9.481 +  sect_offset = MmGetMdlByteOffset(DeviceData->shadow[req->id].Mdl) >> 9;
   9.482 +  for (i = 0, req->nr_segments = 0; i < BlockCount; req->nr_segments++)
   9.483 +  {
   9.484 +    req->seg[req->nr_segments].gref = GntTblInterface.GrantAccess(0, MmGetMdlPfnArray(DeviceData->shadow[req->id].Mdl)[req->nr_segments], FALSE);
   9.485 +    req->seg[req->nr_segments].first_sect = sect_offset;
   9.486 +    for (j = sect_offset; i < BlockCount && j < PAGE_SIZE / DeviceData->ScsiData->BytesPerSector; j++, i++)
   9.487 +      req->seg[req->nr_segments].last_sect = (uint8_t)j;
   9.488 +    sect_offset = 0;
   9.489 +  }
   9.490 +  if (Srb->Cdb[0] == SCSIOP_READ) // && DeviceData->shadow[req->id].Buf != NULL)
   9.491 +  {
   9.492 +    KdPrint((__DRIVER_NAME "     Read Sector = %08X, Sectors = %d\n", (int)req->sector_number, BlockCount));
   9.493 +  }
   9.494 +  else
   9.495 +  {
   9.496 +    KdPrint((__DRIVER_NAME "     Write Sector = %08X, Sectors = %d\n", (int)req->sector_number, BlockCount));
   9.497 +    memcpy(DeviceData->shadow[req->id].Buf, Srb->DataBuffer, BlockCount * DeviceData->ScsiData->BytesPerSector);
   9.498 +  }
   9.499 +  DeviceData->shadow[req->id].req = *req;
   9.500 +
   9.501 +  DeviceData->ScsiData->Ring.req_prod_pvt++;
   9.502 +
   9.503 +  KdPrint((__DRIVER_NAME " <-- PutSrbOnRing\n"));
   9.504 +}
   9.505 +
   9.506 +static BOOLEAN
   9.507 +XenVbdDev_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
   9.508 +{
   9.509 +  PUCHAR DataBuffer;
   9.510 +  PCDB cdb;
   9.511 +  PXENVBDDEV_DEVICE_DATA DeviceData = (PXENVBDDEV_DEVICE_DATA)DeviceExtension;
   9.512 +  unsigned int i;
   9.513 +  KIRQL KIrql;
   9.514 +  int notify;
   9.515 +  SCSI_PHYSICAL_ADDRESS ScsiPhysicalAddress;
   9.516 +  ULONG Length;
   9.517 +
   9.518 +  KdPrint((__DRIVER_NAME " --> HwScsiStartIo PathId = %d, TargetId = %d, Lun = %d\n", Srb->PathId, Srb->TargetId, Srb->Lun));
   9.519 +
   9.520 +  if (Srb->TargetId != 0 || Srb->Lun != 0)
   9.521 +  {
   9.522 +    Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
   9.523 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   9.524 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
   9.525 +    KdPrint((__DRIVER_NAME " <-- HwScsiStartIo (No Device)\n"));
   9.526 +    return TRUE;
   9.527 +  }
   9.528 +
   9.529 +  switch (Srb->Function)
   9.530 +  {
   9.531 +  case SRB_FUNCTION_EXECUTE_SCSI:
   9.532 +    cdb = (PCDB)Srb->Cdb;
   9.533 +    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_EXECUTE_SCSI\n"));
   9.534 +    switch(cdb->CDB6GENERIC.OperationCode)
   9.535 +    {
   9.536 +    case SCSIOP_TEST_UNIT_READY:
   9.537 +      KdPrint((__DRIVER_NAME "     Command = TEST_UNIT_READY\n"));
   9.538 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
   9.539 +      Srb->ScsiStatus = 0;
   9.540 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   9.541 +      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
   9.542 +      break;
   9.543 +    case SCSIOP_INQUIRY:
   9.544 +      KdPrint((__DRIVER_NAME "     Command = INQUIRY\n"));
   9.545 +      KdPrint((__DRIVER_NAME "     (LUN = %d, EVPD = %d, Page Code = %02X)\n", Srb->Cdb[1] >> 5, Srb->Cdb[1] & 1, Srb->Cdb[2]));
   9.546 +      KdPrint((__DRIVER_NAME "     (Length = %d)\n", Srb->DataTransferLength));
   9.547 +      KdPrint((__DRIVER_NAME "     (Databuffer = %08x)\n", Srb->DataBuffer));
   9.548 +      DataBuffer = Srb->DataBuffer;
   9.549 +      RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
   9.550 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
   9.551 +      if ((Srb->Cdb[1] & 1) == 0)
   9.552 +      {
   9.553 +        DataBuffer[0] = DIRECT_ACCESS_DEVICE;
   9.554 +        DataBuffer[1] = 0x00; // not removable
   9.555 +        DataBuffer[3] = 32;
   9.556 +        memcpy(DataBuffer + 8, "James   ", 8); // vendor id
   9.557 +        memcpy(DataBuffer + 16, "XenVBD          ", 16); // product id
   9.558 +        memcpy(DataBuffer + 32, "0000", 4); // product revision level
   9.559 +      }
   9.560 +      else
   9.561 +      {
   9.562 +        switch (Srb->Cdb[2])
   9.563 +        {
   9.564 +        case 0x00:
   9.565 +          DataBuffer[0] = DIRECT_ACCESS_DEVICE;
   9.566 +          DataBuffer[1] = 0x00;
   9.567 +          DataBuffer[2] = 0x00;
   9.568 +          DataBuffer[3] = 2;
   9.569 +          DataBuffer[4] = 0x00;
   9.570 +          DataBuffer[5] = 0x80;
   9.571 +          break;
   9.572 +        case 0x80:
   9.573 +          DataBuffer[0] = DIRECT_ACCESS_DEVICE;
   9.574 +          DataBuffer[1] = 0x80;
   9.575 +          DataBuffer[2] = 0x00;
   9.576 +          DataBuffer[3] = 8;
   9.577 +          DataBuffer[4] = 0x31;
   9.578 +          DataBuffer[5] = 0x32;
   9.579 +          DataBuffer[6] = 0x33;
   9.580 +          DataBuffer[7] = 0x34;
   9.581 +          DataBuffer[8] = 0x35;
   9.582 +          DataBuffer[9] = 0x36;
   9.583 +          DataBuffer[10] = 0x37;
   9.584 +          DataBuffer[11] = 0x38;
   9.585 +          break;
   9.586 +        default:
   9.587 +          KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", Srb->Cdb[2]));
   9.588 +          Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
   9.589 +          break;
   9.590 +        }
   9.591 +//        KdPrint((__DRIVER_NAME "     Command = INQUIRY (LUN = %d, EVPD = %d, Page Code = %02X)\n", Srb->Cdb[1] >> 5, Srb->Cdb[1] & 1, Srb->Cdb[2]));
   9.592 +      }
   9.593 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   9.594 +      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
   9.595 +      break;
   9.596 +    case SCSIOP_READ_CAPACITY:
   9.597 +      KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
   9.598 +      DataBuffer = Srb->DataBuffer;
   9.599 +      RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
   9.600 +      DataBuffer[0] = (unsigned char)(DeviceData->ScsiData->TotalSectors >> 24) & 0xff;
   9.601 +      DataBuffer[1] = (unsigned char)(DeviceData->ScsiData->TotalSectors >> 16) & 0xff;
   9.602 +      DataBuffer[2] = (unsigned char)(DeviceData->ScsiData->TotalSectors >> 8) & 0xff;
   9.603 +      DataBuffer[3] = (unsigned char)(DeviceData->ScsiData->TotalSectors >> 0) & 0xff;
   9.604 +      DataBuffer[4] = (unsigned char)(DeviceData->ScsiData->BytesPerSector >> 24) & 0xff;
   9.605 +      DataBuffer[5] = (unsigned char)(DeviceData->ScsiData->BytesPerSector >> 16) & 0xff;
   9.606 +      DataBuffer[6] = (unsigned char)(DeviceData->ScsiData->BytesPerSector >> 8) & 0xff;
   9.607 +      DataBuffer[7] = (unsigned char)(DeviceData->ScsiData->BytesPerSector >> 0) & 0xff;
   9.608 +      Srb->ScsiStatus = 0;
   9.609 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
   9.610 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   9.611 +      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
   9.612 +      break;
   9.613 +    case SCSIOP_MODE_SENSE:
   9.614 +      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));
   9.615 +      KdPrint((__DRIVER_NAME "     Length = %d\n", Srb->DataTransferLength));
   9.616 +
   9.617 +      Srb->ScsiStatus = 0;
   9.618 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
   9.619 +      Srb->DataTransferLength = 0;
   9.620 +      ScsiPhysicalAddress = ScsiPortGetPhysicalAddress(DeviceData, Srb, Srb->DataBuffer, &Srb->DataTransferLength);
   9.621 +      DataBuffer = ScsiPortGetVirtualAddress(DeviceData, ScsiPhysicalAddress);
   9.622 +      RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
   9.623 +      switch(cdb->MODE_SENSE.PageCode)
   9.624 +      {
   9.625 +      case MODE_SENSE_RETURN_ALL:
   9.626 +        //Ptr = (UCHAR *)Srb->DataBuffer;
   9.627 +        for (i = 0; i < MODE_SENSE_RETURN_ALL; i++)
   9.628 +        {
   9.629 +          if (XenVbdDev_FillModePage(DeviceData, cdb->MODE_SENSE.PageCode, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Srb->DataTransferLength))
   9.630 +          {
   9.631 +            break;
   9.632 +          }
   9.633 +        }
   9.634 +        break;
   9.635 +      default:
   9.636 +        XenVbdDev_FillModePage(DeviceData, cdb->MODE_SENSE.PageCode, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Srb->DataTransferLength);
   9.637 +        break;
   9.638 +      }
   9.639 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   9.640 +      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
   9.641 +      break;
   9.642 +    case SCSIOP_READ:
   9.643 +    case SCSIOP_WRITE:
   9.644 +      KdPrint((__DRIVER_NAME "     Command = READ/WRITE\n"));
   9.645 +
   9.646 +      for (i = 0; i < 10; i++)
   9.647 +      {
   9.648 +        KdPrint((__DRIVER_NAME "     %02x: %02x\n", i, Srb->Cdb[i]));
   9.649 +      }
   9.650 +      //KeAcquireSpinLock(&DeviceData->Lock, &KIrql);
   9.651 +
   9.652 +      XenVbdDev_PutSrbOnRing(DeviceData, Srb);
   9.653 +      RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&DeviceData->ScsiData->Ring, notify);
   9.654 +      if (notify)
   9.655 +        DeviceData->ScsiData->NotifyRoutine(DeviceData->ScsiData->NotifyContext);
   9.656 +      //KeReleaseSpinLock(&DeviceData->Lock, KIrql);
   9.657 +//      Srb->SrbStatus = SRB_STATUS_SUCCESS;
   9.658 +//      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   9.659 +      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
   9.660 +
   9.661 +      break;
   9.662 +    case SCSIOP_REPORT_LUNS:
   9.663 +      KdPrint((__DRIVER_NAME "     Command = REPORT_LUNS\n"));
   9.664 +      Srb->SrbStatus = SRB_STATUS_SUCCESS; //SRB_STATUS_INVALID_REQUEST;
   9.665 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   9.666 +      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
   9.667 +      break;
   9.668 +    default:
   9.669 +      KdPrint((__DRIVER_NAME "     Unhandled EXECUTE_SCSI Command = %02X\n", Srb->Cdb[0]));
   9.670 +      Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
   9.671 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   9.672 +      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
   9.673 +      break;
   9.674 +    }
   9.675 +    break;
   9.676 +  case SRB_FUNCTION_CLAIM_DEVICE:
   9.677 +    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_CLAIM_DEVICE\n"));
   9.678 +//    ObReferenceObject(WdfDeviceWdmGetDeviceObject(Device));
   9.679 +//    Srb->DataBuffer = WdfDeviceWdmGetDeviceObject(Device);
   9.680 +    Srb->SrbStatus = SRB_STATUS_SUCCESS;
   9.681 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   9.682 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
   9.683 +    break;
   9.684 +  case SRB_FUNCTION_IO_CONTROL:
   9.685 +    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_IO_CONTROL\n"));
   9.686 +    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
   9.687 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   9.688 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
   9.689 +    break;
   9.690 +  case SRB_FUNCTION_FLUSH:
   9.691 +    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH\n"));
   9.692 +    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
   9.693 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   9.694 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
   9.695 +    break;
   9.696 +  default:
   9.697 +    KdPrint((__DRIVER_NAME "     Unhandled Srb->Function = %08X\n", Srb->Function));
   9.698 +    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
   9.699 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   9.700 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
   9.701 +    break;
   9.702 +  }
   9.703 +
   9.704 +  KdPrint((__DRIVER_NAME " <-- HwScsiStartIo\n"));
   9.705 +
   9.706 +  return TRUE;
   9.707 +}
   9.708 +
   9.709 +/*
   9.710 +static BOOLEAN
   9.711 +XenVbdDev_HwScsiInterrupt(PVOID DeviceExtension)
   9.712 +{
   9.713 +  KdPrint((__DRIVER_NAME " --> HwScsiInterrupt\n"));
   9.714 +
   9.715 +  KdPrint((__DRIVER_NAME " <-- HwScsiInterrupt\n"));
   9.716 +
   9.717 +  return TRUE;
   9.718 +}
   9.719 +*/
   9.720 +
   9.721 +static BOOLEAN
   9.722 +XenVbdDev_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId)
   9.723 +{
   9.724 +  KdPrint((__DRIVER_NAME " --> HwScsiResetBus\n"));
   9.725 +
   9.726 +  KdPrint((__DRIVER_NAME " <-- HwScsiResetBus\n"));
   9.727 +
   9.728 +  return TRUE;
   9.729 +}
   9.730 +
   9.731 +
   9.732 +static BOOLEAN
   9.733 +XenVbdDev_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState)
   9.734 +{
   9.735 +  KdPrint((__DRIVER_NAME " --> HwScsiAdapterState\n"));
   9.736 +
   9.737 +  KdPrint((__DRIVER_NAME " <-- HwScsiAdapterState\n"));
   9.738 +
   9.739 +  return TRUE;
   9.740 +}
   9.741 +
   9.742 +static SCSI_ADAPTER_CONTROL_STATUS
   9.743 +XenVbdDev_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
   9.744 +{
   9.745 +  SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
   9.746 +  PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
   9.747 +
   9.748 +  KdPrint((__DRIVER_NAME " --> HwScsiAdapterControl\n"));
   9.749 +
   9.750 +  switch (ControlType)
   9.751 +  {
   9.752 +  case ScsiQuerySupportedControlTypes:
   9.753 +    SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
   9.754 +    KdPrint((__DRIVER_NAME "     ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
   9.755 +    SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
   9.756 +    SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
   9.757 +    break;
   9.758 +  case ScsiStopAdapter:
   9.759 +    KdPrint((__DRIVER_NAME "     ScsiStopAdapter\n"));
   9.760 +    break;
   9.761 +  case ScsiRestartAdapter:
   9.762 +    KdPrint((__DRIVER_NAME "     ScsiRestartAdapter\n"));
   9.763 +    break;
   9.764 +  case ScsiSetBootConfig:
   9.765 +    KdPrint((__DRIVER_NAME "     ScsiSetBootConfig\n"));
   9.766 +    break;
   9.767 +  case ScsiSetRunningConfig:
   9.768 +    KdPrint((__DRIVER_NAME "     ScsiSetRunningConfig\n"));
   9.769 +    break;
   9.770 +  default:
   9.771 +    KdPrint((__DRIVER_NAME "     UNKNOWN\n"));
   9.772 +    break;
   9.773 +  }
   9.774 +
   9.775 +  KdPrint((__DRIVER_NAME " <-- HwScsiAdapterControl\n"));
   9.776 +
   9.777 +  return Status;
   9.778 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/xenvbddev/xenvbddev.h	Fri Nov 30 21:33:49 2007 +1100
    10.3 @@ -0,0 +1,104 @@
    10.4 +#if !defined(_XENVBDDEV_H_)
    10.5 +#define _XENVBDDEV_H_
    10.6 +
    10.7 +#include <ntddk.h>
    10.8 +#include <wdm.h>
    10.9 +#include <wdf.h>
   10.10 +#include <initguid.h>
   10.11 +#include <ntdddisk.h>
   10.12 +#include <srb.h>
   10.13 +
   10.14 +#define NTSTRSAFE_LIB
   10.15 +#include <ntstrsafe.h>
   10.16 +
   10.17 +#include <xen_windows.h>
   10.18 +#include <memory.h>
   10.19 +#include <grant_table.h>
   10.20 +#include <event_channel.h>
   10.21 +#include <hvm/params.h>
   10.22 +#include <hvm/hvm_op.h>
   10.23 +#include <evtchn_public.h>
   10.24 +#include <xenbus_public.h>
   10.25 +#include <gnttbl_public.h>
   10.26 +#include <io/ring.h>
   10.27 +#include <io/blkif.h>
   10.28 +#define __DRIVER_NAME "XenVbdDev"
   10.29 +#define XENVBDDEV_POOL_TAG (ULONG) 'XVBD'
   10.30 +
   10.31 +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
   10.32 +#define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
   10.33 +
   10.34 +typedef struct {
   10.35 +  blkif_request_t req;
   10.36 +  PSCSI_REQUEST_BLOCK Srb;
   10.37 +  PMDL Mdl;
   10.38 +  VOID *Buf;
   10.39 +} blkif_shadow_t;
   10.40 +
   10.41 +#include "scsidata.h"
   10.42 +
   10.43 +struct
   10.44 +{
   10.45 +  PXENVBDDEV_SCSI_DATA ScsiData;
   10.46 +
   10.47 +  KSPIN_LOCK Lock;
   10.48 +
   10.49 +  blkif_shadow_t *shadow;
   10.50 +  uint64_t shadow_free;
   10.51 +
   10.52 +  int FastPathUsed;
   10.53 +  int SlowPathUsed;
   10.54 +} typedef XENVBDDEV_DEVICE_DATA, *PXENVBDDEV_DEVICE_DATA;
   10.55 +
   10.56 +/*
   10.57 +struct {
   10.58 +  LIST_ENTRY Entry;
   10.59 +//  KSPIN_LOCK Lock;
   10.60 +//  WDFQUEUE IoDefaultQueue;
   10.61 +  WDFDEVICE Device;
   10.62 +  char Path[128];
   10.63 +  char BackendPath[128];
   10.64 +  ULONG DeviceIndex;
   10.65 +  evtchn_port_t EventChannel;
   10.66 +  //blkif_sring_t *SharedRing;
   10.67 +  ULONG RingBufPFN;
   10.68 +  int BackendState;
   10.69 +  int FrontendState;
   10.70 +  blkif_front_ring_t Ring;
   10.71 +  blkif_shadow_t *shadow;
   10.72 +  uint64_t shadow_free;
   10.73 +
   10.74 +  LIST_ENTRY IrpListHead;
   10.75 +  KSPIN_LOCK IrpListLock;
   10.76 +
   10.77 +  WDFDPC Dpc;
   10.78 +
   10.79 +//  ULONG BytesPerSector;
   10.80 +//  ULONGLONG TotalSectors;
   10.81 +  DISK_GEOMETRY Geometry;
   10.82 +  XENVBD_DEVICETYPE DeviceType;
   10.83 +
   10.84 +  int IrpAddedToList;
   10.85 +  int IrpRemovedFromList;
   10.86 +  int IrpAddedToRing;
   10.87 +  int IrpAddedToRingAtLastNotify;
   10.88 +  int IrpAddedToRingAtLastInterrupt;
   10.89 +  int IrpAddedToRingAtLastDpc;
   10.90 +  int IrpRemovedFromRing;
   10.91 +  int IrpCompleted;
   10.92 +
   10.93 +  int FastPathUsed;
   10.94 +  int SlowPathUsed;
   10.95 +
   10.96 +} typedef XENVBD_CHILD_DEVICE_DATA, *PXENVBD_CHILD_DEVICE_DATA, **PPXENVBD_CHILD_DEVICE_DATA;
   10.97 +
   10.98 +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(PXENVBD_CHILD_DEVICE_DATA, GetChildDeviceData);
   10.99 +
  10.100 +typedef struct _XENVBD_DEVICE_IDENTIFICATION_DESCRIPTION
  10.101 +{
  10.102 +  WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Header;
  10.103 +  PXENVBD_CHILD_DEVICE_DATA DeviceData;
  10.104 +} XENVBD_DEVICE_IDENTIFICATION_DESCRIPTION, *PXENVBD_DEVICE_IDENTIFICATION_DESCRIPTION;
  10.105 +*/
  10.106 +
  10.107 +#endif