win-pvdrivers

changeset 191:8609c27c4893

Added SCSI passthrough support (vscsi). Works as far as windows can see the device, but haven't tested any further
author James Harper <james.harper@bendigoit.com.au>
date Wed Feb 20 17:14:14 2008 +1100 (2008-02-20)
parents 8242c5efce07
children 268fe1eb3ae2
files common.inc common/include/public/io/vscsiif.h common/include/xen_public.h dirs xenenum/xenenum.c xenpci/xenpci.c xenpci/xenpci.h xenscsi/makefile xenscsi/makefile.inc xenscsi/sources xenscsi/xenscsi.c xenscsi/xenscsi.h xenscsi/xenscsi.inx xenvbd/xenvbd.c
line diff
     1.1 --- a/common.inc	Mon Feb 18 22:32:41 2008 +1100
     1.2 +++ b/common.inc	Wed Feb 20 17:14:14 2008 +1100
     1.3 @@ -1,4 +1,4 @@
     1.4 -VERSION=0.7.0.77
     1.5 +VERSION=0.7.0.98
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7  KMDF_VERSION=1
     1.8  !IF $(_NT_TOOLS_VERSION) > 0x700
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/common/include/public/io/vscsiif.h	Wed Feb 20 17:14:14 2008 +1100
     2.3 @@ -0,0 +1,73 @@
     2.4 +/******************************************************************************
     2.5 + * scsiif.h
     2.6 + * 
     2.7 + * Based on the blkif.h code.
     2.8 + * 
     2.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    2.10 + * of this software and associated documentation files (the "Software"), to
    2.11 + * deal in the Software without restriction, including without limitation the
    2.12 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    2.13 + * sell copies of the Software, and to permit persons to whom the Software is
    2.14 + * furnished to do so, subject to the following conditions:
    2.15 + *
    2.16 + * The above copyright notice and this permission notice shall be included in
    2.17 + * all copies or substantial portions of the Software.
    2.18 + *
    2.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    2.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    2.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    2.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    2.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    2.24 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    2.25 + * DEALINGS IN THE SOFTWARE.
    2.26 + *
    2.27 + * Copyright(c) FUJITSU Limited 2008.
    2.28 + */
    2.29 +
    2.30 +#ifndef __XEN__PUBLIC_IO_SCSI_H__
    2.31 +#define __XEN__PUBLIC_IO_SCSI_H__
    2.32 +
    2.33 +#include "ring.h"
    2.34 +#include "../grant_table.h"
    2.35 +
    2.36 +#define VSCSIIF_CMND_SCSI			1	/* scsi */
    2.37 +#define VSCSIIF_CMND_SCSI_RESET			2	/* scsi */
    2.38 +
    2.39 +/* ----------------------------------------------------------------------
    2.40 +	Definition of Ring Structures
    2.41 +   ---------------------------------------------------------------------- */
    2.42 +
    2.43 +#define VSCSIIF_DEFAULT_CAN_QUEUE	256
    2.44 +#define VSCSIIF_MAX_COMMAND_SIZE	16
    2.45 +#define VSCSIIF_SG_TABLESIZE		27
    2.46 +
    2.47 +struct vscsiif_request {
    2.48 +	uint16_t rqid;
    2.49 +	uint8_t cmd;
    2.50 +	/* SCSI */
    2.51 +	uint8_t cmnd[VSCSIIF_MAX_COMMAND_SIZE];
    2.52 +	uint8_t cmd_len;
    2.53 +	uint16_t id, lun, channel;
    2.54 +	uint8_t sc_data_direction;
    2.55 +	uint8_t use_sg;
    2.56 +	uint32_t request_bufflen;
    2.57 +	/*int32_t timeout_per_command;*/
    2.58 +	struct scsiif_request_segment {
    2.59 +		grant_ref_t gref;
    2.60 +		uint16_t offset;
    2.61 +		uint16_t length;
    2.62 +	} seg[VSCSIIF_SG_TABLESIZE];
    2.63 +};
    2.64 +
    2.65 +#define VSCSIIF_SENSE_BUFFERSIZE 	96
    2.66 +
    2.67 +struct vscsiif_response {
    2.68 +	uint16_t rqid;
    2.69 +	int32_t  rslt;
    2.70 +	uint8_t sense_len;
    2.71 +	uint8_t sense_buffer[VSCSIIF_SENSE_BUFFERSIZE];
    2.72 +};
    2.73 +
    2.74 +DEFINE_RING_TYPES(vscsiif, struct vscsiif_request, struct vscsiif_response);
    2.75 +
    2.76 +#endif
     3.1 --- a/common/include/xen_public.h	Mon Feb 18 22:32:41 2008 +1100
     3.2 +++ b/common/include/xen_public.h	Wed Feb 20 17:14:14 2008 +1100
     3.3 @@ -114,7 +114,7 @@ typedef struct _XEN_IFACE {
     3.4  typedef struct _XENPCI_IDENTIFICATION_DESCRIPTION
     3.5  {
     3.6    WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Header;
     3.7 -  UNICODE_STRING DeviceType;
     3.8 +  char DeviceType[128]; //UNICODE_STRING DeviceType;
     3.9    char Path[128];
    3.10    ULONG DeviceIndex;
    3.11  } XENPCI_IDENTIFICATION_DESCRIPTION, *PXENPCI_IDENTIFICATION_DESCRIPTION;
     4.1 --- a/dirs	Mon Feb 18 22:32:41 2008 +1100
     4.2 +++ b/dirs	Wed Feb 20 17:14:14 2008 +1100
     4.3 @@ -1,1 +1,1 @@
     4.4 -DIRS=xenpci xenhide xenvbd xenaddresource xenenum xennet xenstub
     4.5 \ No newline at end of file
     4.6 +DIRS=xenpci xenhide xenvbd xenaddresource xenenum xennet xenstub xenscsi
     4.7 \ No newline at end of file
     5.1 --- a/xenenum/xenenum.c	Mon Feb 18 22:32:41 2008 +1100
     5.2 +++ b/xenenum/xenenum.c	Wed Feb 20 17:14:14 2008 +1100
     5.3 @@ -40,10 +40,15 @@ XenEnum_WatchHandler(char *Path, PVOID D
     5.4  #pragma alloc_text (PAGE, XenEnum_AddDevice)
     5.5  #endif
     5.6  
     5.7 -LIST_ENTRY DeviceListHead;
     5.8 -XEN_IFACE XenInterface;
     5.9 +typedef struct {
    5.10 +  LIST_ENTRY DeviceListHead;
    5.11 +  XEN_IFACE XenInterface;
    5.12 +  PDEVICE_OBJECT Pdo;
    5.13 +  BOOLEAN AutoEnumerate;
    5.14 +  KGUARDED_MUTEX WatchHandlerMutex;
    5.15 +} XENENUM_DEVICE_DATA, *PXENENUM_DEVICE_DATA;
    5.16  
    5.17 -static BOOLEAN AutoEnumerate;
    5.18 +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENENUM_DEVICE_DATA, GetDeviceData);
    5.19  
    5.20  NTSTATUS
    5.21  DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
    5.22 @@ -72,9 +77,6 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
    5.23  
    5.24  DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC828ABE9, 0x14CA, 0x4445, 0xBA, 0xA6, 0x82, 0xC2, 0x37, 0x6C, 0x65, 0x18);
    5.25  
    5.26 -static WDFDEVICE GlobalDevice;
    5.27 -static PDEVICE_OBJECT Pdo;
    5.28 -
    5.29  static NTSTATUS
    5.30  XenEnum_AddDevice(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit)
    5.31  {
    5.32 @@ -82,10 +84,14 @@ XenEnum_AddDevice(WDFDRIVER Driver, PWDF
    5.33    NTSTATUS status;
    5.34    WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
    5.35    PNP_BUS_INFORMATION BusInfo;
    5.36 +  WDFDEVICE Device;
    5.37 +  WDF_OBJECT_ATTRIBUTES attributes;
    5.38 +  PXENENUM_DEVICE_DATA xedd;
    5.39 +  PDEVICE_OBJECT Pdo;
    5.40    
    5.41    UNREFERENCED_PARAMETER(Driver);
    5.42  
    5.43 -  KdPrint((__DRIVER_NAME " --> DeviceAdd\n"));
    5.44 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    5.45  
    5.46    Pdo = WdfFdoInitWdmGetPhysicalDevice(DeviceInit);
    5.47  
    5.48 @@ -103,23 +109,28 @@ XenEnum_AddDevice(WDFDRIVER Driver, PWDF
    5.49    pnpPowerCallbacks.EvtDeviceUsageNotification = XenEnum_DeviceUsageNotification;
    5.50    WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
    5.51  
    5.52 -  /*create a device instance.*/
    5.53 -  status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &GlobalDevice);  
    5.54 +  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, XENENUM_DEVICE_DATA);
    5.55 +
    5.56 +  status = WdfDeviceCreate(&DeviceInit, &attributes, &Device);
    5.57    if(!NT_SUCCESS(status))
    5.58    {
    5.59      KdPrint((__DRIVER_NAME "WdfDeviceCreate failed with status 0x%08x\n", status));
    5.60      return status;
    5.61    }
    5.62  
    5.63 +  xedd = GetDeviceData(Device);
    5.64 +  
    5.65 +  KeInitializeGuardedMutex(&xedd->WatchHandlerMutex);
    5.66 +
    5.67 +  xedd->Pdo = Pdo;
    5.68 +
    5.69    BusInfo.BusTypeGuid = GUID_XENPCI_DEVCLASS;
    5.70    BusInfo.LegacyBusType = Internal;
    5.71    BusInfo.BusNumber = 0;
    5.72  
    5.73 -  WdfDeviceSetBusInformationForChildren(GlobalDevice, &BusInfo);
    5.74 +  WdfDeviceSetBusInformationForChildren(Device, &BusInfo);
    5.75  
    5.76 -  status = STATUS_SUCCESS;
    5.77 -
    5.78 -  KdPrint((__DRIVER_NAME " <-- DeviceAdd\n"));
    5.79 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    5.80    return status;
    5.81  }
    5.82  
    5.83 @@ -130,19 +141,20 @@ XenEnum_PrepareHardware(
    5.84    IN WDFCMRESLIST ResourceListTranslated)
    5.85  {
    5.86    NTSTATUS status = STATUS_SUCCESS;
    5.87 +  PXENENUM_DEVICE_DATA xedd = GetDeviceData(Device);
    5.88  
    5.89    UNREFERENCED_PARAMETER(ResourceList);
    5.90    UNREFERENCED_PARAMETER(ResourceListTranslated);
    5.91  
    5.92    KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware\n"));
    5.93  
    5.94 -  status = WdfFdoQueryForInterface(Device, &GUID_XEN_IFACE, (PINTERFACE)&XenInterface, sizeof(XEN_IFACE), 1, NULL);
    5.95 +  status = WdfFdoQueryForInterface(Device, &GUID_XEN_IFACE, (PINTERFACE)&xedd->XenInterface, sizeof(XEN_IFACE), 1, NULL);
    5.96    if(!NT_SUCCESS(status))
    5.97    {
    5.98      KdPrint((__DRIVER_NAME "     WdfFdoQueryForInterface (EvtChn) failed with status 0x%08x\n", status));
    5.99    }
   5.100  
   5.101 -  InitializeListHead(&DeviceListHead);
   5.102 +  InitializeListHead(&xedd->DeviceListHead);
   5.103  
   5.104    KdPrint((__DRIVER_NAME " <-- EvtDevicePrepareHardware\n"));
   5.105  
   5.106 @@ -178,9 +190,6 @@ XenEnum_D0Entry(
   5.107    return status;
   5.108  }
   5.109  
   5.110 -static int EnumeratedDevices;
   5.111 -static KEVENT WaitDevicesEvent;
   5.112 -
   5.113  static NTSTATUS
   5.114  XenEnum_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState)
   5.115  {
   5.116 @@ -190,24 +199,22 @@ XenEnum_D0EntryPostInterruptsEnabled(WDF
   5.117    char *msg;
   5.118    char buffer[128];
   5.119    int i;
   5.120 +  PXENENUM_DEVICE_DATA xedd = GetDeviceData(Device);
   5.121  
   5.122    UNREFERENCED_PARAMETER(Device);
   5.123    UNREFERENCED_PARAMETER(PreviousState);
   5.124  
   5.125    KdPrint((__DRIVER_NAME " --> EvtDeviceD0EntryPostInterruptsEnabled\n"));
   5.126  
   5.127 -  PdoDeviceData = (PXENPCI_XEN_DEVICE_DATA)Pdo->DeviceExtension; //GetXenDeviceData(Device);
   5.128 +  PdoDeviceData = (PXENPCI_XEN_DEVICE_DATA)xedd->Pdo->DeviceExtension; //GetXenDeviceData(Device);
   5.129  
   5.130    //KdPrint((__DRIVER_NAME "     Path = %s\n", PdoDeviceData->Path));
   5.131    PdoDeviceData->WatchHandler = XenEnum_WatchHandler;
   5.132    PdoDeviceData->WatchContext = Device;
   5.133 -  AutoEnumerate = PdoDeviceData->AutoEnumerate;
   5.134 -
   5.135 -  EnumeratedDevices = 0;
   5.136 -  KeInitializeEvent(&WaitDevicesEvent, SynchronizationEvent, FALSE);  
   5.137 +  xedd->AutoEnumerate = PdoDeviceData->AutoEnumerate;
   5.138  
   5.139    // TODO: Should probably do this in an EvtChildListScanForChildren
   5.140 -  msg = XenInterface.XenBus_List(XenInterface.InterfaceHeader.Context, XBT_NIL, PdoDeviceData->Path, &Devices);
   5.141 +  msg = xedd->XenInterface.XenBus_List(xedd->XenInterface.InterfaceHeader.Context, XBT_NIL, PdoDeviceData->Path, &Devices);
   5.142    if (!msg)
   5.143    {
   5.144      for (i = 0; Devices[i]; i++)
   5.145 @@ -296,17 +303,19 @@ XenEnum_WatchHandler(char *Path, PVOID D
   5.146    XENPCI_IDENTIFICATION_DESCRIPTION IdentificationDescription;
   5.147    char **Bits;
   5.148    int Count;
   5.149 -  ANSI_STRING AnsiBuf;
   5.150    WDFCHILDLIST ChildList;
   5.151    WDFDEVICE Device = Data;
   5.152    WDF_CHILD_LIST_ITERATOR ChildIterator;
   5.153    WDFDEVICE ChildDevice;
   5.154    PXENPCI_XEN_DEVICE_DATA ChildDeviceData;
   5.155 +  PXENENUM_DEVICE_DATA xedd = GetDeviceData(Device);
   5.156  
   5.157    UNREFERENCED_PARAMETER(Data);  
   5.158  
   5.159    KdPrint((__DRIVER_NAME " --> WatchHandler\n"));
   5.160  
   5.161 +  KeAcquireGuardedMutex(&xedd->WatchHandlerMutex);
   5.162 +
   5.163    KdPrint((__DRIVER_NAME "     Path = %s\n", Path));
   5.164  
   5.165    Bits = SplitString(Path, '/', 4, &Count);
   5.166 @@ -314,12 +323,16 @@ XenEnum_WatchHandler(char *Path, PVOID D
   5.167    {
   5.168      KdPrint((__DRIVER_NAME "     Creating %s\n", Bits[2]));
   5.169      ChildList = WdfFdoGetDefaultChildList(Device);
   5.170 +    RtlZeroMemory(&IdentificationDescription, sizeof(IdentificationDescription));
   5.171      WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&IdentificationDescription.Header, sizeof(IdentificationDescription));
   5.172      strncpy(IdentificationDescription.Path, Path, 128);
   5.173 +    strncpy(IdentificationDescription.DeviceType, Bits[1], 128);
   5.174 +    strncat(IdentificationDescription.DeviceType, "dev", 128);
   5.175 +/*
   5.176      RtlInitAnsiString(&AnsiBuf, Bits[1]);
   5.177      RtlAnsiStringToUnicodeString(&IdentificationDescription.DeviceType, &AnsiBuf, TRUE);
   5.178 +*/
   5.179      IdentificationDescription.DeviceIndex = atoi(Bits[2]);
   5.180 -//    if (IdentificationDescription.DeviceIndex > 0)
   5.181      Status = WdfChildListAddOrUpdateChildDescriptionAsPresent(ChildList, &IdentificationDescription.Header, NULL);
   5.182    }
   5.183    else if (Count > 3)
   5.184 @@ -350,6 +363,8 @@ XenEnum_WatchHandler(char *Path, PVOID D
   5.185    }
   5.186    FreeSplitString(Bits, Count);
   5.187  
   5.188 +  KeReleaseGuardedMutex(&xedd->WatchHandlerMutex);
   5.189 +
   5.190    KdPrint((__DRIVER_NAME " <-- WatchHandler\n"));  
   5.191  
   5.192    return;
   5.193 @@ -366,8 +381,9 @@ XenEnum_ChildListCreateDevice(WDFCHILDLI
   5.194    DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
   5.195    PXENPCI_XEN_DEVICE_DATA ChildDeviceData = NULL;
   5.196    WDF_QUERY_INTERFACE_CONFIG  qiConfig;
   5.197 -//  WDF_PDO_EVENT_CALLBACKS PdoCallbacks;
   5.198 -//  UCHAR PnpMinors[2] = { IRP_MN_START_DEVICE, IRP_MN_STOP_DEVICE };
   5.199 +  PXENENUM_DEVICE_DATA xedd = GetDeviceData(WdfChildListGetDevice(ChildList));
   5.200 +  UNICODE_STRING DeviceType;
   5.201 +  ANSI_STRING AnsiBuf;
   5.202  
   5.203    UNREFERENCED_PARAMETER(ChildList);
   5.204  
   5.205 @@ -375,11 +391,12 @@ XenEnum_ChildListCreateDevice(WDFCHILDLI
   5.206  
   5.207    XenIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENPCI_IDENTIFICATION_DESCRIPTION, Header);
   5.208  
   5.209 -//  ChildDeviceData = XenEnumIdentificationDesc->DeviceData;
   5.210 +  RtlInitAnsiString(&AnsiBuf, XenIdentificationDesc->DeviceType);
   5.211 +  RtlAnsiStringToUnicodeString(&DeviceType, &AnsiBuf, TRUE);
   5.212  
   5.213    WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_UNKNOWN);
   5.214  
   5.215 -  status = RtlUnicodeStringPrintf(&buffer, L"XEN\\%wsdev\0", XenIdentificationDesc->DeviceType.Buffer);
   5.216 +  status = RtlUnicodeStringPrintf(&buffer, L"XEN\\%wZ\0", &DeviceType);
   5.217  
   5.218    KdPrint((__DRIVER_NAME "     %ws", buffer.Buffer));
   5.219  
   5.220 @@ -390,7 +407,7 @@ XenEnum_ChildListCreateDevice(WDFCHILDLI
   5.221    status = RtlUnicodeStringPrintf(&buffer, L"%02d\0", XenIdentificationDesc->DeviceIndex);
   5.222    status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
   5.223  
   5.224 -  status = RtlUnicodeStringPrintf(&buffer, L"Xen %ws Device (%d)", XenIdentificationDesc->DeviceType.Buffer, XenIdentificationDesc->DeviceIndex);
   5.225 +  status = RtlUnicodeStringPrintf(&buffer, L"Xen %wZ Device (%d)", &DeviceType, XenIdentificationDesc->DeviceIndex);
   5.226    status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
   5.227    WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
   5.228  
   5.229 @@ -408,38 +425,38 @@ XenEnum_ChildListCreateDevice(WDFCHILDLI
   5.230  
   5.231    ChildDeviceData = GetXenDeviceData(ChildDevice);
   5.232    ChildDeviceData->Magic = XEN_DATA_MAGIC;
   5.233 -  ChildDeviceData->AutoEnumerate = AutoEnumerate;
   5.234 +  ChildDeviceData->AutoEnumerate = xedd->AutoEnumerate;
   5.235    ChildDeviceData->WatchHandler = NULL;
   5.236    strncpy(ChildDeviceData->Path, XenIdentificationDesc->Path, 128);
   5.237    
   5.238    ChildDeviceData->XenInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->XenInterface);
   5.239    ChildDeviceData->XenInterface.InterfaceHeader.Version = 1;
   5.240 -  ChildDeviceData->XenInterface.InterfaceHeader.Context = XenInterface.InterfaceHeader.Context;
   5.241 +  ChildDeviceData->XenInterface.InterfaceHeader.Context = xedd->XenInterface.InterfaceHeader.Context;
   5.242    ChildDeviceData->XenInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
   5.243    ChildDeviceData->XenInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
   5.244  
   5.245 -  ChildDeviceData->XenInterface.AllocMMIO = XenInterface.AllocMMIO;
   5.246 -  ChildDeviceData->XenInterface.FreeMem = XenInterface.FreeMem;
   5.247 -
   5.248 -  ChildDeviceData->XenInterface.EvtChn_Bind = XenInterface.EvtChn_Bind;
   5.249 -  ChildDeviceData->XenInterface.EvtChn_Unbind = XenInterface.EvtChn_Unbind;
   5.250 -  ChildDeviceData->XenInterface.EvtChn_Mask = XenInterface.EvtChn_Mask;
   5.251 -  ChildDeviceData->XenInterface.EvtChn_Unmask = XenInterface.EvtChn_Unmask;
   5.252 -  ChildDeviceData->XenInterface.EvtChn_Notify = XenInterface.EvtChn_Notify;
   5.253 -  ChildDeviceData->XenInterface.EvtChn_AllocUnbound = XenInterface.EvtChn_AllocUnbound;
   5.254 -  ChildDeviceData->XenInterface.EvtChn_BindDpc = XenInterface.EvtChn_BindDpc;
   5.255 +  ChildDeviceData->XenInterface.AllocMMIO = xedd->XenInterface.AllocMMIO;
   5.256 +  ChildDeviceData->XenInterface.FreeMem = xedd->XenInterface.FreeMem;
   5.257  
   5.258 -  ChildDeviceData->XenInterface.GntTbl_GrantAccess = XenInterface.GntTbl_GrantAccess;
   5.259 -  ChildDeviceData->XenInterface.GntTbl_EndAccess = XenInterface.GntTbl_EndAccess;
   5.260 +  ChildDeviceData->XenInterface.EvtChn_Bind = xedd->XenInterface.EvtChn_Bind;
   5.261 +  ChildDeviceData->XenInterface.EvtChn_Unbind = xedd->XenInterface.EvtChn_Unbind;
   5.262 +  ChildDeviceData->XenInterface.EvtChn_Mask = xedd->XenInterface.EvtChn_Mask;
   5.263 +  ChildDeviceData->XenInterface.EvtChn_Unmask = xedd->XenInterface.EvtChn_Unmask;
   5.264 +  ChildDeviceData->XenInterface.EvtChn_Notify = xedd->XenInterface.EvtChn_Notify;
   5.265 +  ChildDeviceData->XenInterface.EvtChn_AllocUnbound = xedd->XenInterface.EvtChn_AllocUnbound;
   5.266 +  ChildDeviceData->XenInterface.EvtChn_BindDpc = xedd->XenInterface.EvtChn_BindDpc;
   5.267  
   5.268 -  ChildDeviceData->XenInterface.XenBus_Read = XenInterface.XenBus_Read;
   5.269 -  ChildDeviceData->XenInterface.XenBus_Write = XenInterface.XenBus_Write;
   5.270 -  ChildDeviceData->XenInterface.XenBus_Printf = XenInterface.XenBus_Printf;
   5.271 -  ChildDeviceData->XenInterface.XenBus_StartTransaction = XenInterface.XenBus_StartTransaction;
   5.272 -  ChildDeviceData->XenInterface.XenBus_EndTransaction = XenInterface.XenBus_EndTransaction;
   5.273 -  ChildDeviceData->XenInterface.XenBus_List = XenInterface.XenBus_List;
   5.274 -  ChildDeviceData->XenInterface.XenBus_AddWatch = XenInterface.XenBus_AddWatch;
   5.275 -  ChildDeviceData->XenInterface.XenBus_RemWatch = XenInterface.XenBus_RemWatch;
   5.276 +  ChildDeviceData->XenInterface.GntTbl_GrantAccess = xedd->XenInterface.GntTbl_GrantAccess;
   5.277 +  ChildDeviceData->XenInterface.GntTbl_EndAccess = xedd->XenInterface.GntTbl_EndAccess;
   5.278 +
   5.279 +  ChildDeviceData->XenInterface.XenBus_Read = xedd->XenInterface.XenBus_Read;
   5.280 +  ChildDeviceData->XenInterface.XenBus_Write = xedd->XenInterface.XenBus_Write;
   5.281 +  ChildDeviceData->XenInterface.XenBus_Printf = xedd->XenInterface.XenBus_Printf;
   5.282 +  ChildDeviceData->XenInterface.XenBus_StartTransaction = xedd->XenInterface.XenBus_StartTransaction;
   5.283 +  ChildDeviceData->XenInterface.XenBus_EndTransaction = xedd->XenInterface.XenBus_EndTransaction;
   5.284 +  ChildDeviceData->XenInterface.XenBus_List = xedd->XenInterface.XenBus_List;
   5.285 +  ChildDeviceData->XenInterface.XenBus_AddWatch = xedd->XenInterface.XenBus_AddWatch;
   5.286 +  ChildDeviceData->XenInterface.XenBus_RemWatch = xedd->XenInterface.XenBus_RemWatch;
   5.287  
   5.288    WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->XenInterface, &GUID_XEN_IFACE, NULL);
   5.289    status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
     6.1 --- a/xenpci/xenpci.c	Mon Feb 18 22:32:41 2008 +1100
     6.2 +++ b/xenpci/xenpci.c	Wed Feb 20 17:14:14 2008 +1100
     6.3 @@ -311,6 +311,7 @@ XenPCI_AddDevice(
     6.4      KdPrint((__DRIVER_NAME "     XenHide loaded and GPLPV specified\n", Status));
     6.5    }
     6.6  
     6.7 +  KeInitializeGuardedMutex(&xpdd->WatchHandlerMutex);
     6.8    busInfo.BusTypeGuid = GUID_XENPCI_DEVCLASS;
     6.9    busInfo.LegacyBusType = Internal;
    6.10    busInfo.BusNumber = 0;
    6.11 @@ -350,29 +351,9 @@ XenPCI_AddDevice(
    6.12    if (!NT_SUCCESS(Status))
    6.13    {
    6.14      KdPrint((__DRIVER_NAME "     WdfIoQueueCreate (ReadQueue) failed 0x%08x\n", Status));
    6.15 -    switch (Status)
    6.16 -    {
    6.17 -    case STATUS_INVALID_PARAMETER:
    6.18 -      KdPrint((__DRIVER_NAME "     STATUS_INVALID_PARAMETER\n"));
    6.19 -      break;
    6.20 -    case STATUS_INFO_LENGTH_MISMATCH:
    6.21 -      KdPrint((__DRIVER_NAME "     STATUS_INFO_LENGTH_MISMATCH\n"));
    6.22 -      break;
    6.23 -    case STATUS_POWER_STATE_INVALID:
    6.24 -      KdPrint((__DRIVER_NAME "     STATUS_POWER_STATE_INVALID\n"));
    6.25 -      break;
    6.26 -    case STATUS_INSUFFICIENT_RESOURCES:
    6.27 -      KdPrint((__DRIVER_NAME "     STATUS_INSUFFICIENT_RESOURCES\n"));
    6.28 -      break;
    6.29 -    case STATUS_WDF_NO_CALLBACK:
    6.30 -      KdPrint((__DRIVER_NAME "     STATUS_WDF_NO_CALLBACK\n"));
    6.31 -      break;
    6.32 -    case STATUS_UNSUCCESSFUL:
    6.33 -      KdPrint((__DRIVER_NAME "     STATUS_UNSUCCESSFUL\n"));
    6.34 -      break;
    6.35 -    }
    6.36      return Status;
    6.37    }
    6.38 +
    6.39    WdfIoQueueStopSynchronously(ReadQueue);
    6.40    WdfDeviceConfigureRequestDispatching(Device, ReadQueue, WdfRequestTypeRead);
    6.41  
    6.42 @@ -510,15 +491,14 @@ XenPCI_D0EntryPostInterruptsEnabled(WDFD
    6.43    char **Types;
    6.44    int i;
    6.45    char buffer[128];
    6.46 +  WDFCHILDLIST ChildList;
    6.47  
    6.48    UNREFERENCED_PARAMETER(PreviousState);
    6.49  
    6.50 -  KdPrint((__DRIVER_NAME " --> EvtDeviceD0EntryPostInterruptsEnabled\n"));
    6.51 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    6.52  
    6.53    XenBus_Start(Device);
    6.54  
    6.55 -  KdPrint((__DRIVER_NAME "     A\n"));
    6.56 -
    6.57    response = XenBus_AddWatch(Device, XBT_NIL, SYSRQ_PATH, XenBus_SysrqHandler, Device);
    6.58    KdPrint((__DRIVER_NAME "     sysrqwatch response = '%s'\n", response)); 
    6.59    
    6.60 @@ -531,20 +511,24 @@ XenPCI_D0EntryPostInterruptsEnabled(WDFD
    6.61    response = XenBus_AddWatch(Device, XBT_NIL, "device", XenPCI_XenBusWatchHandler, Device);
    6.62    KdPrint((__DRIVER_NAME "     device watch response = '%s'\n", response)); 
    6.63  
    6.64 +  ChildList = WdfFdoGetDefaultChildList(Device);
    6.65 +
    6.66 +  WdfChildListBeginScan(ChildList);
    6.67    msgTypes = XenBus_List(Device, XBT_NIL, "device", &Types);
    6.68    if (!msgTypes) {
    6.69      for (i = 0; Types[i]; i++)
    6.70      {
    6.71        RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/%s", Types[i]);
    6.72 -      //KdPrint((__DRIVER_NAME "     ls device[%d] -> %s\n", i, Types[i]));
    6.73        XenPCI_XenBusWatchHandler(buffer, Device);
    6.74        ExFreePoolWithTag(Types[i], XENPCI_POOL_TAG);
    6.75      }
    6.76    }
    6.77 -  KdPrint((__DRIVER_NAME " <-- EvtDeviceD0EntryPostInterruptsEnabled\n"));
    6.78 +  WdfChildListEndScan(ChildList);
    6.79  
    6.80    XenPCI_FreeMem(Types);
    6.81  
    6.82 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    6.83 +
    6.84    return status;
    6.85  }
    6.86  
    6.87 @@ -697,19 +681,24 @@ XenPCI_ChildListCreateDevice(
    6.88    DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
    6.89    WDF_QUERY_INTERFACE_CONFIG  qiConfig;
    6.90    PXENPCI_XEN_DEVICE_DATA ChildDeviceData = NULL;
    6.91 +  UNICODE_STRING DeviceType;
    6.92 +  ANSI_STRING AnsiBuf;
    6.93  
    6.94    UNREFERENCED_PARAMETER(ChildList);
    6.95  
    6.96 -  //KdPrint((__DRIVER_NAME " --> ChildListCreateDevice\n"));
    6.97 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    6.98  
    6.99    XenIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENPCI_IDENTIFICATION_DESCRIPTION, Header);
   6.100  
   6.101 -  //KdPrint((__DRIVER_NAME "     Type = %wZ\n", &XenIdentificationDesc->DeviceType));
   6.102 +  RtlInitAnsiString(&AnsiBuf, XenIdentificationDesc->DeviceType);
   6.103 +  RtlAnsiStringToUnicodeString(&DeviceType, &AnsiBuf, TRUE);
   6.104 +
   6.105 +  KdPrint((__DRIVER_NAME "     Type = %s\n", XenIdentificationDesc->DeviceType));
   6.106  
   6.107    //DeviceInit = WdfPdoInitAllocate(Device);
   6.108    WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_CONTROLLER);
   6.109  
   6.110 -  status = RtlUnicodeStringPrintf(&buffer, L"Xen\\%wZ\0", &XenIdentificationDesc->DeviceType);
   6.111 +  status = RtlUnicodeStringPrintf(&buffer, L"Xen\\%wZ\0", &DeviceType);
   6.112    status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
   6.113    status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
   6.114    status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
   6.115 @@ -717,7 +706,7 @@ XenPCI_ChildListCreateDevice(
   6.116    status = RtlUnicodeStringPrintf(&buffer, L"%02d", 0);
   6.117    status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
   6.118  
   6.119 -  status = RtlUnicodeStringPrintf( &buffer, L"%wZ", &XenIdentificationDesc->DeviceType);
   6.120 +  status = RtlUnicodeStringPrintf(&buffer, L"%wZ", &DeviceType);
   6.121    status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
   6.122  
   6.123    WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
   6.124 @@ -782,7 +771,7 @@ XenPCI_ChildListCreateDevice(
   6.125      return status;
   6.126    }
   6.127  
   6.128 -  //KdPrint((__DRIVER_NAME " <-- ChildListCreateDevice\n"));
   6.129 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   6.130  
   6.131    return status;
   6.132  }
   6.133 @@ -790,7 +779,6 @@ XenPCI_ChildListCreateDevice(
   6.134  VOID
   6.135  XenPCI_XenBusWatchHandler(char *Path, PVOID Data)
   6.136  {
   6.137 -  XENPCI_IDENTIFICATION_DESCRIPTION description;
   6.138    NTSTATUS status;
   6.139    char **Bits;
   6.140    int Count;
   6.141 @@ -799,64 +787,55 @@ XenPCI_XenBusWatchHandler(char *Path, PV
   6.142    WDF_CHILD_LIST_ITERATOR ChildIterator;
   6.143    WDFDEVICE ChildDevice;
   6.144    PXENPCI_XEN_DEVICE_DATA ChildDeviceData;
   6.145 -  
   6.146 -  ANSI_STRING AnsiBuf;
   6.147 +  XENPCI_IDENTIFICATION_DESCRIPTION description;
   6.148 +  PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
   6.149  
   6.150 -  UNREFERENCED_PARAMETER(Data);
   6.151 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   6.152  
   6.153 -  KdPrint((__DRIVER_NAME " --> XenBusWatchHandler\n"));
   6.154 +  KeAcquireGuardedMutex(&xpdd->WatchHandlerMutex);
   6.155  
   6.156 -  //KdPrint((__DRIVER_NAME "     %s\n", Path));
   6.157 +  KdPrint((__DRIVER_NAME "     Path = %s\n", Path));
   6.158  
   6.159    ChildList = WdfFdoGetDefaultChildList(Device);
   6.160  
   6.161    Bits = SplitString(Path, '/', 3, &Count);
   6.162 -  switch (Count)
   6.163 +
   6.164 +  KdPrint((__DRIVER_NAME "     Count = %s\n", Count));
   6.165 +
   6.166 +  ChildDeviceData = NULL;
   6.167 +  WDF_CHILD_LIST_ITERATOR_INIT(&ChildIterator, WdfRetrievePresentChildren);
   6.168 +  WdfChildListBeginIteration(ChildList, &ChildIterator);
   6.169 +  while (NT_SUCCESS(WdfChildListRetrieveNextDevice(ChildList, &ChildIterator, &ChildDevice, NULL)))
   6.170    {
   6.171 -    case 0:
   6.172 -    case 1:
   6.173 -      break;
   6.174 -    case 2:
   6.175 -      // add or update the device node
   6.176 -      WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&description.Header, sizeof(description));
   6.177 -      strncpy(description.Path, Path, 128);
   6.178 -      RtlInitAnsiString(&AnsiBuf, Bits[1]);
   6.179 -      //KdPrint((__DRIVER_NAME "     Name = %s\n", Bits[1]));  
   6.180 -      RtlAnsiStringToUnicodeString(&description.DeviceType, &AnsiBuf, TRUE);
   6.181 -      status = WdfChildListAddOrUpdateChildDescriptionAsPresent(ChildList, &description.Header, NULL);
   6.182 +    ChildDeviceData = GetXenDeviceData(ChildDevice);
   6.183 +    if (!ChildDeviceData)
   6.184 +    {
   6.185 +      KdPrint(("     No child device data, should never happen\n"));
   6.186 +      continue;
   6.187 +    }
   6.188 +    if (strncmp(ChildDeviceData->Path, Path, strlen(ChildDeviceData->Path)) == 0 && Path[strlen(ChildDeviceData->Path)] == '/')
   6.189 +    {
   6.190 +      if (Count == 3 && ChildDeviceData->WatchHandler != NULL)
   6.191 +        ChildDeviceData->WatchHandler(Path, ChildDeviceData->WatchContext);
   6.192        break;
   6.193 -    case 3:
   6.194 -      WDF_CHILD_LIST_ITERATOR_INIT(&ChildIterator, WdfRetrievePresentChildren);
   6.195 -      WdfChildListBeginIteration(ChildList, &ChildIterator);
   6.196 -      while (NT_SUCCESS(WdfChildListRetrieveNextDevice(ChildList, &ChildIterator, &ChildDevice, NULL)))
   6.197 -      {
   6.198 -        ChildDeviceData = GetXenDeviceData(ChildDevice);
   6.199 -        if (!ChildDeviceData)
   6.200 -        {
   6.201 -          KdPrint((__FUNCTION__ " No child device data, should never happen\n"));
   6.202 -          continue;
   6.203 -        }
   6.204 -        if (strncmp(ChildDeviceData->Path, Path, strlen(ChildDeviceData->Path)) == 0 && Path[strlen(ChildDeviceData->Path)] == '/')
   6.205 -        {
   6.206 -          //KdPrint((__DRIVER_NAME "     Child Path = %s (Match - WatchHandler = %08x)\n", ChildDeviceData->Path, ChildDeviceData->WatchHandler));
   6.207 -          if (ChildDeviceData->WatchHandler != NULL)
   6.208 -            ChildDeviceData->WatchHandler(Path, ChildDeviceData->WatchContext);
   6.209 -        }
   6.210 -        else
   6.211 -        {
   6.212 -          //KdPrint((__DRIVER_NAME "     Child Path = %s (No Match)\n", ChildDeviceData->Path));
   6.213 -        }
   6.214 -      }
   6.215 -      WdfChildListEndIteration(ChildList, &ChildIterator);
   6.216 -      break;
   6.217 -    default:
   6.218 -      KdPrint((__FUNCTION__ ": Unknown case %d\n", Count));
   6.219 -      break;
   6.220 +    }
   6.221 +    ChildDeviceData = NULL;
   6.222    }
   6.223 -
   6.224 +  WdfChildListEndIteration(ChildList, &ChildIterator);
   6.225 +  if (Count >= 2 && ChildDeviceData == NULL)
   6.226 +  {
   6.227 +    RtlZeroMemory(&description, sizeof(description));
   6.228 +    WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&description.Header, sizeof(description));
   6.229 +    strncpy(description.Path, Path, 128);
   6.230 +    strncpy(description.DeviceType, Bits[1], 128);
   6.231 +    KdPrint((__DRIVER_NAME "     Adding child for %s\n", description.DeviceType));
   6.232 +    status = WdfChildListAddOrUpdateChildDescriptionAsPresent(ChildList, &description.Header, NULL);
   6.233 +  }
   6.234    FreeSplitString(Bits, Count);
   6.235 +
   6.236 +  KeReleaseGuardedMutex(&xpdd->WatchHandlerMutex);
   6.237    
   6.238 -  KdPrint((__DRIVER_NAME " <-- XenBusWatchHandler\n"));
   6.239 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   6.240  }
   6.241  
   6.242  static void
   6.243 @@ -1019,139 +998,6 @@ XenBus_SysrqHandler(char *Path, PVOID Da
   6.244    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   6.245  }
   6.246  
   6.247 -/*
   6.248 -IO_RESOURCE_DESCRIPTOR MemoryDescriptor;
   6.249 -
   6.250 -static NTSTATUS
   6.251 -XenPCI_FilterRemoveResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList)
   6.252 -{
   6.253 -  NTSTATUS status;
   6.254 -  WDFIORESLIST ResourceList;
   6.255 -  PIO_RESOURCE_DESCRIPTOR Descriptor;
   6.256 -
   6.257 -  int i, j;
   6.258 -  int offset;
   6.259 -
   6.260 -  //KdPrint((__DRIVER_NAME " --> FilterRemoveResourceRequirements\n"));
   6.261 -
   6.262 -  for (i = 0; i < WdfIoResourceRequirementsListGetCount(RequirementsList); i++)
   6.263 -  {
   6.264 -    ResourceList = WdfIoResourceRequirementsListGetIoResList(RequirementsList, i);
   6.265 -    //KdPrint((__DRIVER_NAME "     Resource List %d\n", i));
   6.266 -    //KdPrint((__DRIVER_NAME "     %d resources in list\n", WdfIoResourceListGetCount(ResourceList)));
   6.267 -    offset = 0;
   6.268 -    for (j = 0; j < WdfIoResourceListGetCount(ResourceList); j++)
   6.269 -    {
   6.270 -      //KdPrint((__DRIVER_NAME "       Resource %d\n", j));
   6.271 -      Descriptor = WdfIoResourceListGetDescriptor(ResourceList, j - offset);
   6.272 -
   6.273 -      switch (Descriptor->Type) {
   6.274 -      case CmResourceTypePort:
   6.275 -        //KdPrint((__DRIVER_NAME "         Port\n"));
   6.276 -        break;
   6.277 -      case CmResourceTypeMemory:
   6.278 -        //KdPrint((__DRIVER_NAME "         Memory %08X%08X - %08X%08X\n", Descriptor->u.Memory.MinimumAddress.HighPart, Descriptor->u.Memory.MinimumAddress.LowPart, Descriptor->u.Memory.MaximumAddress.HighPart, Descriptor->u.Memory.MaximumAddress.LowPart));
   6.279 -        //KdPrint((__DRIVER_NAME "         Length %08X\n", Descriptor->u.Memory.Length));
   6.280 -        //KdPrint((__DRIVER_NAME "         ShareDisposition %02X\n", Descriptor->ShareDisposition));
   6.281 -        //KdPrint((__DRIVER_NAME "         Option %02X\n", Descriptor->Option));
   6.282 -        if (!Descriptor->Option || Descriptor->Option == IO_RESOURCE_PREFERRED) {
   6.283 -          memcpy(&MemoryDescriptor, Descriptor, sizeof(IO_RESOURCE_DESCRIPTOR));
   6.284 -          //platform_mmio_orig_len = MemoryDescriptor.u.Memory.Length;
   6.285 -          //MemoryDescriptor.u.Memory.Length = PAGE_SIZE;
   6.286 -          MemoryDescriptor.ShareDisposition = CmResourceShareShared;
   6.287 -        }
   6.288 -        WdfIoResourceListRemove(ResourceList, j - offset);
   6.289 -        offset++;
   6.290 -        break;
   6.291 -      case CmResourceTypeInterrupt:
   6.292 -        //KdPrint((__DRIVER_NAME "         Interrupt\n"));
   6.293 -        break;
   6.294 -      case CmResourceTypeDevicePrivate:
   6.295 -        //KdPrint((__DRIVER_NAME "         Private\n"));
   6.296 -        break;
   6.297 -      default:
   6.298 -        //KdPrint((__DRIVER_NAME "         Unknown Type (0x%x)\n", Descriptor->Type));
   6.299 -        break;
   6.300 -      }
   6.301 -    }
   6.302 -  }
   6.303 -  status = STATUS_SUCCESS;
   6.304 -
   6.305 -  KdPrint((__DRIVER_NAME " <-- FilterRemoveResourceRequirements\n"));
   6.306 -
   6.307 -  return status;
   6.308 -}
   6.309 -
   6.310 -
   6.311 -static NTSTATUS
   6.312 -XenPCI_FilterAddResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList)
   6.313 -{
   6.314 -  NTSTATUS status;
   6.315 -  WDFIORESLIST ResourceList;
   6.316 -  PIO_RESOURCE_DESCRIPTOR Descriptor;
   6.317 -
   6.318 -  int i, j;
   6.319 -
   6.320 -  KdPrint((__DRIVER_NAME " --> FilterAddResourceRequirements\n"));
   6.321 -
   6.322 -
   6.323 -  for (i = 0; i < WdfIoResourceRequirementsListGetCount(RequirementsList); i++)
   6.324 -  {
   6.325 -    ResourceList = WdfIoResourceRequirementsListGetIoResList(RequirementsList, i);
   6.326 -    //KdPrint((__DRIVER_NAME "     Resource List %d\n", i));
   6.327 -    //KdPrint((__DRIVER_NAME "     %d resources in list\n", WdfIoResourceListGetCount(ResourceList)));
   6.328 -    WdfIoResourceListAppendDescriptor(ResourceList, &MemoryDescriptor);
   6.329 -    //KdPrint((__DRIVER_NAME "         Memory %08X%08X - %08X%08X\n", MemoryDescriptor.u.Memory.MinimumAddress.HighPart, MemoryDescriptor.u.Memory.MinimumAddress.LowPart, MemoryDescriptor.u.Memory.MaximumAddress.HighPart, MemoryDescriptor.u.Memory.MaximumAddress.LowPart));
   6.330 -    //KdPrint((__DRIVER_NAME "         Length %08X\n", MemoryDescriptor.u.Memory.Length));
   6.331 -    for (j = 0; j < WdfIoResourceListGetCount(ResourceList); j++)
   6.332 -    {
   6.333 -      //KdPrint((__DRIVER_NAME "       Resource %d\n", j));
   6.334 -      Descriptor = WdfIoResourceListGetDescriptor(ResourceList, j);
   6.335 -
   6.336 -      switch (Descriptor->Type) {
   6.337 -      case CmResourceTypePort:
   6.338 -        //KdPrint((__DRIVER_NAME "         Port\n"));
   6.339 -        break;
   6.340 -      case CmResourceTypeMemory:
   6.341 -        //KdPrint((__DRIVER_NAME "         Memory %08X%08X - %08X%08X\n", Descriptor->u.Memory.MinimumAddress.HighPart, Descriptor->u.Memory.MinimumAddress.LowPart, Descriptor->u.Memory.MaximumAddress.HighPart, Descriptor->u.Memory.MaximumAddress.LowPart));
   6.342 -        //KdPrint((__DRIVER_NAME "         Length %08X\n", Descriptor->u.Memory.Length));
   6.343 -        //KdPrint((__DRIVER_NAME "         ShareDisposition %02X\n", Descriptor->ShareDisposition));
   6.344 -        //Descriptor->ShareDisposition = CmResourceShareShared;
   6.345 -        //memcpy(&MemoryDescriptor, Descriptor, sizeof(IO_RESOURCE_DESCRIPTOR));
   6.346 -        //platform_mmio_orig_len = MemoryDescriptor.u.Memory.Length;
   6.347 -        //MemoryDescriptor.u.Memory.Length = PAGE_SIZE;
   6.348 -        //WdfIoResourceListRemove(ResourceList, j);
   6.349 -        break;
   6.350 -      case CmResourceTypeInterrupt:
   6.351 -        //KdPrint((__DRIVER_NAME "         Interrupt\n"));
   6.352 -        break;
   6.353 -      case CmResourceTypeDevicePrivate:
   6.354 -        //KdPrint((__DRIVER_NAME "         Private\n"));
   6.355 -        break;
   6.356 -      default:
   6.357 -        //KdPrint((__DRIVER_NAME "         Unknown Type (0x%x)\n", Descriptor->Type));
   6.358 -        break;
   6.359 -      }
   6.360 -    }
   6.361 -  }
   6.362 -  status = STATUS_SUCCESS;
   6.363 -
   6.364 -  //KdPrint((__DRIVER_NAME " <-- FilterAddResourceRequirements\n"));
   6.365 -
   6.366 -  return status;
   6.367 -}
   6.368 -
   6.369 -static NTSTATUS
   6.370 -XenPCI_RemoveAddedResources(WDFDEVICE Device, WDFCMRESLIST ResourcesRaw, WDFCMRESLIST ResourcesTranslated)
   6.371 -{
   6.372 -  //KdPrint((__DRIVER_NAME " --> RemoveAddedResources\n"));
   6.373 -  //KdPrint((__DRIVER_NAME " <-- RemoveAddedResources\n"));
   6.374 -
   6.375 -  return STATUS_SUCCESS;
   6.376 -}
   6.377 -
   6.378 -*/
   6.379 -
   6.380  static NTSTATUS
   6.381  XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList)
   6.382  {
   6.383 @@ -1166,23 +1012,6 @@ XenPCI_DeviceResourceRequirementsQuery(W
   6.384    if (!NT_SUCCESS(status))
   6.385      return status;
   6.386  
   6.387 -/*
   6.388 -  RtlZeroMemory(&descriptor, sizeof(descriptor));
   6.389 -
   6.390 -  descriptor.Option = 0;
   6.391 -  descriptor.Type = CmResourceTypeInterrupt;
   6.392 -  descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
   6.393 -  descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
   6.394 -  descriptor.u.Interrupt.MinimumVector = 1024;
   6.395 -  descriptor.u.Interrupt.MaximumVector = 1024+255;
   6.396 -
   6.397 -  //KdPrint((__DRIVER_NAME "     MinimumVector = %d, MaximumVector = %d\n", descriptor.u.Interrupt.MinimumVector, descriptor.u.Interrupt.MaximumVector));
   6.398 -
   6.399 -  status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
   6.400 -  if (!NT_SUCCESS(status))
   6.401 -    return status;
   6.402 -*/
   6.403 -
   6.404    RtlZeroMemory(&descriptor, sizeof(descriptor));
   6.405  
   6.406    descriptor.Option = 0;
     7.1 --- a/xenpci/xenpci.h	Mon Feb 18 22:32:41 2008 +1100
     7.2 +++ b/xenpci/xenpci.h	Wed Feb 20 17:14:14 2008 +1100
     7.3 @@ -142,6 +142,8 @@ typedef struct {
     7.4  
     7.5    KSPIN_LOCK WatchLock;
     7.6    KSPIN_LOCK grant_lock;
     7.7 +
     7.8 +  KGUARDED_MUTEX WatchHandlerMutex;
     7.9  } XENPCI_DEVICE_DATA, *PXENPCI_DEVICE_DATA;
    7.10  
    7.11  WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_DATA, GetDeviceData);
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/xenscsi/makefile	Wed Feb 20 17:14:14 2008 +1100
     8.3 @@ -0,0 +1,1 @@
     8.4 +!INCLUDE $(NTMAKEENV)\makefile.def
     8.5 \ No newline at end of file
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/xenscsi/makefile.inc	Wed Feb 20 17:14:14 2008 +1100
     9.3 @@ -0,0 +1,6 @@
     9.4 +_LNG=$(LANGUAGE)
     9.5 +STAMP=stampinf -f $@ -a $(_BUILDARCH) -d * -k $(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR) -v $(VERSION)
     9.6 +
     9.7 +..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf: $(INF_NAME).inx sources ..\common.inc
     9.8 +    copy $(@B).inx $@
     9.9 +    $(STAMP)
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/xenscsi/sources	Wed Feb 20 17:14:14 2008 +1100
    10.3 @@ -0,0 +1,7 @@
    10.4 +!include "..\common.inc"
    10.5 +TARGETNAME=xenscsi
    10.6 +TARGETTYPE=DRIVER
    10.7 +INF_NAME=$(TARGETNAME)
    10.8 +TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\scsiport.lib
    10.9 +MISCFILES=..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf
   10.10 +SOURCES=xenscsi.c
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/xenscsi/xenscsi.c	Wed Feb 20 17:14:14 2008 +1100
    11.3 @@ -0,0 +1,857 @@
    11.4 +#include "xenscsi.h"
    11.5 +#include <scsi.h>
    11.6 +#include <ntddscsi.h>
    11.7 +#include <ntdddisk.h>
    11.8 +#include <stdlib.h>
    11.9 +#include <xen_public.h>
   11.10 +#include <io/xenbus.h>
   11.11 +#include <io/protocols.h>
   11.12 +
   11.13 +#pragma warning(disable: 4127)
   11.14 +
   11.15 +#define wmb() KeMemoryBarrier()
   11.16 +#define mb() KeMemoryBarrier()
   11.17 +
   11.18 +DRIVER_INITIALIZE DriverEntry;
   11.19 +
   11.20 +static ULONG
   11.21 +XenScsi_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again);
   11.22 +static BOOLEAN
   11.23 +XenScsi_HwScsiInitialize(PVOID DeviceExtension);
   11.24 +static BOOLEAN
   11.25 +XenScsi_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb);
   11.26 +static BOOLEAN
   11.27 +XenScsi_HwScsiInterrupt(PVOID DeviceExtension);
   11.28 +static BOOLEAN
   11.29 +XenScsi_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId);
   11.30 +static BOOLEAN
   11.31 +XenScsi_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState);
   11.32 +static SCSI_ADAPTER_CONTROL_STATUS
   11.33 +XenScsi_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters);
   11.34 +
   11.35 +#ifdef ALLOC_PRAGMA
   11.36 +#pragma alloc_text (INIT, DriverEntry)
   11.37 +#endif
   11.38 +
   11.39 +NTSTATUS
   11.40 +DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
   11.41 +{
   11.42 +  ULONG Status;
   11.43 +  HW_INITIALIZATION_DATA HwInitializationData;
   11.44 +
   11.45 +  KdPrint((__DRIVER_NAME " --> "__FUNCTION__ "\n"));
   11.46 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   11.47 +
   11.48 +  RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
   11.49 +
   11.50 +  HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
   11.51 +  HwInitializationData.AdapterInterfaceType = Internal; //PNPBus;
   11.52 +  HwInitializationData.HwInitialize = XenScsi_HwScsiInitialize;
   11.53 +  HwInitializationData.HwStartIo = XenScsi_HwScsiStartIo;
   11.54 +  HwInitializationData.HwInterrupt = XenScsi_HwScsiInterrupt;
   11.55 +  HwInitializationData.HwFindAdapter = XenScsi_HwScsiFindAdapter;
   11.56 +  HwInitializationData.HwResetBus = XenScsi_HwScsiResetBus;
   11.57 +  HwInitializationData.HwDmaStarted = NULL;
   11.58 +  HwInitializationData.HwAdapterState = XenScsi_HwScsiAdapterState;
   11.59 +  HwInitializationData.DeviceExtensionSize = sizeof(XENSCSI_DEVICE_DATA);
   11.60 +  HwInitializationData.SpecificLuExtensionSize = 0;
   11.61 +  HwInitializationData.SrbExtensionSize = 0;
   11.62 +  HwInitializationData.NumberOfAccessRanges = 1;
   11.63 +  HwInitializationData.MapBuffers = TRUE;
   11.64 +  HwInitializationData.NeedPhysicalAddresses = FALSE;
   11.65 +  HwInitializationData.TaggedQueuing = TRUE;
   11.66 +  HwInitializationData.AutoRequestSense = FALSE;
   11.67 +  HwInitializationData.MultipleRequestPerLu = TRUE;
   11.68 +  HwInitializationData.ReceiveEvent = FALSE;
   11.69 +  HwInitializationData.VendorIdLength = 0;
   11.70 +  HwInitializationData.VendorId = NULL;
   11.71 +  HwInitializationData.DeviceIdLength = 0;
   11.72 +  HwInitializationData.DeviceId = NULL;
   11.73 +  HwInitializationData.HwAdapterControl = XenScsi_HwScsiAdapterControl;
   11.74 +
   11.75 +  Status = ScsiPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
   11.76 +
   11.77 +  if(!NT_SUCCESS(Status))
   11.78 +  {
   11.79 +    KdPrint((__DRIVER_NAME " ScsiPortInitialize failed with status 0x%08x\n", Status));
   11.80 +  }
   11.81 +
   11.82 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   11.83 +
   11.84 +  return Status;
   11.85 +}
   11.86 +
   11.87 +static __inline uint16_t
   11.88 +GET_ID_FROM_FREELIST(PXENSCSI_TARGET_DATA TargetData)
   11.89 +{
   11.90 +  uint16_t free;
   11.91 +  free = TargetData->shadow_free;
   11.92 +  TargetData->shadow_free = TargetData->shadow[free].req.rqid;
   11.93 +  TargetData->shadow[free].req.rqid = 0x0fff; /* debug */
   11.94 +  return free;
   11.95 +}
   11.96 +
   11.97 +static __inline VOID
   11.98 +ADD_ID_TO_FREELIST(PXENSCSI_TARGET_DATA TargetData, uint16_t Id)
   11.99 +{
  11.100 +  TargetData->shadow[Id].req.rqid  = TargetData->shadow_free;
  11.101 +  TargetData->shadow[Id].Srb = NULL;
  11.102 +  TargetData->shadow_free = Id;
  11.103 +}
  11.104 +
  11.105 +static BOOLEAN
  11.106 +XenScsi_Interrupt(PKINTERRUPT Interrupt, PVOID DeviceExtension)
  11.107 +{
  11.108 +  PXENSCSI_TARGET_DATA TargetData = (PXENSCSI_TARGET_DATA)DeviceExtension;
  11.109 +
  11.110 +  UNREFERENCED_PARAMETER(Interrupt);
  11.111 +
  11.112 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  11.113 +
  11.114 +  TargetData->PendingInterrupt = TRUE;
  11.115 +
  11.116 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  11.117 +
  11.118 +  return TRUE;
  11.119 +}
  11.120 +
  11.121 +static VOID
  11.122 +XenScsi_HwScsiInterruptTarget(PVOID DeviceExtension)
  11.123 +{
  11.124 +  PXENSCSI_TARGET_DATA TargetData = (PXENSCSI_TARGET_DATA)DeviceExtension;
  11.125 +  PSCSI_REQUEST_BLOCK Srb;
  11.126 +  RING_IDX i, rp;
  11.127 +  vscsiif_response_t *rep;
  11.128 +  PXENSCSI_DEVICE_DATA DeviceData = (PXENSCSI_DEVICE_DATA)TargetData->DeviceData;
  11.129 +  int more_to_do = TRUE;
  11.130 +
  11.131 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  11.132 +
  11.133 +  while (more_to_do)
  11.134 +  {
  11.135 +    rp = TargetData->Ring.sring->rsp_prod;
  11.136 +    KeMemoryBarrier();
  11.137 +    for (i = TargetData->Ring.rsp_cons; i != rp; i++)
  11.138 +    {
  11.139 +      rep = RING_GET_RESPONSE(&TargetData->Ring, i);
  11.140 +      Srb = TargetData->shadow[rep->rqid].Srb;
  11.141 +      if (!rep->rslt)
  11.142 +        Srb->SrbStatus = SRB_STATUS_SUCCESS;
  11.143 +      else
  11.144 +      {
  11.145 +// copy sense info here
  11.146 +        KdPrint((__DRIVER_NAME "     Xen Operation returned error\n"));
  11.147 +        Srb->SrbStatus = SRB_STATUS_ERROR;
  11.148 +      }
  11.149 +      if (Srb->SrbFlags & SRB_FLAGS_DATA_IN)
  11.150 +        memcpy(Srb->DataBuffer, TargetData->shadow[rep->rqid].Buf, Srb->DataTransferLength);
  11.151 +
  11.152 +      ScsiPortNotification(RequestComplete, DeviceData, Srb);
  11.153 +      ScsiPortNotification(NextLuRequest, DeviceData, Srb->PathId, Srb->TargetId, Srb->Lun);
  11.154 +
  11.155 +      ADD_ID_TO_FREELIST(TargetData, rep->rqid);
  11.156 +    }
  11.157 +
  11.158 +    TargetData->Ring.rsp_cons = i;
  11.159 +    if (i != TargetData->Ring.req_prod_pvt)
  11.160 +    {
  11.161 +      RING_FINAL_CHECK_FOR_RESPONSES(&TargetData->Ring, more_to_do);
  11.162 +    }
  11.163 +    else
  11.164 +    {
  11.165 +      TargetData->Ring.sring->rsp_event = i + 1;
  11.166 +      more_to_do = FALSE;
  11.167 +    }
  11.168 +  }
  11.169 +
  11.170 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  11.171 +}
  11.172 +
  11.173 +static BOOLEAN
  11.174 +XenScsi_HwScsiInterrupt(PVOID DeviceExtension)
  11.175 +{
  11.176 +  PXENSCSI_DEVICE_DATA DeviceData;
  11.177 +  PXENSCSI_TARGET_DATA TargetData;
  11.178 +  int i, j;
  11.179 +
  11.180 +  //KdPrint((__DRIVER_NAME " --> HwScsiInterrupt\n"));
  11.181 +
  11.182 +  DeviceData = (PXENSCSI_DEVICE_DATA)DeviceExtension;
  11.183 +
  11.184 +  KeMemoryBarrier();
  11.185 +  for (i = 0; i < SCSI_BUSES; i++)
  11.186 +  {
  11.187 +    for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
  11.188 +    {
  11.189 +      TargetData = &DeviceData->BusData[i].TargetData[j];
  11.190 +      if (TargetData->PendingInterrupt)
  11.191 +        XenScsi_HwScsiInterruptTarget(TargetData);
  11.192 +      TargetData->PendingInterrupt = FALSE;
  11.193 +    }
  11.194 +  }
  11.195 +  //KdPrint((__DRIVER_NAME " <-- HwScsiInterrupt\n"));
  11.196 +
  11.197 +  return FALSE;
  11.198 +}
  11.199 +
  11.200 +static VOID
  11.201 +XenScsi_BackEndStateHandler(char *Path, PVOID Data)
  11.202 +{
  11.203 +  PXENSCSI_TARGET_DATA TargetData;
  11.204 +  PXENSCSI_DEVICE_DATA DeviceData;
  11.205 +  char TmpPath[128];
  11.206 +  char *Value;
  11.207 +  int NewState;
  11.208 +  int scanning;
  11.209 +  PMDL Mdl;
  11.210 +  grant_ref_t ref;
  11.211 +  vscsiif_sring_t *SharedRing;
  11.212 +  ULONG PFN;
  11.213 +  ULONG i, j;
  11.214 +
  11.215 +  KdPrint((__DRIVER_NAME " --> BackEndStateHandler\n"));
  11.216 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  11.217 +
  11.218 +  TargetData = (PXENSCSI_TARGET_DATA)Data;
  11.219 +  DeviceData = (PXENSCSI_DEVICE_DATA)TargetData->DeviceData;
  11.220 +
  11.221 +  DeviceData->XenDeviceData->XenInterface.XenBus_Read(
  11.222 +    DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  11.223 +    XBT_NIL, Path, &Value);
  11.224 +
  11.225 +  NewState = atoi(Value);
  11.226 +  switch (NewState)
  11.227 +  {
  11.228 +  case XenbusStateUnknown:
  11.229 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Unknown\n"));  
  11.230 +    break;
  11.231 +
  11.232 +  case XenbusStateInitialising:
  11.233 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialising\n"));  
  11.234 +    break;
  11.235 +
  11.236 +  case XenbusStateInitWait:
  11.237 +    KdPrint((__DRIVER_NAME "     Backend State Changed to InitWait\n"));  
  11.238 +
  11.239 +    TargetData->EventChannel = DeviceData->XenDeviceData->XenInterface.EvtChn_AllocUnbound(
  11.240 +      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, 0);
  11.241 +    DeviceData->XenDeviceData->XenInterface.EvtChn_Bind(
  11.242 +      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  11.243 +      TargetData->EventChannel, XenScsi_Interrupt, TargetData);
  11.244 +    Mdl = AllocatePage();
  11.245 +    PFN = (ULONG)*MmGetMdlPfnArray(Mdl);
  11.246 +    SharedRing = (vscsiif_sring_t *)MmGetMdlVirtualAddress(Mdl);
  11.247 +    RtlZeroMemory(SharedRing, PAGE_SIZE);
  11.248 +    SHARED_RING_INIT(SharedRing);
  11.249 +    FRONT_RING_INIT(&TargetData->Ring, SharedRing, PAGE_SIZE);
  11.250 +    ref = DeviceData->XenDeviceData->XenInterface.GntTbl_GrantAccess(
  11.251 +      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  11.252 +      0, PFN, FALSE);
  11.253 +    ASSERT((signed short)ref >= 0);
  11.254 +    TargetData->ring_detect_state = 0;
  11.255 +    TargetData->shadow = ExAllocatePoolWithTag(NonPagedPool, sizeof(vscsiif_shadow_t) * VSCSIIF_RING_SIZE, XENSCSI_POOL_TAG);
  11.256 +
  11.257 +    memset(TargetData->shadow, 0, sizeof(vscsiif_shadow_t) * VSCSIIF_RING_SIZE);
  11.258 +    for (i = 0; i < VSCSIIF_RING_SIZE; i++)
  11.259 +    {
  11.260 +      TargetData->shadow[i].req.rqid = (uint16_t)i + 1;
  11.261 +      TargetData->shadow[i].Mdl = AllocatePages(VSCSIIF_SG_TABLESIZE); // stupid that we have to do this!
  11.262 +      TargetData->shadow[i].Buf = MmGetMdlVirtualAddress(TargetData->shadow[i].Mdl);
  11.263 +      for (j = 0; j < VSCSIIF_SG_TABLESIZE; j++)
  11.264 +      {
  11.265 +        TargetData->shadow[i].req.seg[j].gref = DeviceData->XenDeviceData->XenInterface.GntTbl_GrantAccess(
  11.266 +          DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  11.267 +          0, (ULONG)MmGetMdlPfnArray(TargetData->shadow[i].Mdl)[j], FALSE);
  11.268 +        ASSERT((signed short)TargetData->shadow[i].req.seg[j].gref >= 0);
  11.269 +      }
  11.270 +    }
  11.271 +    TargetData->shadow_free = 0;
  11.272 +
  11.273 +    RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  11.274 +    RtlStringCbCatA(TmpPath, 128, "/ring-ref");
  11.275 +    DeviceData->XenDeviceData->XenInterface.XenBus_Printf(
  11.276 +      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  11.277 +      XBT_NIL, TmpPath, "%d", ref);
  11.278 +
  11.279 +    RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  11.280 +    RtlStringCbCatA(TmpPath, 128, "/event-channel");
  11.281 +    DeviceData->XenDeviceData->XenInterface.XenBus_Printf(
  11.282 +      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  11.283 +      XBT_NIL, TmpPath, "%d", TargetData->EventChannel);
  11.284 +
  11.285 +    RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  11.286 +    RtlStringCbCatA(TmpPath, 128, "/state");
  11.287 +    DeviceData->XenDeviceData->XenInterface.XenBus_Printf(
  11.288 +      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, 
  11.289 +      XBT_NIL, TmpPath, "%d", XenbusStateInitialised);
  11.290 +
  11.291 +    RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  11.292 +    RtlStringCbCatA(TmpPath, 128, "/b-dev");
  11.293 +    DeviceData->XenDeviceData->XenInterface.XenBus_Read(
  11.294 +      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  11.295 +      XBT_NIL, TmpPath, &Value);
  11.296 +
  11.297 +    KdPrint((__DRIVER_NAME "     dev string = %s\n", Value));  
  11.298 +    
  11.299 +    i = 0;
  11.300 +    j = 0;
  11.301 +    scanning = TRUE;
  11.302 +    while (scanning)
  11.303 +    {
  11.304 +      if (Value[i] == 0)
  11.305 +        scanning = FALSE;
  11.306 +      if (Value[i] == ':' || Value[i] == 0)
  11.307 +      {
  11.308 +         Value[i] = 0;
  11.309 +         TargetData->host = TargetData->channel;
  11.310 +         TargetData->channel = TargetData->id;
  11.311 +         TargetData->id = TargetData->lun;
  11.312 +         TargetData->lun = atoi(&Value[j]);
  11.313 +         j = i + 1;
  11.314 +      }
  11.315 +      i++;
  11.316 +    }
  11.317 +    KdPrint((__DRIVER_NAME "     host = %d, channel = %d, id = %d, lun = %d\n",
  11.318 +      TargetData->host, TargetData->channel, TargetData->id, TargetData->lun));  
  11.319 +
  11.320 +/*
  11.321 +    KdPrint((__DRIVER_NAME "     sizeof(vscsiif_request) = %d\n", sizeof(struct vscsiif_request)));
  11.322 +    KdPrint((__DRIVER_NAME "     sizeof(vscsiif_request_segment) = %d\n", sizeof(struct vscsiif_request_segment)));
  11.323 +    KdPrint((__DRIVER_NAME "     sizeof(vscsiif_response) = %d\n", sizeof(struct vscsiif_response)));
  11.324 +    KdPrint((__DRIVER_NAME "     operation = %d\n", (int)((char *)(&req.operation) - (char *)(&req))));
  11.325 +    KdPrint((__DRIVER_NAME "     nr_segments = %d\n", (int)((char *)(&req.nr_segments) - (char *)(&req))));
  11.326 +    KdPrint((__DRIVER_NAME "     handle = %d\n", (int)((char *)(&req.handle) - (char *)(&req))));
  11.327 +    KdPrint((__DRIVER_NAME "     id = %d\n", (int)((char *)(&req.rqid) - (char *)(&req))));
  11.328 +    KdPrint((__DRIVER_NAME "     sector_number = %d\n", (int)((char *)(&req.sector_number) - (char *)(&req))));
  11.329 +    KdPrint((__DRIVER_NAME "     seg = %d\n", (int)((char *)(&req.seg) - (char *)(&req))));
  11.330 +
  11.331 +    KdPrint((__DRIVER_NAME "     id = %d\n", (int)((char *)(&rep.id) - (char *)(&rep))));
  11.332 +    KdPrint((__DRIVER_NAME "     operation = %d\n", (int)((char *)(&rep.operation) - (char *)(&rep))));
  11.333 +    KdPrint((__DRIVER_NAME "     status = %d\n", (int)((char *)(&rep.status) - (char *)(&rep))));
  11.334 +
  11.335 +    KdPrint((__DRIVER_NAME "     sizeof(union vscsiif_sring_entry) = %d\n", sizeof(union vscsiif_sring_entry)));
  11.336 +    KdPrint((__DRIVER_NAME "     %d\n", (int)((char *)(&entries[1]) - (char *)(&entries[0]))));
  11.337 +*/
  11.338 +    KdPrint((__DRIVER_NAME "     Set Frontend state to Initialised\n"));
  11.339 +    break;
  11.340 +
  11.341 +  case XenbusStateInitialised:
  11.342 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialised\n"));
  11.343 +    break;
  11.344 +
  11.345 +  case XenbusStateConnected:
  11.346 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Connected\n"));  
  11.347 +
  11.348 +    RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  11.349 +    RtlStringCbCatA(TmpPath, 128, "/state");
  11.350 +    DeviceData->XenDeviceData->XenInterface.XenBus_Printf(DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", XenbusStateConnected);
  11.351 +
  11.352 +    KdPrint((__DRIVER_NAME "     Set Frontend state to Connected\n"));
  11.353 +    InterlockedIncrement(&DeviceData->EnumeratedDevices);
  11.354 +    KdPrint((__DRIVER_NAME "     Added a device\n"));  
  11.355 +
  11.356 +// now ask windows to rescan the scsi bus...
  11.357 +    DeviceData->BusChangePending = 1;
  11.358 +    break;
  11.359 +
  11.360 +  case XenbusStateClosing:
  11.361 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Closing\n"));  
  11.362 +    // this behaviour is only to properly close down to then restart in the case of a dump
  11.363 +    RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  11.364 +    RtlStringCbCatA(TmpPath, 128, "/state");
  11.365 +    DeviceData->XenDeviceData->XenInterface.XenBus_Printf(DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", XenbusStateClosed);
  11.366 +    KdPrint((__DRIVER_NAME "     Set Frontend state to Closed\n"));
  11.367 +    break;
  11.368 +
  11.369 +  case XenbusStateClosed:
  11.370 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Closed\n"));  
  11.371 +    // this behaviour is only to properly close down to then restart in the case of a dump
  11.372 +    RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  11.373 +    RtlStringCbCatA(TmpPath, 128, "/state");
  11.374 +    DeviceData->XenDeviceData->XenInterface.XenBus_Printf(DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", XenbusStateInitialising);
  11.375 +    KdPrint((__DRIVER_NAME "     Set Frontend state to Initialising\n"));
  11.376 +    break;
  11.377 +
  11.378 +  default:
  11.379 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Undefined = %d\n", NewState));
  11.380 +    break;
  11.381 +  }
  11.382 +
  11.383 +  KdPrint((__DRIVER_NAME " <-- BackEndStateHandler\n"));
  11.384 +}
  11.385 +
  11.386 +static VOID
  11.387 +XenScsi_WatchHandler(char *Path, PVOID DeviceExtension)
  11.388 +{
  11.389 +  PXENSCSI_DEVICE_DATA DeviceData = (PXENSCSI_DEVICE_DATA)DeviceExtension;
  11.390 +  char **Bits;
  11.391 +  int Count;
  11.392 +  char TmpPath[128];
  11.393 +  char *Value;
  11.394 +  int CurrentBus, CurrentTarget;
  11.395 +  PXENSCSI_TARGET_DATA TargetData, VacantTarget;
  11.396 +  KIRQL OldIrql;
  11.397 +  int i;
  11.398 +
  11.399 +  KdPrint((__DRIVER_NAME " --> WatchHandler (DeviceData = %p)\n", DeviceData));
  11.400 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  11.401 +
  11.402 +  KdPrint((__DRIVER_NAME "     Path = %s\n", Path));
  11.403 +
  11.404 +  Bits = SplitString(Path, '/', 4, &Count);
  11.405 +  switch (Count)
  11.406 +  {
  11.407 +  case 0:
  11.408 +  case 1:
  11.409 +  case 2:
  11.410 +    break; // should never happen
  11.411 +  case 3:
  11.412 +    break;
  11.413 +  case 4:
  11.414 +    if (strcmp(Bits[3], "state") != 0) // we only care when the state appears
  11.415 +      break;
  11.416 +
  11.417 +    KeAcquireSpinLock(&DeviceData->Lock, &OldIrql);
  11.418 +
  11.419 +    for (VacantTarget = NULL,i = 0; i < SCSI_BUSES * SCSI_TARGETS_PER_BUS; i++)
  11.420 +    {
  11.421 +      CurrentBus = i / SCSI_TARGETS_PER_BUS;
  11.422 +      CurrentTarget = i % SCSI_TARGETS_PER_BUS;
  11.423 +      if (CurrentTarget == 7) // don't use 7 - it would be for the controller
  11.424 +        continue;
  11.425 +      TargetData = &DeviceData->BusData[CurrentBus].TargetData[CurrentTarget];
  11.426 +      if (TargetData->Present && strncmp(TargetData->Path, Path, strlen(TargetData->Path)) == 0 && Path[strlen(TargetData->Path)] == '/')
  11.427 +        break; // already exists
  11.428 +      else if (!TargetData->Present && VacantTarget == NULL)
  11.429 +        VacantTarget = TargetData;
  11.430 +    }
  11.431 +    if (i == SCSI_BUSES * SCSI_TARGETS_PER_BUS && VacantTarget != NULL)
  11.432 +    {
  11.433 +      VacantTarget->Present = 1;
  11.434 +      KeReleaseSpinLock(&DeviceData->Lock, OldIrql);
  11.435 +
  11.436 +      DeviceData->XenDeviceData->XenInterface.XenBus_Read(
  11.437 +        DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  11.438 +        XBT_NIL, Path, &Value);
  11.439 +
  11.440 +      if (Value == NULL)
  11.441 +      {
  11.442 +        KdPrint((__DRIVER_NAME "     blank state?\n"));
  11.443 +        break;
  11.444 +      }
  11.445 +      if (atoi(Value) != XenbusStateInitialising)
  11.446 +        DeviceData->XenDeviceData->XenInterface.XenBus_Printf(
  11.447 +          DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  11.448 +          XBT_NIL, Path, "%d", XenbusStateClosing);
  11.449 +
  11.450 +      RtlStringCbCopyA(VacantTarget->Path, 128, Bits[0]);
  11.451 +      RtlStringCbCatA(VacantTarget->Path, 128, "/");
  11.452 +      RtlStringCbCatA(VacantTarget->Path, 128, Bits[1]);
  11.453 +      RtlStringCbCatA(VacantTarget->Path, 128, "/");
  11.454 +      RtlStringCbCatA(VacantTarget->Path, 128, Bits[2]);
  11.455 +
  11.456 +      VacantTarget->DeviceIndex = atoi(Bits[2]);
  11.457 +
  11.458 +      RtlStringCbCopyA(TmpPath, 128, VacantTarget->Path);
  11.459 +      RtlStringCbCatA(TmpPath, 128, "/backend");
  11.460 +      DeviceData->XenDeviceData->XenInterface.XenBus_Read(
  11.461 +        DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  11.462 +        XBT_NIL, TmpPath, &Value);
  11.463 +      if (Value == NULL)
  11.464 +        KdPrint((__DRIVER_NAME "     Read Failed\n"));
  11.465 +      else
  11.466 +        RtlStringCbCopyA(VacantTarget->BackendPath, 128, Value);
  11.467 +      RtlStringCbCopyA(TmpPath, 128, VacantTarget->BackendPath);
  11.468 +      RtlStringCbCatA(TmpPath, 128, "/state");
  11.469 +
  11.470 +      DeviceData->XenDeviceData->XenInterface.XenBus_AddWatch(
  11.471 +        DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  11.472 +        XBT_NIL, TmpPath, XenScsi_BackEndStateHandler, VacantTarget);
  11.473 +    }
  11.474 +    else
  11.475 +      KeReleaseSpinLock(&DeviceData->Lock, OldIrql);
  11.476 +    break;
  11.477 +  }
  11.478 +  
  11.479 +  FreeSplitString(Bits, Count);
  11.480 +
  11.481 +  KdPrint((__DRIVER_NAME " <-- WatchHandler\n"));  
  11.482 +
  11.483 +  return;
  11.484 +}
  11.485 +
  11.486 +static ULONG
  11.487 +XenScsi_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
  11.488 +{
  11.489 +  ULONG i, j;
  11.490 +  PACCESS_RANGE AccessRange;
  11.491 +  PXENSCSI_DEVICE_DATA DeviceData = (PXENSCSI_DEVICE_DATA)DeviceExtension;
  11.492 +  char **ScsiDevices;
  11.493 +  char *msg;
  11.494 +  char buffer[128];
  11.495 +
  11.496 +  UNREFERENCED_PARAMETER(HwContext);
  11.497 +  UNREFERENCED_PARAMETER(BusInformation);
  11.498 +  UNREFERENCED_PARAMETER(ArgumentString);
  11.499 +  KeInitializeSpinLock(&DeviceData->Lock);
  11.500 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));  
  11.501 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  11.502 +
  11.503 +  // testing this for dump mode
  11.504 +//  if (KeGetCurrentIrql() > ConfigInfo->BusInterruptLevel)
  11.505 +//    ConfigInfo->BusInterruptLevel = KeGetCurrentIrql();
  11.506 +
  11.507 +  KdPrint((__DRIVER_NAME "     BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
  11.508 +  KdPrint((__DRIVER_NAME "     BusInterruptVector = %d\n", ConfigInfo->BusInterruptVector));
  11.509 +
  11.510 +  KdPrint((__DRIVER_NAME "     AccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));
  11.511 +
  11.512 +  for (i = 0; i < ConfigInfo->NumberOfAccessRanges; i++)
  11.513 +  {
  11.514 +    AccessRange = &(*(ConfigInfo->AccessRanges))[i];
  11.515 +    KdPrint((__DRIVER_NAME "     AccessRange %2d: RangeStart = %p, RangeLength = %x, RangeInMemory = %d\n", i, AccessRange->RangeStart.QuadPart, AccessRange->RangeLength, AccessRange->RangeInMemory));
  11.516 +    switch (i)
  11.517 +    {
  11.518 +    case 0:
  11.519 +      DeviceData->XenDeviceData = (PVOID)(xen_ulong_t)AccessRange->RangeStart.QuadPart;
  11.520 +      KdPrint((__DRIVER_NAME "     Mapped to virtual address %p\n", DeviceData->XenDeviceData));
  11.521 +      KdPrint((__DRIVER_NAME "     Magic = %08x\n", DeviceData->XenDeviceData->Magic));
  11.522 +      if (DeviceData->XenDeviceData->Magic != XEN_DATA_MAGIC)
  11.523 +      {
  11.524 +        KdPrint((__DRIVER_NAME "     Invalid Magic Number\n"));
  11.525 +        return SP_RETURN_NOT_FOUND;
  11.526 +      }
  11.527 +      break;
  11.528 +    default:
  11.529 +      break;
  11.530 +    }
  11.531 +  }
  11.532 +#if defined(__x86_64__)
  11.533 +  ConfigInfo->Master = TRUE; // Won't work under x64 without this...
  11.534 +#endif
  11.535 +  ConfigInfo->MaximumTransferLength = VSCSIIF_SG_TABLESIZE * PAGE_SIZE;
  11.536 +  ConfigInfo->NumberOfPhysicalBreaks = VSCSIIF_SG_TABLESIZE - 1;
  11.537 +  ConfigInfo->ScatterGather = TRUE;
  11.538 +  ConfigInfo->AlignmentMask = 0;
  11.539 +  ConfigInfo->NumberOfBuses = SCSI_BUSES;
  11.540 +  for (i = 0; i < ConfigInfo->NumberOfBuses; i++)
  11.541 +  {
  11.542 +    ConfigInfo->InitiatorBusId[i] = 7;
  11.543 +  }
  11.544 +  ConfigInfo->MaximumNumberOfLogicalUnits = 1;
  11.545 +  ConfigInfo->MaximumNumberOfTargets = SCSI_TARGETS_PER_BUS;
  11.546 +//  ConfigInfo->TaggedQueueing = TRUE;
  11.547 +  if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
  11.548 +    ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
  11.549 +  // This all has to be initialized here as the real Initialize routine
  11.550 +  // is called at DIRQL, and the XenBus stuff has to be called at
  11.551 +  // <= DISPATCH_LEVEL
  11.552 +
  11.553 +  for (i = 0; i < SCSI_BUSES; i++)
  11.554 +  {
  11.555 +    for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
  11.556 +    {
  11.557 +      DeviceData->BusData[i].TargetData[j].Present = 0;
  11.558 +      DeviceData->BusData[i].TargetData[j].DeviceData = DeviceData;
  11.559 +    }
  11.560 +  }
  11.561 +
  11.562 +  DeviceData->XenDeviceData->WatchContext = DeviceExtension;
  11.563 +  KeMemoryBarrier();
  11.564 +  DeviceData->XenDeviceData->WatchHandler = XenScsi_WatchHandler;
  11.565 +
  11.566 +//  KeInitializeEvent(&DeviceData->WaitDevicesEvent, SynchronizationEvent, FALSE);  
  11.567 +  DeviceData->EnumeratedDevices = 0;
  11.568 +  DeviceData->TotalInitialDevices = 0;
  11.569 +
  11.570 +  if (DeviceData->XenDeviceData->AutoEnumerate)
  11.571 +  {
  11.572 +    msg = DeviceData->XenDeviceData->XenInterface.XenBus_List(
  11.573 +      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  11.574 +      XBT_NIL, "device/vscsi", &ScsiDevices);
  11.575 +    if (!msg)
  11.576 +    {
  11.577 +      for (i = 0; ScsiDevices[i]; i++)
  11.578 +      {
  11.579 +        KdPrint((__DRIVER_NAME "     found existing scsi device %s\n", ScsiDevices[i]));
  11.580 +        RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/vscsi/%s/state", ScsiDevices[i]);
  11.581 +        XenScsi_WatchHandler(buffer, DeviceData);
  11.582 +        DeviceData->TotalInitialDevices++;
  11.583 +      }  
  11.584 +    }
  11.585 +  }
  11.586 +
  11.587 +  *Again = FALSE;
  11.588 +
  11.589 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
  11.590 +
  11.591 +  return SP_RETURN_FOUND;
  11.592 +}
  11.593 +
  11.594 +static VOID 
  11.595 +XenScsi_CheckBusChangedTimer(PVOID DeviceExtension);
  11.596 +
  11.597 +static VOID 
  11.598 +XenScsi_CheckBusEnumeratedTimer(PVOID DeviceExtension)
  11.599 +{
  11.600 +  PXENSCSI_DEVICE_DATA DeviceData = (PXENSCSI_DEVICE_DATA)DeviceExtension;
  11.601 +
  11.602 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  11.603 +//  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  11.604 +
  11.605 +  if (DeviceData->BusChangePending && DeviceData->EnumeratedDevices >= DeviceData->TotalInitialDevices)
  11.606 +  {
  11.607 +    DeviceData->BusChangePending = 0;
  11.608 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  11.609 +    ScsiPortNotification(RequestTimerCall, DeviceExtension, XenScsi_CheckBusChangedTimer, 1000000);
  11.610 +  }
  11.611 +  else
  11.612 +  {
  11.613 +    ScsiPortNotification(RequestTimerCall, DeviceExtension, XenScsi_CheckBusEnumeratedTimer, 100000);
  11.614 +  }
  11.615 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  11.616 +}
  11.617 +
  11.618 +static VOID 
  11.619 +XenScsi_CheckBusChangedTimer(PVOID DeviceExtension)
  11.620 +{
  11.621 +  PXENSCSI_DEVICE_DATA DeviceData = (PXENSCSI_DEVICE_DATA)DeviceExtension;
  11.622 +
  11.623 +  if (DeviceData->BusChangePending)
  11.624 +  {
  11.625 +    ScsiPortNotification(BusChangeDetected, DeviceData, 0);
  11.626 +    DeviceData->BusChangePending = 0;
  11.627 +  }
  11.628 +  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenScsi_CheckBusChangedTimer, 1000000);
  11.629 +}
  11.630 +
  11.631 +static BOOLEAN
  11.632 +XenScsi_HwScsiInitialize(PVOID DeviceExtension)
  11.633 +{
  11.634 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  11.635 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  11.636 +
  11.637 +  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenScsi_CheckBusEnumeratedTimer, 100000);
  11.638 +
  11.639 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  11.640 +
  11.641 +  return TRUE;
  11.642 +}
  11.643 +
  11.644 +// Call with device lock held
  11.645 +static VOID
  11.646 +XenScsi_PutSrbOnRing(PXENSCSI_TARGET_DATA TargetData, PSCSI_REQUEST_BLOCK Srb)
  11.647 +{
  11.648 +  //PUCHAR DataBuffer;
  11.649 +  int i;
  11.650 +  vscsiif_shadow_t *shadow;
  11.651 +  uint16_t id;
  11.652 +
  11.653 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  11.654 +
  11.655 +  if (RING_FULL(&TargetData->Ring))
  11.656 +  {
  11.657 +    KdPrint((__DRIVER_NAME "     RING IS FULL - EXPECT BADNESS\n"));
  11.658 +    // TODO: Fail badly here
  11.659 +  }
  11.660 +
  11.661 +  id = GET_ID_FROM_FREELIST(TargetData);
  11.662 +  if (id == 0x0fff)
  11.663 +  {
  11.664 +    KdPrint((__DRIVER_NAME "     Something is horribly wrong in PutSrbOnRing\n"));
  11.665 +  }
  11.666 +
  11.667 +  shadow = &TargetData->shadow[id];
  11.668 +  shadow->Srb = Srb;
  11.669 +  shadow->req.rqid = id;
  11.670 +  shadow->req.cmd = VSCSIIF_CMND_SCSI;
  11.671 +  memcpy(shadow->req.cmnd, Srb->Cdb, 16);
  11.672 +  shadow->req.cmd_len = Srb->CdbLength;
  11.673 +  shadow->req.id = TargetData->id;
  11.674 +  shadow->req.lun = TargetData->lun;
  11.675 +  shadow->req.channel = TargetData->channel;
  11.676 +  if ((Srb->SrbFlags & SRB_FLAGS_DATA_IN) && (Srb->SrbFlags & SRB_FLAGS_DATA_OUT))
  11.677 +    shadow->req.sc_data_direction = DMA_BIDIRECTIONAL;
  11.678 +  else if (Srb->SrbFlags & SRB_FLAGS_DATA_IN)
  11.679 +    shadow->req.sc_data_direction = DMA_FROM_DEVICE;
  11.680 +  else if (Srb->SrbFlags & SRB_FLAGS_DATA_OUT)
  11.681 +    shadow->req.sc_data_direction = DMA_TO_DEVICE;
  11.682 +  else
  11.683 +    shadow->req.sc_data_direction = DMA_NONE;
  11.684 +  shadow->req.use_sg = (UINT8)((Srb->DataTransferLength + PAGE_SIZE - 1) / PAGE_SIZE);
  11.685 +  shadow->req.request_bufflen = Srb->DataTransferLength;
  11.686 +
  11.687 +  for (i = 0; i < shadow->req.use_sg; i++)
  11.688 +  {
  11.689 +    shadow->req.seg[i].offset = (uint16_t)i * PAGE_SIZE;
  11.690 +    if (i != shadow->req.use_sg - 1)
  11.691 +      shadow->req.seg[i].length = PAGE_SIZE;
  11.692 +    else
  11.693 +      shadow->req.seg[i].length = (uint16_t)(Srb->DataTransferLength & (PAGE_SIZE - 1));
  11.694 +  }
  11.695 +  if (Srb->SrbFlags & SRB_FLAGS_DATA_OUT)
  11.696 +    memcpy(TargetData->shadow[shadow->req.rqid].Buf, Srb->DataBuffer, Srb->DataTransferLength);
  11.697 +
  11.698 +  *RING_GET_REQUEST(&TargetData->Ring, TargetData->Ring.req_prod_pvt) = shadow->req;
  11.699 +  TargetData->Ring.req_prod_pvt++;
  11.700 +
  11.701 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  11.702 +}
  11.703 +
  11.704 +static BOOLEAN
  11.705 +XenScsi_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
  11.706 +{
  11.707 +  PXENSCSI_DEVICE_DATA DeviceData = (PXENSCSI_DEVICE_DATA)DeviceExtension;
  11.708 +  PXENSCSI_TARGET_DATA TargetData;
  11.709 +  int notify;
  11.710 +
  11.711 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " PathId = %d, TargetId = %d, Lun = %d\n", Srb->PathId, Srb->TargetId, Srb->Lun));
  11.712 +
  11.713 +  // If we haven't enumerated all the devices yet then just defer the request
  11.714 +  // A timer will issue a NextRequest to get things started again...
  11.715 +  if (DeviceData->EnumeratedDevices < DeviceData->TotalInitialDevices)
  11.716 +  {
  11.717 +    Srb->SrbStatus = SRB_STATUS_BUSY;
  11.718 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  11.719 +    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Bus not enumerated yet)\n"));
  11.720 +    return TRUE;
  11.721 +  }
  11.722 +
  11.723 +  if (Srb->PathId >= SCSI_BUSES || Srb->TargetId >= SCSI_TARGETS_PER_BUS)
  11.724 +  {
  11.725 +    Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
  11.726 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  11.727 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  11.728 +    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Out of bounds)\n"));
  11.729 +    return TRUE;
  11.730 +  }
  11.731 +
  11.732 +  TargetData = &DeviceData->BusData[Srb->PathId].TargetData[Srb->TargetId];
  11.733 +
  11.734 +  if (!TargetData->Present)
  11.735 +  {
  11.736 +    Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
  11.737 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  11.738 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  11.739 +    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Not Present)\n"));
  11.740 +    return TRUE;
  11.741 +  }
  11.742 +
  11.743 +  switch (Srb->Function)
  11.744 +  {
  11.745 +  case SRB_FUNCTION_EXECUTE_SCSI:
  11.746 +    XenScsi_PutSrbOnRing(TargetData, Srb);
  11.747 +    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&TargetData->Ring, notify);
  11.748 +    if (notify)
  11.749 +      DeviceData->XenDeviceData->XenInterface.EvtChn_Notify(
  11.750 +        DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  11.751 +        TargetData->EventChannel);
  11.752 +    if (!RING_FULL(&TargetData->Ring))
  11.753 +      ScsiPortNotification(NextLuRequest, DeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun);
  11.754 +    else
  11.755 +      ScsiPortNotification(NextRequest, DeviceExtension);
  11.756 +    break;
  11.757 +  case SRB_FUNCTION_CLAIM_DEVICE:
  11.758 +    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_CLAIM_DEVICE\n"));
  11.759 +//    ObReferenceObject(WdfDeviceWdmGetDeviceObject(Device));
  11.760 +//    Srb->DataBuffer = WdfDeviceWdmGetDeviceObject(Device);
  11.761 +    Srb->SrbStatus = SRB_STATUS_SUCCESS;
  11.762 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  11.763 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  11.764 +    break;
  11.765 +  case SRB_FUNCTION_IO_CONTROL:
  11.766 +    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_IO_CONTROL\n"));
  11.767 +    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  11.768 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  11.769 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  11.770 +    break;
  11.771 +  case SRB_FUNCTION_FLUSH:
  11.772 +    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH\n"));
  11.773 +    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  11.774 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  11.775 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  11.776 +    break;
  11.777 +  default:
  11.778 +    KdPrint((__DRIVER_NAME "     Unhandled Srb->Function = %08X\n", Srb->Function));
  11.779 +    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  11.780 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  11.781 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  11.782 +    break;
  11.783 +  }
  11.784 +
  11.785 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  11.786 +
  11.787 +  return TRUE;
  11.788 +}
  11.789 +
  11.790 +static BOOLEAN
  11.791 +XenScsi_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId)
  11.792 +{
  11.793 +  UNREFERENCED_PARAMETER(DeviceExtension);
  11.794 +  UNREFERENCED_PARAMETER(PathId);
  11.795 +
  11.796 +
  11.797 +  KdPrint((__DRIVER_NAME " --> HwScsiResetBus\n"));
  11.798 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  11.799 +
  11.800 +  KdPrint((__DRIVER_NAME " <-- HwScsiResetBus\n"));
  11.801 +
  11.802 +  return TRUE;
  11.803 +}
  11.804 +
  11.805 +
  11.806 +static BOOLEAN
  11.807 +XenScsi_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState)
  11.808 +{
  11.809 +  UNREFERENCED_PARAMETER(DeviceExtension);
  11.810 +  UNREFERENCED_PARAMETER(Context);
  11.811 +  UNREFERENCED_PARAMETER(SaveState);
  11.812 +
  11.813 +  KdPrint((__DRIVER_NAME " --> HwScsiAdapterState\n"));
  11.814 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  11.815 +
  11.816 +  KdPrint((__DRIVER_NAME " <-- HwScsiAdapterState\n"));
  11.817 +
  11.818 +  return TRUE;
  11.819 +}
  11.820 +
  11.821 +static SCSI_ADAPTER_CONTROL_STATUS
  11.822 +XenScsi_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
  11.823 +{
  11.824 +  SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
  11.825 +  PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
  11.826 +
  11.827 +  UNREFERENCED_PARAMETER(DeviceExtension);
  11.828 +
  11.829 +  KdPrint((__DRIVER_NAME " --> HwScsiAdapterControl\n"));
  11.830 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  11.831 +
  11.832 +  switch (ControlType)
  11.833 +  {
  11.834 +  case ScsiQuerySupportedControlTypes:
  11.835 +    SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
  11.836 +    KdPrint((__DRIVER_NAME "     ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
  11.837 +    SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
  11.838 +    SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
  11.839 +    break;
  11.840 +  case ScsiStopAdapter:
  11.841 +    KdPrint((__DRIVER_NAME "     ScsiStopAdapter\n"));
  11.842 +    break;
  11.843 +  case ScsiRestartAdapter:
  11.844 +    KdPrint((__DRIVER_NAME "     ScsiRestartAdapter\n"));
  11.845 +    break;
  11.846 +  case ScsiSetBootConfig:
  11.847 +    KdPrint((__DRIVER_NAME "     ScsiSetBootConfig\n"));
  11.848 +    break;
  11.849 +  case ScsiSetRunningConfig:
  11.850 +    KdPrint((__DRIVER_NAME "     ScsiSetRunningConfig\n"));
  11.851 +    break;
  11.852 +  default:
  11.853 +    KdPrint((__DRIVER_NAME "     UNKNOWN\n"));
  11.854 +    break;
  11.855 +  }
  11.856 +
  11.857 +  KdPrint((__DRIVER_NAME " <-- HwScsiAdapterControl\n"));
  11.858 +
  11.859 +  return Status;
  11.860 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/xenscsi/xenscsi.h	Wed Feb 20 17:14:14 2008 +1100
    12.3 @@ -0,0 +1,94 @@
    12.4 +#if !defined(_XENSCSI_H_)
    12.5 +#define _XENSCSI_H_
    12.6 +
    12.7 +#include <ntifs.h>
    12.8 +#include <ntddk.h>
    12.9 +#include <wdm.h>
   12.10 +#include <wdf.h>
   12.11 +#include <initguid.h>
   12.12 +#include <ntdddisk.h>
   12.13 +#include <srb.h>
   12.14 +
   12.15 +#define NTSTRSAFE_LIB
   12.16 +#include <ntstrsafe.h>
   12.17 +
   12.18 +#define __DRIVER_NAME "XenSCSI"
   12.19 +
   12.20 +#include <xen_windows.h>
   12.21 +#include <memory.h>
   12.22 +#include <grant_table.h>
   12.23 +#include <event_channel.h>
   12.24 +#include <hvm/params.h>
   12.25 +#include <hvm/hvm_op.h>
   12.26 +#include <xen_public.h>
   12.27 +#include <io/ring.h>
   12.28 +#include <io/vscsiif.h>
   12.29 +
   12.30 +typedef struct vscsiif_request vscsiif_request_t;
   12.31 +typedef struct vscsiif_response vscsiif_response_t;
   12.32 +
   12.33 +#define XENSCSI_POOL_TAG (ULONG) 'XSCS'
   12.34 +
   12.35 +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
   12.36 +#define VSCSIIF_RING_SIZE __RING_SIZE((vscsiif_sring_t *)0, PAGE_SIZE)
   12.37 +
   12.38 +typedef struct {
   12.39 +  vscsiif_request_t req;
   12.40 +  PSCSI_REQUEST_BLOCK Srb;
   12.41 +  PMDL Mdl;
   12.42 +  VOID *Buf;
   12.43 +} vscsiif_shadow_t;
   12.44 +
   12.45 +//#include "scsidata.h"
   12.46 +
   12.47 +#define SCSI_BUSES 4
   12.48 +#define SCSI_TARGETS_PER_BUS 16
   12.49 +
   12.50 +struct
   12.51 +{
   12.52 +  int Present;
   12.53 +  BOOLEAN PendingInterrupt;
   12.54 +  PVOID DeviceData; // how can we create a forward definition for this???
   12.55 +  evtchn_port_t EventChannel;
   12.56 +  vscsiif_shadow_t *shadow;
   12.57 +  uint16_t shadow_free;
   12.58 +  ULONG RingBufPFN;
   12.59 +  int BackendState;
   12.60 +  int FrontendState;
   12.61 +  char Path[128];
   12.62 +  int DeviceIndex;
   12.63 +  char BackendPath[128];
   12.64 +  vscsiif_front_ring_t Ring;
   12.65 +  int ring_detect_state;
   12.66 +  int host;
   12.67 +  int channel;
   12.68 +  int id;
   12.69 +  int lun;
   12.70 +} typedef XENSCSI_TARGET_DATA, *PXENSCSI_TARGET_DATA;
   12.71 +
   12.72 +struct
   12.73 +{
   12.74 +  XENSCSI_TARGET_DATA TargetData[SCSI_TARGETS_PER_BUS];
   12.75 +} typedef XENSCSI_BUS_DATA, *PXENSCSI_BUS_DATA;
   12.76 +
   12.77 +struct
   12.78 +{
   12.79 +  PXENPCI_XEN_DEVICE_DATA XenDeviceData;
   12.80 +  XENSCSI_BUS_DATA BusData[SCSI_BUSES];
   12.81 +
   12.82 +  KSPIN_LOCK Lock;
   12.83 +
   12.84 +  int BusChangePending;
   12.85 +
   12.86 +  LONG EnumeratedDevices;
   12.87 +  int TotalInitialDevices;
   12.88 +} typedef XENSCSI_DEVICE_DATA, *PXENSCSI_DEVICE_DATA;
   12.89 +
   12.90 +enum dma_data_direction {
   12.91 +        DMA_BIDIRECTIONAL = 0,
   12.92 +        DMA_TO_DEVICE = 1,
   12.93 +        DMA_FROM_DEVICE = 2,
   12.94 +        DMA_NONE = 3,
   12.95 +};
   12.96 +
   12.97 +#endif
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/xenscsi/xenscsi.inx	Wed Feb 20 17:14:14 2008 +1100
    13.3 @@ -0,0 +1,133 @@
    13.4 +[Version]
    13.5 +Signature="$WINDOWS NT$"
    13.6 +Class=SCSIAdapter
    13.7 +ClassGuid={4D36E97B-E325-11CE-BFC1-08002BE10318}
    13.8 +Provider=%XenGplPv%
    13.9 +
   13.10 +[DestinationDirs]
   13.11 +DefaultDestDir = 12
   13.12 +ClassInstall32_CopyFiles=11
   13.13 +CoInstaller_CopyFiles = 11
   13.14 +
   13.15 +[ControlFlags]
   13.16 +ExcludeFromSelect=*
   13.17 +
   13.18 +[Manufacturer]
   13.19 +%XenGplPv%=XenGplPv,NTx86
   13.20 +%XenGplPv%=XenGplPv,NTamd64
   13.21 +
   13.22 +[XenGplPv.NTx86]
   13.23 +%XenScsi.DRVDESC%=XenScsi_Inst, XEN\VSCSI
   13.24 +
   13.25 +[XenGplPv.NTamd64]
   13.26 +%XenScsi.DRVDESC%=XenScsi_Inst, XEN\VSCSI
   13.27 +
   13.28 +[XenScsi_Inst.NT]
   13.29 +CopyFiles=XenScsi.CopyFiles
   13.30 +
   13.31 +[XenScsi.CopyFiles]
   13.32 +xenscsi.sys
   13.33 +xenaddresource.sys
   13.34 +
   13.35 +[XenScsi_Inst.NT.Services]
   13.36 +AddService=XenScsi,2,XenScsi_Service, XenScsi_EventLog
   13.37 +AddService=XenAddResource,,XenAddResource_Service
   13.38 +
   13.39 +[XenScsi_Service]
   13.40 +DisplayName    = %XenScsi.SVCDESC%                            
   13.41 +ServiceType    = 1
   13.42 +StartType      = 0
   13.43 +ErrorControl   = 1
   13.44 +LoadOrderGroup = System Bus Extender
   13.45 +ServiceBinary  = %12%\xenscsi.sys                            
   13.46 +AddReg = XenScsi_Service_AddReg
   13.47 +
   13.48 +[XenScsi_Service_AddReg]
   13.49 +HKR,"Parameters\PnpInterface", "0", 0x00010001, 0x00000001
   13.50 +
   13.51 +[XenScsi_EventLog]
   13.52 +AddReg = XenScsi_EventLog_AddReg
   13.53 +
   13.54 +[XenScsi_EventLog_AddReg]
   13.55 +HKR,,EventMessageFile,0x00020000,"%SystemRoot%\System32\IoLogMsg.dll;%SystemRoot%\System32\drivers\XenScsi.sys"
   13.56 +HKR,,TypesSupported,0x00010001,7
   13.57 +
   13.58 +[XenScsi_Inst.NT.CoInstallers]
   13.59 +AddReg=CoInstaller_AddReg
   13.60 +CopyFiles=CoInstaller_CopyFiles
   13.61 +
   13.62 +[XenScsi_Inst.NT.Wdf]
   13.63 +KmdfService = xenscsi, xenscsi_wdfsect
   13.64 +
   13.65 +[XenScsi_Inst.NT.HW]
   13.66 +AddReg = XenScsi_Inst_HW_AddReg
   13.67 +
   13.68 +[XenScsi_Inst_HW_AddReg]
   13.69 +HKR,,"UpperFilters",0x00010000,"xenaddresource"
   13.70 +
   13.71 +[XenAddResource_Inst.NT]
   13.72 +CopyFiles=XenAddResource.CopyFiles
   13.73 +
   13.74 +[XenAddResource_Inst.NT.Services]
   13.75 +AddService=XenAddResource,,XenAddResource_Service 
   13.76 +
   13.77 +[XenAddResource_Inst.NT.HW]
   13.78 +AddReg = XenAddResource_Inst_HW_AddReg
   13.79 +
   13.80 +[XenAddResource_Inst_HW_AddReg]
   13.81 +HKR,,"LowerFilters",0x00010000,"xenaddresource"
   13.82 +
   13.83 +[XenAddResource.CopyFiles]
   13.84 +xenaddresource.sys
   13.85 +
   13.86 +[XenAddResource_Service]
   13.87 +DisplayName    = "Xen Resource Adder"
   13.88 +ServiceType    = 1
   13.89 +StartType      = 0
   13.90 +ErrorControl   = 1
   13.91 +LoadOrderGroup = System Bus Extender
   13.92 +ServiceBinary  = %12%\xenaddresource.sys
   13.93 +AddReg = XenAddResource_Service_AddReg
   13.94 +
   13.95 +[XenAddResource.CopyFiles]
   13.96 +xenaddresource.sys
   13.97 +
   13.98 +[XenAddResource_Service_AddReg]
   13.99 +HKR,"Parameters\PnpInterface", "0", 0x00010001, 0x00000001
  13.100 +
  13.101 +[XenAddResource_Inst.NT.CoInstallers]
  13.102 +AddReg=CoInstaller_AddReg
  13.103 +CopyFiles=CoInstaller_CopyFiles
  13.104 +
  13.105 +[XenAddResource_Inst.NT.Wdf]
  13.106 +KmdfService = xenaddresource, xenaddresource_wdfsect
  13.107 +
  13.108 +[xenscsi_wdfsect]
  13.109 +KmdfLibraryVersion = $KMDFVERSION$
  13.110 +
  13.111 +[xenaddresource_wdfsect]
  13.112 +KmdfLibraryVersion = $KMDFVERSION$
  13.113 +
  13.114 +[SourceDisksFiles]
  13.115 +xenscsi.sys=1
  13.116 +xenaddresource.sys=1
  13.117 +WdfCoinstaller$KMDFCOINSTALLERVERSION$.dll=1,,
  13.118 +
  13.119 +[SourceDisksNames.x86]
  13.120 +1 = %DISK_NAME%,,,\i386
  13.121 +
  13.122 +[SourceDisksNames.amd64]
  13.123 +1 = %DISK_NAME%,,,\amd64
  13.124 +
  13.125 +[CoInstaller_CopyFiles]
  13.126 +WdfCoinstaller$KMDFCOINSTALLERVERSION$.dll,,,2
  13.127 +
  13.128 +[CoInstaller_AddReg]
  13.129 +HKR,,CoInstallers32,0x00010000, "WdfCoinstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"
  13.130 +
  13.131 +[Strings]
  13.132 +XenGplPv = "Xen GPL PV Driver Developers"
  13.133 +XenScsi.SVCDESC = "Xen SCSI Driver"
  13.134 +XenScsi.DRVDESC = "Xen SCSI Driver"
  13.135 +XenAddResource.DRVDESC = "Xen Resource Adder"
  13.136 +DISK_NAME = "Xen SCSI Device Driver Install Disk"
    14.1 --- a/xenvbd/xenvbd.c	Mon Feb 18 22:32:41 2008 +1100
    14.2 +++ b/xenvbd/xenvbd.c	Wed Feb 20 17:14:14 2008 +1100
    14.3 @@ -13,8 +13,6 @@
    14.4  #define wmb() KeMemoryBarrier()
    14.5  #define mb() KeMemoryBarrier()
    14.6  
    14.7 -//#define BUF_PAGES_PER_SRB 11
    14.8 -
    14.9  DRIVER_INITIALIZE DriverEntry;
   14.10  
   14.11  static ULONG
   14.12 @@ -258,7 +256,7 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
   14.13    }
   14.14  //  KdPrint((__DRIVER_NAME " <-- HwScsiInterrupt\n"));
   14.15  
   14.16 -  return TRUE;
   14.17 +  return FALSE;
   14.18  }
   14.19  
   14.20  static VOID
   14.21 @@ -917,6 +915,7 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   14.22    {
   14.23      Srb->SrbStatus = SRB_STATUS_BUSY;
   14.24      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   14.25 +    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (NotEnumeratedYet)\n"));
   14.26      return TRUE;
   14.27    }
   14.28  
   14.29 @@ -1208,7 +1207,7 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   14.30      break;
   14.31    }
   14.32  
   14.33 -//  KdPrint((__DRIVER_NAME " <-- HwScsiStartIo\n"));
   14.34 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   14.35  
   14.36    return TRUE;
   14.37  }