win-pvdrivers

changeset 48:a70cbf588756

scsiport updates all working now
author James Harper <james.harper@bendigoit.com.au>
date Sat Dec 15 15:42:55 2007 +1100 (2007-12-15)
parents d87e19a1eeeb
children 4f37f90fc704
files common/include/evtchn_public.h common/include/gnttbl_public.h common/include/xen_public.h common/include/xenbus_public.h dirs xenpci/evtchn.c xenpci/sources xenpci/xenbus.c xenpci/xenpci.c xenvbd/sources xenvbd/xenvbd.c xenvbd/xenvbd.h
line diff
     1.1 --- a/common/include/evtchn_public.h	Mon Dec 10 16:51:00 2007 +1100
     1.2 +++ b/common/include/evtchn_public.h	Sat Dec 15 15:42:55 2007 +1100
     1.3 @@ -17,6 +17,9 @@ along with this program; if not, write t
     1.4  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     1.5  */
     1.6  
     1.7 +#if !defined(_EVTCHN_PUBLIC_H_)
     1.8 +#define _EVTCHN_PUBLIC_H_
     1.9 +
    1.10  DEFINE_GUID( GUID_XEN_IFACE_EVTCHN, 0xD2D20756, 0xDE69, 0x4447, 0x8A, 0x7D, 0x98, 0x37, 0x19, 0x7D, 0x61, 0x66);
    1.11  //{D2D20756-DE69-4447-8A7D-9837197D6166}
    1.12  
    1.13 @@ -49,3 +52,5 @@ typedef struct _XENBUS_IFACE_EVTCHN {
    1.14    PXEN_EVTCHN_ALLOCUNBOUND AllocUnbound;
    1.15  
    1.16  } XEN_IFACE_EVTCHN, *PXEN_IFACE_EVTCHN;
    1.17 +
    1.18 +#endif
    1.19 \ No newline at end of file
     2.1 --- a/common/include/gnttbl_public.h	Mon Dec 10 16:51:00 2007 +1100
     2.2 +++ b/common/include/gnttbl_public.h	Sat Dec 15 15:42:55 2007 +1100
     2.3 @@ -17,6 +17,9 @@ along with this program; if not, write t
     2.4  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     2.5  */
     2.6  
     2.7 +#if !defined(_GNTTBL_PUBLIC_H_)
     2.8 +#define _GNTTBL_PUBLIC_H_
     2.9 +
    2.10  // {6A71ACF8-0F6D-4022-BA60-19986EBEEA73}
    2.11  DEFINE_GUID(GUID_XEN_IFACE_GNTTBL, 0x6a71acf8, 0xf6d, 0x4022, 0xba, 0x60, 0x19, 0x98, 0x6e, 0xbe, 0xea, 0x73);
    2.12  
    2.13 @@ -31,3 +34,5 @@ typedef struct _XEN_IFACE_GNTTBL {
    2.14    PXEN_GNTTBL_GRANTACCESS GrantAccess;
    2.15    PXEN_GNTTBL_ENDACCESS EndAccess;
    2.16  } XEN_IFACE_GNTTBL, *PXEN_IFACE_GNTTBL;
    2.17 +
    2.18 +#endif
    2.19 \ No newline at end of file
     3.1 --- a/common/include/xen_public.h	Mon Dec 10 16:51:00 2007 +1100
     3.2 +++ b/common/include/xen_public.h	Sat Dec 15 15:42:55 2007 +1100
     3.3 @@ -1,6 +1,10 @@
     3.4  #if !defined(_XEN_PUBLIC_H_)
     3.5  #define _XEN_PUBLIC_H_
     3.6  
     3.7 +#include <evtchn_public.h>
     3.8 +#include <xenbus_public.h>
     3.9 +#include <gnttbl_public.h>
    3.10 +
    3.11  DEFINE_GUID( GUID_XEN_IFACE_XEN, 0x5C568AC5, 0x9DDF, 0x4FA5, 0xA9, 0x4A, 0x39, 0xD6, 0x70, 0x77, 0x81, 0x9C);
    3.12  //{5C568AC5-9DDF-4FA5-A94A-39D67077819C}
    3.13  
    3.14 @@ -18,10 +22,20 @@ typedef struct _XEN_IFACE_XEN {
    3.15  
    3.16  } XEN_IFACE_XEN, *PXEN_IFACE_XEN;
    3.17  
    3.18 +#define XEN_DATA_MAGIC 0x12345678
    3.19  
    3.20  typedef struct {
    3.21 +  ULONG Magic;
    3.22    char BasePath[128];
    3.23    PXENBUS_WATCH_CALLBACK WatchHandler;
    3.24 +  PVOID WatchContext;
    3.25 +  XEN_IFACE_EVTCHN EvtChnInterface;
    3.26 +  XEN_IFACE_XENBUS XenBusInterface;
    3.27 +  //XEN_IFACE_XEN XenInterface;
    3.28 +  XEN_IFACE_GNTTBL GntTblInterface;
    3.29 +  BOOLEAN AutoEnumerate;
    3.30 +  CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptRaw;
    3.31 +  CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptTranslated;
    3.32  } XENPCI_XEN_DEVICE_DATA, *PXENPCI_XEN_DEVICE_DATA;
    3.33  
    3.34  WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_XEN_DEVICE_DATA, GetXenDeviceData);
     4.1 --- a/common/include/xenbus_public.h	Mon Dec 10 16:51:00 2007 +1100
     4.2 +++ b/common/include/xenbus_public.h	Sat Dec 15 15:42:55 2007 +1100
     4.3 @@ -17,6 +17,9 @@ along with this program; if not, write t
     4.4  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     4.5  */
     4.6  
     4.7 +#if !defined(_XENBUS_PUBLIC_H_)
     4.8 +#define _XENBUS_PUBLIC_H_
     4.9 +
    4.10  DEFINE_GUID( GUID_XEN_IFACE_XENBUS, 0x9CA4D816, 0x0E5E, 0x4f9a, 0x8F, 0x59, 0x94, 0x4C, 0xED, 0x82, 0x78, 0x11);
    4.11  //{9CA4D816-0E5E-4f9a-8F59-944CED827811}
    4.12  
    4.13 @@ -52,3 +55,5 @@ typedef struct _XEN_IFACE_XENBUS {
    4.14    PXEN_XENBUS_ADDWATCH AddWatch;
    4.15    PXEN_XENBUS_REMWATCH RemWatch;
    4.16  } XEN_IFACE_XENBUS, *PXEN_IFACE_XENBUS;
    4.17 +
    4.18 +#endif
    4.19 \ No newline at end of file
     5.1 --- a/dirs	Mon Dec 10 16:51:00 2007 +1100
     5.2 +++ b/dirs	Sat Dec 15 15:42:55 2007 +1100
     5.3 @@ -1,1 +1,1 @@
     5.4 -DIRS=xenpci xenhide xenvbd
     5.5 \ No newline at end of file
     5.6 +DIRS=xenpci xenhide xenvbd xenaddresource
     5.7 \ No newline at end of file
     6.1 --- a/xenpci/evtchn.c	Mon Dec 10 16:51:00 2007 +1100
     6.2 +++ b/xenpci/evtchn.c	Sat Dec 15 15:42:55 2007 +1100
     6.3 @@ -79,7 +79,8 @@ EvtChn_Interrupt(WDFINTERRUPT Interrupt,
     6.4  
     6.5    //KdPrint((__DRIVER_NAME "     I-\n"));
     6.6  
     6.7 -  return TRUE;
     6.8 +//  return TRUE;
     6.9 +  return FALSE;
    6.10  }
    6.11  
    6.12  evtchn_port_t
    6.13 @@ -102,7 +103,7 @@ EvtChn_AllocUnbound(domid_t Domain)
    6.14  NTSTATUS
    6.15  EvtChn_Bind(evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
    6.16  {
    6.17 -  KdPrint((__DRIVER_NAME " --> EvtChn_Bind\n"));
    6.18 +  KdPrint((__DRIVER_NAME " --> EvtChn_Bind (ServiceRoutine = %08X, ServiceContext = %08x)\n", ServiceRoutine, ServiceContext));
    6.19  
    6.20    if(ev_actions[Port].ServiceRoutine != NULL)
    6.21    {
     7.1 --- a/xenpci/sources	Mon Dec 10 16:51:00 2007 +1100
     7.2 +++ b/xenpci/sources	Sat Dec 15 15:42:55 2007 +1100
     7.3 @@ -1,7 +1,7 @@
     7.4  TARGETNAME=XENPCI
     7.5  TARGETTYPE=DRIVER
     7.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     7.7 -VERSION=0.4.0.0
     7.8 +VERSION=0.4.0.12
     7.9  KMDF_VERSION=1
    7.10  MSC_WARNING_LEVEL=/W4
    7.11  INF_NAME=xenpci
     8.1 --- a/xenpci/xenbus.c	Mon Dec 10 16:51:00 2007 +1100
     8.2 +++ b/xenpci/xenbus.c	Sat Dec 15 15:42:55 2007 +1100
     8.3 @@ -433,15 +433,25 @@ XenBus_Close()
     8.4    KdPrint((__DRIVER_NAME "     Waiting for threads to die\n"));
     8.5    ObReferenceObjectByHandle(XenBus_ReadThreadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, &WaitArray[0], NULL);
     8.6    ObReferenceObjectByHandle(XenBus_WatchThreadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, &WaitArray[1], NULL);
     8.7 -  KeWaitForMultipleObjects(2, WaitArray, WaitAll, Executive, KernelMode, FALSE, NULL, WaitBlockArray);
     8.8 +  //KeWaitForMultipleObjects(1, &WaitArray[0], WaitAny, Executive, KernelMode, FALSE, NULL, WaitBlockArray);
     8.9 +  KdPrint((__DRIVER_NAME "     Waiting for ReadThread\n"));
    8.10 +  KeWaitForSingleObject(WaitArray[0], Executive, KernelMode, FALSE, NULL);
    8.11 +  KdPrint((__DRIVER_NAME "     Waiting for WatchThread\n"));
    8.12 +  //KeWaitForMultipleObjects(1, &WaitArray[1], WaitAny, Executive, KernelMode, FALSE, NULL, WaitBlockArray);
    8.13 +  KeWaitForSingleObject(WaitArray[1], Executive, KernelMode, FALSE, NULL);
    8.14    KdPrint((__DRIVER_NAME "     Threads are dead\n"));
    8.15  
    8.16    XenBus_ShuttingDown = FALSE;
    8.17  
    8.18 -  ObDereferenceObject(WaitArray[0]);
    8.19 -  ObDereferenceObject(WaitArray[1]);
    8.20 +//  ObDereferenceObject(WaitArray[0]);
    8.21 +//  ObDereferenceObject(WaitArray[1]);
    8.22 +
    8.23 +  KdPrint((__DRIVER_NAME "     A\n"));
    8.24  
    8.25    ZwClose(XenBus_WatchThreadHandle);
    8.26 +
    8.27 +  KdPrint((__DRIVER_NAME "     B\n"));
    8.28 +
    8.29    ZwClose(XenBus_ReadThreadHandle);
    8.30  
    8.31    KdPrint((__DRIVER_NAME " <-- XenBus_Close\n"));
     9.1 --- a/xenpci/xenpci.c	Mon Dec 10 16:51:00 2007 +1100
     9.2 +++ b/xenpci/xenpci.c	Sat Dec 15 15:42:55 2007 +1100
     9.3 @@ -75,6 +75,9 @@ static BOOLEAN AutoEnumerate;
     9.4  
     9.5  static WDFDEVICE Device;
     9.6  
     9.7 +CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptRaw;
     9.8 +CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptTranslated;
     9.9 +
    9.10  NTSTATUS
    9.11  DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
    9.12  {
    9.13 @@ -310,10 +313,10 @@ XenPCI_AddDevice(
    9.14  {
    9.15    NTSTATUS status;
    9.16    WDF_CHILD_LIST_CONFIG config;
    9.17 -  PXENPCI_DEVICE_DATA devData = NULL;
    9.18 +  //PXENPCI_DEVICE_DATA devData = NULL;
    9.19    WDF_OBJECT_ATTRIBUTES attributes;
    9.20    WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
    9.21 -  WDF_IO_QUEUE_CONFIG ioQConfig;
    9.22 +  //WDF_IO_QUEUE_CONFIG ioQConfig;
    9.23    WDF_INTERRUPT_CONFIG interruptConfig;
    9.24    PNP_BUS_INFORMATION busInfo;
    9.25    BUS_INTERFACE_STANDARD BusInterface;
    9.26 @@ -376,35 +379,11 @@ XenPCI_AddDevice(
    9.27  
    9.28    
    9.29    busInfo.BusTypeGuid = GUID_XENPCI_DEVCLASS;
    9.30 -  busInfo.LegacyBusType = PNPBus;
    9.31 +  busInfo.LegacyBusType = Internal; //PNPBus;
    9.32    busInfo.BusNumber = 0;
    9.33  
    9.34    WdfDeviceSetBusInformationForChildren(Device, &busInfo);
    9.35  
    9.36 -  /*create the default IO queue. this one will 
    9.37 -  be used for all requests*/
    9.38 -/*
    9.39 -  WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQConfig,
    9.40 -                                WdfIoQueueDispatchSequential);
    9.41 -  ioQConfig.EvtIoDefault = XenPCI_IoDefault;
    9.42 -  status = WdfIoQueueCreate(Device, &ioQConfig,
    9.43 -                            WDF_NO_OBJECT_ATTRIBUTES,
    9.44 -                            &devData->IoDefaultQueue);
    9.45 -  if(!NT_SUCCESS(status))
    9.46 -  {
    9.47 -    KdPrint((__DRIVER_NAME "     WdfIoQueueCreate failed with status 0x%08x\n", status));
    9.48 -    return status;
    9.49 -  }
    9.50 -*/
    9.51 -/*
    9.52 -  status = WdfDeviceCreateDeviceInterface(Device, &GUID_INTERFACE_XENPCI, NULL);
    9.53 -  if(!NT_SUCCESS(status))
    9.54 -  {
    9.55 -    KdPrint((__DRIVER_NAME "WdfDeviceCreateDeviceInterface failed with status 0x%08x\n", status));
    9.56 -    return status;
    9.57 -  }
    9.58 -*/
    9.59 -
    9.60    WDF_INTERRUPT_CONFIG_INIT(&interruptConfig, EvtChn_Interrupt, NULL); //EvtChn_InterruptDpc);
    9.61    interruptConfig.EvtInterruptEnable = XenPCI_InterruptEnable;
    9.62    interruptConfig.EvtInterruptDisable = XenPCI_InterruptDisable;
    9.63 @@ -460,8 +439,6 @@ XenPCI_PrepareHardware(
    9.64      switch (descriptor->Type) {
    9.65      case CmResourceTypePort:
    9.66        //KdPrint((__DRIVER_NAME "     I/O mapped CSR: (%x) Length: (%d)\n", descriptor->u.Port.Start.LowPart, descriptor->u.Port.Length));
    9.67 -//      deviceData->IoBaseAddress = ULongToPtr(descriptor->u.Port.Start.LowPart);
    9.68 -//      deviceData->IoRange = descriptor->u.Port.Length;
    9.69        break;
    9.70      case CmResourceTypeMemory:
    9.71        KdPrint((__DRIVER_NAME "     Memory mapped CSR:(%x:%x) Length:(%d)\n", descriptor->u.Memory.Start.LowPart, descriptor->u.Memory.Start.HighPart, descriptor->u.Memory.Length));
    9.72 @@ -471,6 +448,8 @@ XenPCI_PrepareHardware(
    9.73        break;
    9.74      case CmResourceTypeInterrupt:
    9.75        //KdPrint((__DRIVER_NAME "     Interrupt level: 0x%0x, Vector: 0x%0x\n", descriptor->u.Interrupt.Level, descriptor->u.Interrupt.Vector));
    9.76 +      memcpy(&InterruptRaw, WdfCmResourceListGetDescriptor(ResourceList, i), sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
    9.77 +      memcpy(&InterruptTranslated, WdfCmResourceListGetDescriptor(ResourceListTranslated, i), sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
    9.78        break;
    9.79      case CmResourceTypeDevicePrivate:
    9.80        //KdPrint((__DRIVER_NAME "     Private Data: 0x%02x 0x%02x 0x%02x\n", descriptor->u.DevicePrivate.Data[0], descriptor->u.DevicePrivate.Data[1], descriptor->u.DevicePrivate.Data[2] ));
    9.81 @@ -695,11 +674,6 @@ XenPCI_ChildListCreateDevice(WDFCHILDLIS
    9.82    NTSTATUS status;
    9.83    WDFDEVICE ChildDevice = NULL;
    9.84    PXENPCI_IDENTIFICATION_DESCRIPTION XenIdentificationDesc;
    9.85 -  XEN_IFACE_EVTCHN EvtChnInterface;
    9.86 -  XEN_IFACE_XENBUS XenBusInterface;
    9.87 -  XEN_IFACE_XEN XenInterface;
    9.88 -  XEN_IFACE_GNTTBL GntTblInterface;
    9.89 -  //UNICODE_STRING DeviceId;
    9.90    DECLARE_UNICODE_STRING_SIZE(buffer, 20);
    9.91    WDF_OBJECT_ATTRIBUTES PdoAttributes;
    9.92    DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
    9.93 @@ -749,70 +723,73 @@ XenPCI_ChildListCreateDevice(WDFCHILDLIS
    9.94    WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileDump, TRUE);
    9.95  
    9.96    ChildDeviceData = GetXenDeviceData(ChildDevice);
    9.97 +  ChildDeviceData->Magic = XEN_DATA_MAGIC;
    9.98 +  ChildDeviceData->AutoEnumerate = AutoEnumerate;
    9.99 +  ChildDeviceData->WatchHandler = NULL;
   9.100    strncpy(ChildDeviceData->BasePath, XenIdentificationDesc->Path, 128);
   9.101 +
   9.102 +  memcpy(&ChildDeviceData->InterruptRaw, &InterruptRaw, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
   9.103 +  memcpy(&ChildDeviceData->InterruptTranslated, &InterruptTranslated, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
   9.104    
   9.105 -  RtlZeroMemory(&EvtChnInterface, sizeof(EvtChnInterface));
   9.106 -  EvtChnInterface.InterfaceHeader.Size = sizeof(EvtChnInterface);
   9.107 -  EvtChnInterface.InterfaceHeader.Version = 1;
   9.108 -  EvtChnInterface.InterfaceHeader.Context = NULL;
   9.109 -  EvtChnInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
   9.110 -  EvtChnInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
   9.111 -  EvtChnInterface.Bind = EvtChn_Bind;
   9.112 -  EvtChnInterface.Unbind = EvtChn_Unbind;
   9.113 -  EvtChnInterface.Mask = EvtChn_Mask;
   9.114 -  EvtChnInterface.Unmask = EvtChn_Unmask;
   9.115 -  EvtChnInterface.Notify = EvtChn_Notify;
   9.116 -  EvtChnInterface.AllocUnbound = EvtChn_AllocUnbound;
   9.117 -  WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&EvtChnInterface, &GUID_XEN_IFACE_EVTCHN, NULL);
   9.118 +  ChildDeviceData->EvtChnInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->EvtChnInterface);
   9.119 +  ChildDeviceData->EvtChnInterface.InterfaceHeader.Version = 1;
   9.120 +  ChildDeviceData->EvtChnInterface.InterfaceHeader.Context = NULL;
   9.121 +  ChildDeviceData->EvtChnInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
   9.122 +  ChildDeviceData->EvtChnInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
   9.123 +  ChildDeviceData->EvtChnInterface.Bind = EvtChn_Bind;
   9.124 +  ChildDeviceData->EvtChnInterface.Unbind = EvtChn_Unbind;
   9.125 +  ChildDeviceData->EvtChnInterface.Mask = EvtChn_Mask;
   9.126 +  ChildDeviceData->EvtChnInterface.Unmask = EvtChn_Unmask;
   9.127 +  ChildDeviceData->EvtChnInterface.Notify = EvtChn_Notify;
   9.128 +  ChildDeviceData->EvtChnInterface.AllocUnbound = EvtChn_AllocUnbound;
   9.129 +  WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->EvtChnInterface, &GUID_XEN_IFACE_EVTCHN, NULL);
   9.130    status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
   9.131    if (!NT_SUCCESS(status))
   9.132    {
   9.133      return status;
   9.134    }
   9.135  
   9.136 -  RtlZeroMemory(&XenInterface, sizeof(XenInterface));
   9.137 -  XenInterface.InterfaceHeader.Size = sizeof(XenInterface);
   9.138 -  XenInterface.InterfaceHeader.Version = 1;
   9.139 -  XenInterface.InterfaceHeader.Context = NULL;
   9.140 -  XenInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
   9.141 -  XenInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
   9.142 -  XenInterface.AllocMMIO = XenPCI_AllocMMIO;
   9.143 -  WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&XenInterface, &GUID_XEN_IFACE_XEN, NULL);
   9.144 +/*
   9.145 +  ChildDeviceData->XenInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->XenInterface);
   9.146 +  ChildDeviceData->XenInterface.InterfaceHeader.Version = 1;
   9.147 +  ChildDeviceData->XenInterface.InterfaceHeader.Context = NULL;
   9.148 +  ChildDeviceData->XenInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
   9.149 +  ChildDeviceData->XenInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
   9.150 +  ChildDeviceData->XenInterface.AllocMMIO = XenPCI_AllocMMIO;
   9.151 +  WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->XenInterface, &GUID_XEN_IFACE_XEN, NULL);
   9.152 +  status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
   9.153 +  if (!NT_SUCCESS(status)) {
   9.154 +    return status;
   9.155 +  }
   9.156 +*/
   9.157 +
   9.158 +  ChildDeviceData->GntTblInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->GntTblInterface);
   9.159 +  ChildDeviceData->GntTblInterface.InterfaceHeader.Version = 1;
   9.160 +  ChildDeviceData->GntTblInterface.InterfaceHeader.Context = NULL;
   9.161 +  ChildDeviceData->GntTblInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
   9.162 +  ChildDeviceData->GntTblInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
   9.163 +  ChildDeviceData->GntTblInterface.GrantAccess = GntTbl_GrantAccess;
   9.164 +  ChildDeviceData->GntTblInterface.EndAccess = GntTbl_EndAccess;
   9.165 +  WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->GntTblInterface, &GUID_XEN_IFACE_GNTTBL, NULL);
   9.166    status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
   9.167    if (!NT_SUCCESS(status)) {
   9.168      return status;
   9.169    }
   9.170  
   9.171 -  RtlZeroMemory(&GntTblInterface, sizeof(GntTblInterface));
   9.172 -  GntTblInterface.InterfaceHeader.Size = sizeof(GntTblInterface);
   9.173 -  GntTblInterface.InterfaceHeader.Version = 1;
   9.174 -  GntTblInterface.InterfaceHeader.Context = NULL;
   9.175 -  GntTblInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
   9.176 -  GntTblInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
   9.177 -  GntTblInterface.GrantAccess = GntTbl_GrantAccess;
   9.178 -  GntTblInterface.EndAccess = GntTbl_EndAccess;
   9.179 -  WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&GntTblInterface, &GUID_XEN_IFACE_GNTTBL, NULL);
   9.180 -  status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
   9.181 -  if (!NT_SUCCESS(status)) {
   9.182 -    return status;
   9.183 -  }
   9.184 -
   9.185 -  RtlZeroMemory(&XenBusInterface, sizeof(XenBusInterface));
   9.186 -
   9.187 -  XenBusInterface.InterfaceHeader.Size = sizeof(XenBusInterface);
   9.188 -  XenBusInterface.InterfaceHeader.Version = 1;
   9.189 -  XenBusInterface.InterfaceHeader.Context = NULL;
   9.190 +  ChildDeviceData->XenBusInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->XenBusInterface);
   9.191 +  ChildDeviceData->XenBusInterface.InterfaceHeader.Version = 1;
   9.192 +  ChildDeviceData->XenBusInterface.InterfaceHeader.Context = NULL;
   9.193    //XenBusInterface.InterfaceHeader.Context = ExAllocatePoolWithTag(NonPagedPool, (strlen(XenIdentificationDesc->Path) + 1), XENPCI_POOL_TAG);
   9.194    //strcpy(XenBusInterface.InterfaceHeader.Context, XenIdentificationDesc->Path);
   9.195 -  XenBusInterface.Read = XenBus_Read;
   9.196 -  XenBusInterface.Write = XenBus_Write;
   9.197 -  XenBusInterface.Printf = XenBus_Printf;
   9.198 -  XenBusInterface.StartTransaction = XenBus_StartTransaction;
   9.199 -  XenBusInterface.EndTransaction = XenBus_EndTransaction;
   9.200 -  XenBusInterface.List = XenBus_List;
   9.201 -  XenBusInterface.AddWatch = XenBus_AddWatch;
   9.202 -  XenBusInterface.RemWatch = XenBus_RemWatch;
   9.203 -  WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&XenBusInterface, &GUID_XEN_IFACE_XENBUS, NULL);
   9.204 +  ChildDeviceData->XenBusInterface.Read = XenBus_Read;
   9.205 +  ChildDeviceData->XenBusInterface.Write = XenBus_Write;
   9.206 +  ChildDeviceData->XenBusInterface.Printf = XenBus_Printf;
   9.207 +  ChildDeviceData->XenBusInterface.StartTransaction = XenBus_StartTransaction;
   9.208 +  ChildDeviceData->XenBusInterface.EndTransaction = XenBus_EndTransaction;
   9.209 +  ChildDeviceData->XenBusInterface.List = XenBus_List;
   9.210 +  ChildDeviceData->XenBusInterface.AddWatch = XenBus_AddWatch;
   9.211 +  ChildDeviceData->XenBusInterface.RemWatch = XenBus_RemWatch;
   9.212 +  WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->XenBusInterface, &GUID_XEN_IFACE_XENBUS, NULL);
   9.213    status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
   9.214    if (!NT_SUCCESS(status)) {
   9.215      return status;
   9.216 @@ -872,7 +849,7 @@ XenPCI_XenBusWatchHandler(char *Path, PV
   9.217          {
   9.218            //KdPrint((__DRIVER_NAME "     Child Path = %s (Match - WatchHandler = %08x)\n", ChildDeviceData->BasePath, ChildDeviceData->WatchHandler));
   9.219            if (ChildDeviceData->WatchHandler != NULL)
   9.220 -            ChildDeviceData->WatchHandler(Path, NULL);
   9.221 +            ChildDeviceData->WatchHandler(Path, ChildDeviceData->WatchContext);
   9.222          }
   9.223          else
   9.224          {
    10.1 --- a/xenvbd/sources	Mon Dec 10 16:51:00 2007 +1100
    10.2 +++ b/xenvbd/sources	Sat Dec 15 15:42:55 2007 +1100
    10.3 @@ -1,7 +1,7 @@
    10.4  TARGETNAME=XENVBD
    10.5  TARGETTYPE=DRIVER
    10.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
    10.7 -VERSION=0.4.0.20
    10.8 +VERSION=0.4.0.117
    10.9  KMDF_VERSION=1
   10.10  MSC_WARNING_LEVEL=/W4
   10.11  INF_NAME=xenvbd
    11.1 --- a/xenvbd/xenvbd.c	Mon Dec 10 16:51:00 2007 +1100
    11.2 +++ b/xenvbd/xenvbd.c	Sat Dec 15 15:42:55 2007 +1100
    11.3 @@ -1,472 +1,102 @@
    11.4  #include "xenvbd.h"
    11.5  #include <io/blkif.h>
    11.6 -#include <srb.h>
    11.7  #include <scsi.h>
    11.8  #include <ntddscsi.h>
    11.9  #include <ntdddisk.h>
   11.10  #include <stdlib.h>
   11.11  #include <xen_public.h>
   11.12 -#include <gnttbl_public.h>
   11.13  #include <io/xenbus.h>
   11.14 -#include <ntddft.h>
   11.15  
   11.16  #define wmb() KeMemoryBarrier()
   11.17  #define mb() KeMemoryBarrier()
   11.18  
   11.19 +#define BUF_PAGES_PER_SRB 11
   11.20 +
   11.21  DRIVER_INITIALIZE DriverEntry;
   11.22  
   11.23 -static NTSTATUS
   11.24 -XenVbd_AddDevice(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit);
   11.25 -static NTSTATUS
   11.26 -XenVbd_PrepareHardware(WDFDEVICE hDevice, WDFCMRESLIST Resources, WDFCMRESLIST ResourcesTranslated);
   11.27 -static NTSTATUS
   11.28 -XenVbd_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated);
   11.29 -static NTSTATUS
   11.30 -XenVbd_D0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
   11.31 -static NTSTATUS
   11.32 -XenVbd_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
   11.33 -static NTSTATUS
   11.34 -XenVbd_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState);
   11.35 -static NTSTATUS
   11.36 -XenVbd_DeviceUsageNotification(WDFDEVICE Device, WDF_SPECIAL_FILE_TYPE NotificationType, BOOLEAN IsInNotificationPath);
   11.37 +static ULONG
   11.38 +XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again);
   11.39 +static BOOLEAN
   11.40 +XenVbd_HwScsiInitialize(PVOID DeviceExtension);
   11.41 +static BOOLEAN
   11.42 +XenVbd_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb);
   11.43 +static BOOLEAN
   11.44 +XenVbd_HwScsiInterrupt(PVOID DeviceExtension);
   11.45 +static BOOLEAN
   11.46 +XenVbd_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId);
   11.47 +static BOOLEAN
   11.48 +XenVbd_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState);
   11.49 +static SCSI_ADAPTER_CONTROL_STATUS
   11.50 +XenVbd_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters);
   11.51  
   11.52 -static VOID
   11.53 -XenVbd_IoDefault(WDFQUEUE Queue, WDFREQUEST Request);
   11.54 -static VOID
   11.55 -XenVbd_IoRead(WDFQUEUE Queue, WDFREQUEST Request, size_t  Length);
   11.56 -static VOID
   11.57 -XenVbd_IoWrite(WDFQUEUE Queue, WDFREQUEST Request, size_t  Length);
   11.58 -static VOID
   11.59 -XenVbd_IoDeviceControl(WDFQUEUE Queue, WDFREQUEST Request, IN size_t  OutputBufferLength, size_t  InputBufferLength, ULONG IoControlCode);
   11.60 -
   11.61 -static NTSTATUS
   11.62 -XenVbd_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit);
   11.63 -//static NTSTATUS
   11.64 -//XenVbd_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
   11.65 -static NTSTATUS
   11.66 -XenVbd_Child_PreprocessWdmIrpSCSI(WDFDEVICE Device, PIRP Irp);
   11.67 -static NTSTATUS
   11.68 -XenVbd_Child_PreprocessWdmIrpDEVICE_CONTROL(WDFDEVICE Device, PIRP Irp);
   11.69 -static NTSTATUS
   11.70 -XenVbd_Child_PreprocessWdmIrpSomethingSomething(WDFDEVICE Device, PIRP Irp);
   11.71 -
   11.72 -static VOID
   11.73 -XenVbd_HotPlugHandler(char *Path, PVOID Data);
   11.74 +//static XEN_IFACE_EVTCHN EvtChnInterface;
   11.75 +//static XEN_IFACE_XENBUS XenBusInterface;
   11.76  
   11.77  #ifdef ALLOC_PRAGMA
   11.78  #pragma alloc_text (INIT, DriverEntry)
   11.79 -#pragma alloc_text (PAGE, XenVbd_AddDevice)
   11.80  #endif
   11.81  
   11.82 -LIST_ENTRY DeviceListHead;
   11.83 -XEN_IFACE_EVTCHN EvtChnInterface;
   11.84 -XEN_IFACE_XENBUS XenBusInterface;
   11.85 -XEN_IFACE_XEN XenInterface;
   11.86 -XEN_IFACE_GNTTBL GntTblInterface;
   11.87 -
   11.88  static BOOLEAN AutoEnumerate;
   11.89  
   11.90  NTSTATUS
   11.91  DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
   11.92  {
   11.93 -  WDF_DRIVER_CONFIG config;
   11.94 -  ULONG status;
   11.95 -  UNICODE_STRING RegKeyName;
   11.96 -  UNICODE_STRING RegValueName;
   11.97 -  HANDLE RegHandle;
   11.98 -  OBJECT_ATTRIBUTES RegObjectAttributes;
   11.99 -  char Buf[200];
  11.100 -  ULONG BufLen = 200;
  11.101 -  PKEY_VALUE_PARTIAL_INFORMATION KeyPartialValue;
  11.102 -  int State = 0;
  11.103 -  int StartPos = 0;
  11.104 -  WCHAR *SystemStartOptions;
  11.105 -  size_t SystemStartOptionsLen;
  11.106 -  size_t i;
  11.107 +  ULONG Status;
  11.108 +  HW_INITIALIZATION_DATA HwInitializationData;
  11.109  
  11.110    KdPrint((__DRIVER_NAME " --> DriverEntry\n"));
  11.111  
  11.112 -  WDF_DRIVER_CONFIG_INIT(&config, XenVbd_AddDevice);
  11.113 -  status = WdfDriverCreate(
  11.114 -                      DriverObject,
  11.115 -                      RegistryPath,
  11.116 -                      WDF_NO_OBJECT_ATTRIBUTES,
  11.117 -                      &config,
  11.118 -                      WDF_NO_HANDLE);
  11.119 -  if(!NT_SUCCESS(status))
  11.120 -  {
  11.121 -    KdPrint((__DRIVER_NAME " WdfDriverCreate failed with status 0x%08x\n", status));
  11.122 -  }
  11.123 +  RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
  11.124  
  11.125 -  RtlInitUnicodeString(&RegKeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
  11.126 -  InitializeObjectAttributes(&RegObjectAttributes, &RegKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
  11.127 -  status = ZwOpenKey(&RegHandle, KEY_READ, &RegObjectAttributes);
  11.128 -  if(!NT_SUCCESS(status))
  11.129 -  {
  11.130 -    KdPrint((__DRIVER_NAME "     ZwOpenKey returned %08x\n", status));
  11.131 -  }
  11.132 +  HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
  11.133 +  HwInitializationData.AdapterInterfaceType = Internal; //PNPBus;
  11.134 +  HwInitializationData.HwInitialize = XenVbd_HwScsiInitialize;
  11.135 +  HwInitializationData.HwStartIo = XenVbd_HwScsiStartIo;
  11.136 +  HwInitializationData.HwInterrupt = XenVbd_HwScsiInterrupt;
  11.137 +  HwInitializationData.HwFindAdapter = XenVbd_HwScsiFindAdapter;
  11.138 +  HwInitializationData.HwResetBus = XenVbd_HwScsiResetBus;
  11.139 +  HwInitializationData.HwDmaStarted = NULL;
  11.140 +  HwInitializationData.HwAdapterState = NULL;
  11.141 +  HwInitializationData.DeviceExtensionSize = sizeof(XENVBD_DEVICE_DATA);
  11.142 +  HwInitializationData.SpecificLuExtensionSize = 0;
  11.143 +  HwInitializationData.SrbExtensionSize = 0;
  11.144 +  HwInitializationData.NumberOfAccessRanges = 1;
  11.145  
  11.146 -  RtlInitUnicodeString(&RegValueName, L"SystemStartOptions");
  11.147 -  status = ZwQueryValueKey(RegHandle, &RegValueName, KeyValuePartialInformation, Buf, BufLen, &BufLen);
  11.148 -  if(!NT_SUCCESS(status))
  11.149 -  {
  11.150 -    KdPrint((__DRIVER_NAME "     ZwQueryKeyValue returned %08x\n", status));
  11.151 -  }
  11.152 -  //KdPrint((__DRIVER_NAME "     BufLen = %d\n", BufLen));
  11.153 -  KeyPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
  11.154 -  KdPrint((__DRIVER_NAME "     Buf = %ws\n", KeyPartialValue->Data));
  11.155 -  SystemStartOptions = (WCHAR *)KeyPartialValue->Data;
  11.156 +  //HwInitializationData.MapBuffers = FALSE;
  11.157 +  HwInitializationData.MapBuffers = TRUE;
  11.158  
  11.159 -  AutoEnumerate = FALSE;
  11.160 +  HwInitializationData.NeedPhysicalAddresses = FALSE;
  11.161 +//  HwInitializationData.NeedPhysicalAddresses = TRUE;
  11.162  
  11.163 -  RtlStringCbLengthW(SystemStartOptions, KeyPartialValue->DataLength, &SystemStartOptionsLen);
  11.164 +  HwInitializationData.TaggedQueuing = TRUE; //FALSE;
  11.165 +  HwInitializationData.AutoRequestSense = FALSE;
  11.166 +  HwInitializationData.MultipleRequestPerLu = FALSE;
  11.167 +  HwInitializationData.ReceiveEvent = FALSE; // check this
  11.168 +  HwInitializationData.VendorIdLength = 0;
  11.169 +  HwInitializationData.VendorId = NULL;
  11.170 +  HwInitializationData.DeviceIdLength = 0;
  11.171 +  HwInitializationData.DeviceId = NULL;
  11.172 +  HwInitializationData.HwAdapterControl = XenVbd_HwScsiAdapterControl;
  11.173  
  11.174 -  for (i = 0; i <= SystemStartOptionsLen/2; i++)
  11.175 +  Status = ScsiPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
  11.176 +
  11.177 +  if(!NT_SUCCESS(Status))
  11.178    {
  11.179 -    //KdPrint((__DRIVER_NAME "     pos = %d, state = %d, char = '%wc' (%d)\n", i, State, SystemStartOptions[i], SystemStartOptions[i]));
  11.180 -    
  11.181 -    switch (State)
  11.182 -    {
  11.183 -    case 0:
  11.184 -      if (SystemStartOptions[i] == L'G')
  11.185 -      {
  11.186 -        StartPos = i;
  11.187 -        State = 2;
  11.188 -      } else if (SystemStartOptions[i] != L' ')
  11.189 -      {
  11.190 -        State = 1;
  11.191 -      }
  11.192 -      break;
  11.193 -    case 1:
  11.194 -      if (SystemStartOptions[i] == L' ')
  11.195 -        State = 0;
  11.196 -      break;
  11.197 -    case 2:
  11.198 -      if (SystemStartOptions[i] == L'P')
  11.199 -        State = 3;
  11.200 -      else
  11.201 -        State = 0;
  11.202 -      break;
  11.203 -    case 3:
  11.204 -      if (SystemStartOptions[i] == L'L')
  11.205 -        State = 4;
  11.206 -      else
  11.207 -        State = 0;
  11.208 -      break;
  11.209 -    case 4:
  11.210 -      if (SystemStartOptions[i] == L'P')
  11.211 -        State = 5;
  11.212 -      else
  11.213 -        State = 0;
  11.214 -      break;
  11.215 -    case 5:
  11.216 -      if (SystemStartOptions[i] == L'V')
  11.217 -        State = 6;
  11.218 -      else
  11.219 -        State = 0;
  11.220 -      break;
  11.221 -    case 6:
  11.222 -      if (SystemStartOptions[i] == L' ' || SystemStartOptions[i] == 0)
  11.223 -        AutoEnumerate = TRUE;
  11.224 -      State = 0;
  11.225 -      break;
  11.226 -    }
  11.227 +    KdPrint((__DRIVER_NAME " ScsiPortInitialize failed with status 0x%08x\n", Status));
  11.228    }
  11.229  
  11.230 -  KdPrint((__DRIVER_NAME "     AutoEnumerate = %d\n", AutoEnumerate));
  11.231 -
  11.232    KdPrint((__DRIVER_NAME " <-- DriverEntry\n"));
  11.233  
  11.234 -  return status;
  11.235 -}
  11.236 -
  11.237 -static WDFDEVICE GlobalDevice;
  11.238 -static PDEVICE_OBJECT Pdo;
  11.239 -
  11.240 -static NTSTATUS
  11.241 -XenVbd_AddDevice(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit)
  11.242 -{
  11.243 -  WDF_CHILD_LIST_CONFIG ChildListConfig;
  11.244 -  NTSTATUS status;
  11.245 -  WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
  11.246 -
  11.247 -  UNREFERENCED_PARAMETER(Driver);
  11.248 -
  11.249 -  KdPrint((__DRIVER_NAME " --> DeviceAdd\n"));
  11.250 -
  11.251 -  Pdo = WdfFdoInitWdmGetPhysicalDevice(DeviceInit);
  11.252 -
  11.253 -  //WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
  11.254 -  WDF_CHILD_LIST_CONFIG_INIT(&ChildListConfig, sizeof(XENVBD_DEVICE_IDENTIFICATION_DESCRIPTION), XenVbd_ChildListCreateDevice);
  11.255 -  WdfFdoInitSetDefaultChildListConfig(DeviceInit, &ChildListConfig, WDF_NO_OBJECT_ATTRIBUTES);
  11.256 -
  11.257 -  WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_CONTROLLER);
  11.258 -  //WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);
  11.259 -  WdfDeviceInitSetExclusive(DeviceInit, FALSE);
  11.260 -  
  11.261 -  WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
  11.262 -  pnpPowerCallbacks.EvtDevicePrepareHardware = XenVbd_PrepareHardware;
  11.263 -  pnpPowerCallbacks.EvtDeviceReleaseHardware = XenVbd_ReleaseHardware;
  11.264 -  pnpPowerCallbacks.EvtDeviceD0Entry = XenVbd_D0Entry;
  11.265 -  pnpPowerCallbacks.EvtDeviceD0EntryPostInterruptsEnabled = XenVbd_D0EntryPostInterruptsEnabled;
  11.266 -  pnpPowerCallbacks.EvtDeviceD0Exit = XenVbd_D0Exit;
  11.267 -  pnpPowerCallbacks.EvtDeviceUsageNotification = XenVbd_DeviceUsageNotification;
  11.268 -  WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
  11.269 -
  11.270 -  /*initialize storage for the device context*/
  11.271 -  //WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, XENVBD_DEVICE_DATA);
  11.272 -
  11.273 -  //WdfDeviceInitSetPowerNotPageable(DeviceInit);
  11.274 -
  11.275 -  /*create a device instance.*/
  11.276 -  status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &GlobalDevice);  
  11.277 -  if(!NT_SUCCESS(status))
  11.278 -  {
  11.279 -    KdPrint((__DRIVER_NAME "WdfDeviceCreate failed with status 0x%08x\n", status));
  11.280 -    return status;
  11.281 -  }
  11.282 -
  11.283 -  WdfDeviceSetSpecialFileSupport(GlobalDevice, WdfSpecialFilePaging, TRUE);
  11.284 -  WdfDeviceSetSpecialFileSupport(GlobalDevice, WdfSpecialFileHibernation, TRUE);
  11.285 -  WdfDeviceSetSpecialFileSupport(GlobalDevice, WdfSpecialFileDump, TRUE);
  11.286 -  
  11.287 -  status = STATUS_SUCCESS;
  11.288 -
  11.289 -  KdPrint((__DRIVER_NAME " <-- DeviceAdd\n"));
  11.290 -  return status;
  11.291 -}
  11.292 -
  11.293 -static NTSTATUS
  11.294 -XenVbd_PrepareHardware(
  11.295 -  IN WDFDEVICE    Device,
  11.296 -  IN WDFCMRESLIST ResourceList,
  11.297 -  IN WDFCMRESLIST ResourceListTranslated)
  11.298 -{
  11.299 -  NTSTATUS status = STATUS_SUCCESS;
  11.300 -
  11.301 -  UNREFERENCED_PARAMETER(ResourceList);
  11.302 -  UNREFERENCED_PARAMETER(ResourceListTranslated);
  11.303 -
  11.304 -  //KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware\n"));
  11.305 -
  11.306 -  status = WdfFdoQueryForInterface(Device, &GUID_XEN_IFACE_EVTCHN, (PINTERFACE) &EvtChnInterface, sizeof(XEN_IFACE_EVTCHN), 1, NULL);
  11.307 -  if(!NT_SUCCESS(status))
  11.308 -  {
  11.309 -    KdPrint((__DRIVER_NAME "     WdfFdoQueryForInterface (EvtChn) failed with status 0x%08x\n", status));
  11.310 -  }
  11.311 -
  11.312 -  status = WdfFdoQueryForInterface(Device, &GUID_XEN_IFACE_XENBUS, (PINTERFACE)&XenBusInterface, sizeof(XEN_IFACE_XENBUS), 1, NULL);
  11.313 -  if(!NT_SUCCESS(status))
  11.314 -  {
  11.315 -    KdPrint((__DRIVER_NAME "     WdfFdoQueryForInterface (XenBus) failed with status 0x%08x\n", status));
  11.316 -  }
  11.317 -
  11.318 -  status = WdfFdoQueryForInterface(Device, &GUID_XEN_IFACE_XEN, (PINTERFACE)&XenInterface, sizeof(XEN_IFACE_XEN), 1, NULL);
  11.319 -  if(!NT_SUCCESS(status))
  11.320 -  {
  11.321 -    KdPrint((__DRIVER_NAME "     WdfFdoQueryForInterface (Xen) failed with status 0x%08x\n", status));
  11.322 -  }
  11.323 -
  11.324 -  status = WdfFdoQueryForInterface(Device, &GUID_XEN_IFACE_GNTTBL, (PINTERFACE)&GntTblInterface, sizeof(XEN_IFACE_GNTTBL), 1, NULL);
  11.325 -  if(!NT_SUCCESS(status))
  11.326 -  {
  11.327 -    KdPrint((__DRIVER_NAME "     WdfFdoQueryForInterface (GntTbl) failed with status 0x%08x\n", status));
  11.328 -  }
  11.329 -  
  11.330 -  //KdPrint((__DRIVER_NAME " <-- EvtDevicePrepareHardware\n"));
  11.331 -
  11.332 -  InitializeListHead(&DeviceListHead);
  11.333 -
  11.334 -  return status;
  11.335 -}
  11.336 -
  11.337 -static NTSTATUS
  11.338 -XenVbd_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated)
  11.339 -{
  11.340 -  UNREFERENCED_PARAMETER(Device);
  11.341 -  UNREFERENCED_PARAMETER(ResourcesTranslated);
  11.342 -
  11.343 -  // release interfaces here...
  11.344 -
  11.345 -  //XenVbd_Close();
  11.346 -
  11.347 -  return STATUS_SUCCESS;
  11.348 -}
  11.349 -
  11.350 -static NTSTATUS
  11.351 -XenVbd_D0Entry(
  11.352 -    IN WDFDEVICE  Device,
  11.353 -    IN WDF_POWER_DEVICE_STATE PreviousState
  11.354 -    )
  11.355 -{
  11.356 -  NTSTATUS status = STATUS_SUCCESS;
  11.357 -
  11.358 -  UNREFERENCED_PARAMETER(Device);
  11.359 -  UNREFERENCED_PARAMETER(PreviousState);
  11.360 -
  11.361 -  //KdPrint((__DRIVER_NAME " --> EvtDeviceD0Entry\n"));
  11.362 -
  11.363 -  //KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Entry\n"));
  11.364 -
  11.365 -  return status;
  11.366 +  return Status;
  11.367  }
  11.368  
  11.369 -static int EnumeratedDevices;
  11.370 -static KEVENT WaitDevicesEvent;
  11.371 -
  11.372 -static NTSTATUS
  11.373 -XenVbd_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState)
  11.374 -{
  11.375 -  //OBJECT_ATTRIBUTES oa;
  11.376 -  NTSTATUS status = STATUS_SUCCESS;
  11.377 -  //HANDLE nothing;
  11.378 -  //char *response;
  11.379 -  PXENPCI_XEN_DEVICE_DATA PdoDeviceData;
  11.380 -  char **VbdDevices;
  11.381 -  char *msg;
  11.382 -  char buffer[128];
  11.383 -  int i;
  11.384 -  LARGE_INTEGER WaitTimeout;
  11.385 -
  11.386 -  UNREFERENCED_PARAMETER(Device);
  11.387 -  UNREFERENCED_PARAMETER(PreviousState);
  11.388 -
  11.389 -  //KdPrint((__DRIVER_NAME " --> EvtDeviceD0EntryPostInterruptsEnabled\n"));
  11.390 -
  11.391 -  PdoDeviceData = (PXENPCI_XEN_DEVICE_DATA)Pdo->DeviceExtension; //GetXenDeviceData(Device);
  11.392 -
  11.393 -  //KdPrint((__DRIVER_NAME "     BasePath = %s\n", PdoDeviceData->BasePath));
  11.394 -  PdoDeviceData->WatchHandler = XenVbd_HotPlugHandler;
  11.395 -
  11.396 -  EnumeratedDevices = 0;
  11.397 -  KeInitializeEvent(&WaitDevicesEvent, SynchronizationEvent, FALSE);  
  11.398 -
  11.399 -  // TODO: Should probably do this in an EvtChildListScanForChildren
  11.400 -  if (AutoEnumerate)
  11.401 -  {
  11.402 -    msg = XenBusInterface.List(XBT_NIL, "device/vbd", &VbdDevices);
  11.403 -    if (!msg) {
  11.404 -      for (i = 0; VbdDevices[i]; i++)
  11.405 -      {
  11.406 -        KdPrint((__DRIVER_NAME "     found existing vbd device %s\n", VbdDevices[i]));
  11.407 -        RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/vbd/%s/state", VbdDevices[i]);
  11.408 -        XenVbd_HotPlugHandler(buffer, NULL);
  11.409 -        //ExFreePoolWithTag(bdDevices[i], XENPCI_POOL_TAG);
  11.410 -      }
  11.411 -      KdPrint((__DRIVER_NAME "     Waiting for devices to be enumerated\n"));
  11.412 -      while (EnumeratedDevices != i)
  11.413 -      {
  11.414 -        WaitTimeout.QuadPart = -600000000;
  11.415 -        if (KeWaitForSingleObject(&WaitDevicesEvent, Executive, KernelMode, FALSE, &WaitTimeout) == STATUS_TIMEOUT)
  11.416 -        {
  11.417 -          KdPrint((__DRIVER_NAME "     Wait timed out\n"));
  11.418 -          break;
  11.419 -        }
  11.420 -        KdPrint((__DRIVER_NAME "     %d out of %d devices enumerated\n", EnumeratedDevices, i));
  11.421 -      }  
  11.422 -    }
  11.423 -  }
  11.424 -
  11.425 -  //KdPrint((__DRIVER_NAME " <-- EvtDeviceD0EntryPostInterruptsEnabled\n"));
  11.426 -
  11.427 -  return status;
  11.428 -}
  11.429 -
  11.430 -static NTSTATUS
  11.431 -XenVbd_D0Exit(
  11.432 -    IN WDFDEVICE Device,
  11.433 -    IN WDF_POWER_DEVICE_STATE  TargetState
  11.434 -    )
  11.435 -{
  11.436 -  NTSTATUS status = STATUS_SUCCESS;
  11.437 -  //char *response;
  11.438 -
  11.439 -  UNREFERENCED_PARAMETER(Device);
  11.440 -  UNREFERENCED_PARAMETER(TargetState);
  11.441 -
  11.442 -  //KdPrint((__DRIVER_NAME " --> EvtDeviceD0Exit\n"));
  11.443 -
  11.444 -  //response = XenBusInterface.RemWatch(XBT_NIL, XenBusInterface.InterfaceHeader.Context, XenVbd_HotPlugHandler, NULL);
  11.445 -
  11.446 -  //KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Exit\n"));
  11.447 -
  11.448 -  return status;
  11.449 -}
  11.450 -
  11.451 -static NTSTATUS
  11.452 -XenVbd_DeviceUsageNotification(WDFDEVICE Device, WDF_SPECIAL_FILE_TYPE NotificationType, BOOLEAN IsInNotificationPath)
  11.453 -{
  11.454 -//  KdPrint((__DRIVER_NAME " --> DeviceUsageNotification\n"));
  11.455 -
  11.456 -  switch (NotificationType)
  11.457 -  {
  11.458 -  case WdfSpecialFilePaging:
  11.459 -    KdPrint((__DRIVER_NAME "     NotificationType = WdfSpecialFilePaging, Using = %d\n", IsInNotificationPath));
  11.460 -    break;
  11.461 -  case WdfSpecialFileHibernation:
  11.462 -    KdPrint((__DRIVER_NAME "     NotificationType = WdfSpecialFileHibernation, Using = %d\n", IsInNotificationPath));
  11.463 -    break;
  11.464 -  case WdfSpecialFileDump:
  11.465 -    KdPrint((__DRIVER_NAME "     NotificationType = WdfSpecialFileDump, Using = %d\n", IsInNotificationPath));
  11.466 -    break;
  11.467 -  default:
  11.468 -    KdPrint((__DRIVER_NAME "     NotificationType = %d, Using = %d\n", NotificationType, IsInNotificationPath));
  11.469 -    break;
  11.470 -  }
  11.471 -//  KdPrint((__DRIVER_NAME " <-- DeviceUsageNotification\n"));
  11.472 -
  11.473 -  return TRUE;
  11.474 -}
  11.475 -
  11.476 -static VOID 
  11.477 -XenVbd_IoDefault(
  11.478 -    IN WDFQUEUE  Queue,
  11.479 -    IN WDFREQUEST  Request
  11.480 -    )
  11.481 -{
  11.482 -  UNREFERENCED_PARAMETER(Queue);
  11.483 -
  11.484 -  KdPrint((__DRIVER_NAME " --> EvtDeviceIoDefault\n"));
  11.485 -
  11.486 -  WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
  11.487 -
  11.488 -  KdPrint((__DRIVER_NAME " <-- EvtDeviceIoDefault\n"));
  11.489 -}
  11.490 -
  11.491 -static __inline uint64_t
  11.492 -GET_ID_FROM_FREELIST(PXENVBD_CHILD_DEVICE_DATA ChildDeviceData)
  11.493 -{
  11.494 -  uint64_t free;
  11.495 -
  11.496 -  free = ChildDeviceData->shadow_free;
  11.497 -
  11.498 -  //KdPrint((__DRIVER_NAME "     A free = %d\n", free));
  11.499 -  
  11.500 -  ChildDeviceData->shadow_free = ChildDeviceData->shadow[free].req.id;
  11.501 -
  11.502 -  //KdPrint((__DRIVER_NAME "     A shadow_free now = %d\n", ChildDeviceData->shadow_free));
  11.503 -
  11.504 -  ChildDeviceData->shadow[free].req.id = 0x0fffffee; /* debug */
  11.505 -  return free;
  11.506 -}
  11.507 -
  11.508 -static __inline VOID
  11.509 -ADD_ID_TO_FREELIST(PXENVBD_CHILD_DEVICE_DATA ChildDeviceData, uint64_t Id)
  11.510 -{
  11.511 -  ChildDeviceData->shadow[Id].req.id  = ChildDeviceData->shadow_free;
  11.512 -  ChildDeviceData->shadow[Id].Irp = NULL;
  11.513 -  ChildDeviceData->shadow_free = Id;
  11.514 -}
  11.515 -
  11.516 -static VOID
  11.517 -XenVbd_PutIrpOnRing(WDFDEVICE Device, PIRP Irp);
  11.518 -
  11.519  static PMDL
  11.520  AllocatePages(int Pages)
  11.521  {
  11.522    PMDL Mdl;
  11.523    PVOID Buf;
  11.524  
  11.525 +  KdPrint((__DRIVER_NAME " --- AllocatePages IRQL = %d\n", KeGetCurrentIrql()));
  11.526    Buf = ExAllocatePoolWithTag(NonPagedPool, Pages * PAGE_SIZE, XENVBD_POOL_TAG);
  11.527    if (Buf == NULL)
  11.528    {
  11.529 @@ -492,163 +122,197 @@ static VOID
  11.530  FreePages(PMDL Mdl)
  11.531  {
  11.532    PVOID Buf = MmGetMdlVirtualAddress(Mdl);
  11.533 +  KdPrint((__DRIVER_NAME " --- FreePages IRQL = %d\n", KeGetCurrentIrql()));
  11.534    //KdPrint((__DRIVER_NAME "     FreePages Failed at IoAllocateMdl\n"));
  11.535    //KdPrint((__DRIVER_NAME "     FreePages Buf = %08x\n", Buf));
  11.536    IoFreeMdl(Mdl);
  11.537    ExFreePoolWithTag(Buf, XENVBD_POOL_TAG);
  11.538  }
  11.539  
  11.540 +static ULONG
  11.541 +XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
  11.542 +{
  11.543 +  ULONG Status = SP_RETURN_FOUND;
  11.544 +  ULONG i;
  11.545 +  PACCESS_RANGE AccessRange;
  11.546 +  PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
  11.547 +
  11.548 +  KdPrint((__DRIVER_NAME " --> HwScsiFindAdapter\n"));
  11.549 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  11.550 +
  11.551 +  KdPrint((__DRIVER_NAME "     BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
  11.552 +  KdPrint((__DRIVER_NAME "     BusInterruptVector = %d\n", ConfigInfo->BusInterruptVector));
  11.553 +
  11.554 +  KdPrint((__DRIVER_NAME "     AccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));
  11.555 +
  11.556 +  for (i = 0; i < ConfigInfo->NumberOfAccessRanges; i++)
  11.557 +  {
  11.558 +    AccessRange = &(*(ConfigInfo->AccessRanges))[i];
  11.559 +    KdPrint((__DRIVER_NAME "     AccessRange %2d: RangeStart = %08x, RangeLength = %08x, RangeInMemory = %d\n", i, AccessRange->RangeStart.LowPart, AccessRange->RangeLength, AccessRange->RangeInMemory));
  11.560 +    switch (i)
  11.561 +    {
  11.562 +    case 0:
  11.563 +      //DeviceData->ScsiData = ScsiPortGetDeviceBase(DeviceExtension, ConfigInfo->AdapterInterfaceType, ConfigInfo->SystemIoBusNumber, AccessRange->RangeStart, PAGE_SIZE, FALSE);
  11.564 +      //DeviceData->ScsiData = MmMapIoSpace(AccessRange->RangeStart, PAGE_SIZE, MmCached);
  11.565 +      DeviceData->XenDeviceData = (PXENPCI_XEN_DEVICE_DATA)AccessRange->RangeStart.QuadPart;
  11.566 +      KdPrint((__DRIVER_NAME "     Mapped to virtual address %08x\n", DeviceData->XenDeviceData));
  11.567 +      KdPrint((__DRIVER_NAME "     Magic = %08x\n", DeviceData->XenDeviceData->Magic));
  11.568 +      if (DeviceData->XenDeviceData->Magic == XEN_DATA_MAGIC)
  11.569 +      {
  11.570 +      }
  11.571 +      break;
  11.572 +    default:
  11.573 +      break;
  11.574 +    }
  11.575 +  }
  11.576 +
  11.577 +  ConfigInfo->NumberOfBuses = SCSI_BUSES;
  11.578 +  ConfigInfo->MaximumTransferLength = BUF_PAGES_PER_SRB * PAGE_SIZE;
  11.579 +  ConfigInfo->NumberOfPhysicalBreaks = BUF_PAGES_PER_SRB - 1; //11 - 1;
  11.580 +  ConfigInfo->ScatterGather = TRUE;
  11.581 +  ConfigInfo->Master = FALSE;
  11.582 +  ConfigInfo->AlignmentMask = 0;
  11.583 +  ConfigInfo->MaximumNumberOfLogicalUnits = 1;
  11.584 +  ConfigInfo->MaximumNumberOfTargets = SCSI_TARGETS_PER_BUS;
  11.585 +  //ConfigInfo->TaggedQueueing = TRUE;
  11.586 +
  11.587 +  *Again = FALSE;
  11.588 +
  11.589 +  KdPrint((__DRIVER_NAME " <-- HwScsiFindAdapter\n"));  
  11.590 +
  11.591 +  return Status;
  11.592 +}
  11.593 +
  11.594 +static __inline uint64_t
  11.595 +GET_ID_FROM_FREELIST(PXENVBD_TARGET_DATA TargetData)
  11.596 +{
  11.597 +  uint64_t free;
  11.598 +  free = TargetData->shadow_free;
  11.599 +  TargetData->shadow_free = TargetData->shadow[free].req.id;
  11.600 +  TargetData->shadow[free].req.id = 0x0fffffee; /* debug */
  11.601 +  return free;
  11.602 +}
  11.603 +
  11.604 +static __inline VOID
  11.605 +ADD_ID_TO_FREELIST(PXENVBD_TARGET_DATA TargetData, uint64_t Id)
  11.606 +{
  11.607 +  TargetData->shadow[Id].req.id  = TargetData->shadow_free;
  11.608 +  TargetData->shadow[Id].Srb = NULL;
  11.609 +  TargetData->shadow_free = Id;
  11.610 +}
  11.611 +
  11.612 +//static HANDLE XenVbd_ScsiPortThreadHandle;
  11.613 +//static KEVENT XenVbd_ScsiPortThreadEvent;
  11.614 +
  11.615  static VOID
  11.616 -XenVbd_DpcThreadProc(WDFDPC Dpc)
  11.617 +XenVbd_Interrupt(PKINTERRUPT Interrupt, PVOID DeviceExtension)
  11.618  {
  11.619 -  PIRP Irp;
  11.620 +  PXENVBD_TARGET_DATA TargetData = (PXENVBD_TARGET_DATA)DeviceExtension;
  11.621 +
  11.622 +  TargetData->PendingInterrupt = TRUE;
  11.623 +  return;
  11.624 +}
  11.625 +
  11.626 +static VOID
  11.627 +XenVbd_HwScsiInterruptTarget(PVOID DeviceExtension)
  11.628 +{
  11.629 +  PXENVBD_TARGET_DATA TargetData = (PXENVBD_TARGET_DATA)DeviceExtension;
  11.630 +  PSCSI_REQUEST_BLOCK Srb;
  11.631    RING_IDX i, rp;
  11.632    int j;
  11.633    blkif_response_t *rep;
  11.634 -  PXENVBD_CHILD_DEVICE_DATA ChildDeviceData;
  11.635 -  PSCSI_REQUEST_BLOCK Srb;
  11.636 -  PIO_STACK_LOCATION IrpSp;
  11.637    char *DataBuffer;
  11.638    int more_to_do;
  11.639 -  int IrpCount;
  11.640 -  PIRP Irps[100];
  11.641    int BlockCount;
  11.642 -  KIRQL KIrql;
  11.643 -  WDFDEVICE ChildDevice;
  11.644 -  XenVbd_ListEntry *ListEntry;
  11.645 +  KIRQL Irql;
  11.646    int notify;
  11.647 -  PUCHAR ptr;
  11.648 -  int sum;
  11.649 +  KAPC_STATE ApcState;
  11.650 +  PIRP Irp;
  11.651 +  PXENVBD_DEVICE_DATA DeviceData;
  11.652  
  11.653 -  //!!!IRQL_DISPATCH!!!
  11.654 -
  11.655 -  //KdPrint((__DRIVER_NAME " --> XenVbd_DpcThreadProc\n"));
  11.656 -
  11.657 -  ChildDevice = WdfDpcGetParentObject(Dpc);
  11.658 +//  KdPrint((__DRIVER_NAME " --> HwScsiInterruptTarget\n"));
  11.659  
  11.660 -  ChildDeviceData = *GetChildDeviceData(ChildDevice);
  11.661 -
  11.662 -  IrpCount = 0;
  11.663 +  DeviceData = (PXENVBD_DEVICE_DATA)TargetData->DeviceData;
  11.664    more_to_do = TRUE;
  11.665 -  KeAcquireSpinLock(&ChildDeviceData->Lock, &KIrql);
  11.666 -
  11.667 -  ChildDeviceData->IrpAddedToRingAtLastDpc = ChildDeviceData->IrpAddedToRing;
  11.668  
  11.669    while (more_to_do)
  11.670    {
  11.671 -    rp = ChildDeviceData->Ring.sring->rsp_prod;
  11.672 +    rp = TargetData->Ring.sring->rsp_prod;
  11.673      KeMemoryBarrier();
  11.674 -    for (i = ChildDeviceData->Ring.rsp_cons; i != rp; i++)
  11.675 +    for (i = TargetData->Ring.rsp_cons; i != rp; i++)
  11.676      {
  11.677 -      rep = RING_GET_RESPONSE(&ChildDeviceData->Ring, i);
  11.678 -      ChildDeviceData->IrpRemovedFromRing++;
  11.679 -      Irp = ChildDeviceData->shadow[rep->id].Irp;
  11.680 -      IrpSp = IoGetCurrentIrpStackLocation(Irp);
  11.681 -      Srb = IrpSp->Parameters.Scsi.Srb;
  11.682 +      rep = RING_GET_RESPONSE(&TargetData->Ring, i);
  11.683 +      Srb = TargetData->shadow[rep->id].Srb;
  11.684 +
  11.685 +//      KdPrint((__DRIVER_NAME "     Response Id = %d\n", (int)rep->id));
  11.686  
  11.687        if (rep->status != BLKIF_RSP_OKAY)
  11.688        {
  11.689 -        KdPrint((__DRIVER_NAME "     Xen Operation returned error in DpcThreadProc\n"));
  11.690 -        KdPrint((__DRIVER_NAME "       operation = %d, nr_segments = %d, sector_number = %d\n", ChildDeviceData->shadow[rep->id].req.operation, ChildDeviceData->shadow[rep->id].req.nr_segments, ChildDeviceData->shadow[rep->id].req.sector_number));
  11.691 -        for (j = 0; j < ChildDeviceData->shadow[rep->id].req.nr_segments; j++)
  11.692 -        {
  11.693 -          KdPrint((__DRIVER_NAME "       gref[%d] = %d\n", j, ChildDeviceData->shadow[rep->id].req.seg[j].gref));
  11.694 -        }
  11.695 -        KdPrint((__DRIVER_NAME "       MmGetMdlByteOffset = %d\n", MmGetMdlByteOffset(Irp->MdlAddress)));
  11.696 +        KdPrint((__DRIVER_NAME "     Xen Operation returned error\n"));
  11.697        }
  11.698 -      for (j = 0; j < ChildDeviceData->shadow[rep->id].req.nr_segments; j++)
  11.699 +      for (j = 0; j < TargetData->shadow[rep->id].req.nr_segments; j++)
  11.700        {
  11.701 -        GntTblInterface.EndAccess(ChildDeviceData->shadow[rep->id].req.seg[j].gref);
  11.702 +        DeviceData->XenDeviceData->GntTblInterface.EndAccess(TargetData->shadow[rep->id].req.seg[j].gref);
  11.703        }
  11.704        BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
  11.705 -      if (ChildDeviceData->shadow[rep->id].Buf != NULL)
  11.706 -      {
  11.707 -        if (Srb->Cdb[0] == SCSIOP_READ)
  11.708 -        {
  11.709 -          DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
  11.710 -          if (DataBuffer == NULL)
  11.711 -            KdPrint((__DRIVER_NAME "     MmGetSystemAddressForMdlSafe Failed in DpcThreadProc\n"));
  11.712 -          memcpy(DataBuffer, ChildDeviceData->shadow[rep->id].Buf, BlockCount * ChildDeviceData->BytesPerSector);
  11.713 -          for (j = 0, sum = 0, ptr = ChildDeviceData->shadow[rep->id].Buf; j < BlockCount * ChildDeviceData->BytesPerSector; j++, ptr++)
  11.714 -          {
  11.715 -            sum += *ptr;
  11.716 -          }
  11.717 -          KdPrint((__DRIVER_NAME "     READ sum = %08X\n", sum));
  11.718 -        }
  11.719 -        FreePages(ChildDeviceData->shadow[rep->id].Mdl);
  11.720 -      }
  11.721 +      if (Srb->Cdb[0] == SCSIOP_READ)
  11.722 +        memcpy(Srb->DataBuffer, TargetData->shadow[rep->id].Buf, BlockCount * TargetData->BytesPerSector);
  11.723 +
  11.724 +      //FreePages(TargetData->shadow[rep->id].Mdl);
  11.725        Srb->SrbStatus = SRB_STATUS_SUCCESS;
  11.726 -      Srb->ScsiStatus = 0;
  11.727 -      Irp->IoStatus.Status = STATUS_SUCCESS;
  11.728 -      Irp->IoStatus.Information = BlockCount * ChildDeviceData->BytesPerSector;
  11.729  
  11.730 -      Irps[IrpCount++] = Irp;
  11.731 +      ScsiPortNotification(RequestComplete, DeviceData, Srb);
  11.732  
  11.733 -      ADD_ID_TO_FREELIST(ChildDeviceData, rep->id);
  11.734 +      ADD_ID_TO_FREELIST(TargetData, rep->id);
  11.735      }
  11.736  
  11.737 -    ChildDeviceData->Ring.rsp_cons = i;
  11.738 -    if (i != ChildDeviceData->Ring.req_prod_pvt)
  11.739 +    TargetData->Ring.rsp_cons = i;
  11.740 +    if (i != TargetData->Ring.req_prod_pvt)
  11.741      {
  11.742 -      RING_FINAL_CHECK_FOR_RESPONSES(&ChildDeviceData->Ring, more_to_do);
  11.743 +      RING_FINAL_CHECK_FOR_RESPONSES(&TargetData->Ring, more_to_do);
  11.744      }
  11.745      else
  11.746      {
  11.747 -      ChildDeviceData->Ring.sring->rsp_event = i + 1;
  11.748 +      TargetData->Ring.sring->rsp_event = i + 1;
  11.749        more_to_do = FALSE;
  11.750      }
  11.751    }
  11.752  
  11.753 -  notify = 0;
  11.754 -  while (!RING_FULL(&ChildDeviceData->Ring) && (ListEntry = (XenVbd_ListEntry *)RemoveHeadList(&ChildDeviceData->IrpListHead)) != (XenVbd_ListEntry *)&ChildDeviceData->IrpListHead)
  11.755 -  {
  11.756 -    ChildDeviceData->IrpRemovedFromList++;
  11.757 -    XenVbd_PutIrpOnRing(ChildDevice, ListEntry->Irp);
  11.758 -    ExFreePoolWithTag(ListEntry, XENVBD_POOL_TAG);
  11.759 -    notify = 1;
  11.760 -  }
  11.761 -  if (notify)
  11.762 -  {
  11.763 -    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&ChildDeviceData->Ring, notify);
  11.764 -    if (notify)
  11.765 -      EvtChnInterface.Notify(ChildDeviceData->EventChannel);
  11.766 -  }
  11.767 -  KeReleaseSpinLock(&ChildDeviceData->Lock, KIrql);
  11.768 +//  KdPrint((__DRIVER_NAME " <-- HwScsiInterruptTarget\n"));
  11.769  
  11.770 -  for (j = 0; j < IrpCount; j++)
  11.771 -  {
  11.772 -    IoCompleteRequest(Irps[j], IO_NO_INCREMENT);
  11.773 -    ChildDeviceData->IrpCompleted++;
  11.774 -  }
  11.775 -
  11.776 -  //KdPrint((__DRIVER_NAME " <-- XenVbd_DpcThreadProc\n"));
  11.777 -  //KdPrint((__DRIVER_NAME " <-- XenVbd_DpcThreadProc (AddedToList = %d, RemovedFromList = %d, AddedToRing = %d, AddedToRingAtLastNotify = %d, AddedToRingAtLastInterrupt = %d, AddedToRingAtLastDpc = %d, RemovedFromRing = %d, IrpCompleted = %d)\n", ChildDeviceData->IrpAddedToList, ChildDeviceData->IrpRemovedFromList, ChildDeviceData->IrpAddedToRing, ChildDeviceData->IrpAddedToRingAtLastNotify, ChildDeviceData->IrpAddedToRingAtLastInterrupt, ChildDeviceData->IrpAddedToRingAtLastDpc, ChildDeviceData->IrpRemovedFromRing, ChildDeviceData->IrpCompleted));
  11.778 +  return FALSE;
  11.779  }
  11.780  
  11.781  static BOOLEAN
  11.782 -XenVbd_Interrupt(PKINTERRUPT Interrupt, PVOID ServiceContext)
  11.783 +XenVbd_HwScsiInterrupt(PVOID DeviceExtension)
  11.784  {
  11.785 -  BOOLEAN RetVal;
  11.786 -  PXENVBD_CHILD_DEVICE_DATA ChildDeviceData;
  11.787 -
  11.788 -  UNREFERENCED_PARAMETER(Interrupt);
  11.789 -  // !!!RUNS AT DIRQL!!!
  11.790 +  PXENVBD_DEVICE_DATA DeviceData;
  11.791 +  PXENVBD_TARGET_DATA TargetData;
  11.792 +  int i, j;
  11.793  
  11.794 -  //KdPrint((__DRIVER_NAME " --> XenVbd_Interrupt\n"));
  11.795 +//  KdPrint((__DRIVER_NAME " --> HwScsiInterrupt\n"));
  11.796  
  11.797 -  ChildDeviceData = (PXENVBD_CHILD_DEVICE_DATA)ServiceContext;
  11.798 -  ChildDeviceData->IrpAddedToRingAtLastInterrupt = ChildDeviceData->IrpAddedToRing;
  11.799 -  RetVal = WdfDpcEnqueue(ChildDeviceData->Dpc);
  11.800 +  DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
  11.801  
  11.802 -  //KdPrint((__DRIVER_NAME " <-- XenVbd_Interrupt (RetVal = %d)\n", RetVal));  
  11.803 -
  11.804 -  return STATUS_SUCCESS;
  11.805 +  KeMemoryBarrier();
  11.806 +  for (i = 0; i < SCSI_BUSES; i++)
  11.807 +  {
  11.808 +    for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
  11.809 +    {
  11.810 +      TargetData = &DeviceData->BusData[i].TargetData[j];
  11.811 +      if (TargetData->PendingInterrupt)
  11.812 +        XenVbd_HwScsiInterruptTarget(TargetData);
  11.813 +      TargetData->PendingInterrupt = FALSE;
  11.814 +    }
  11.815 +  }
  11.816 +//  KdPrint((__DRIVER_NAME " <-- HwScsiInterrupt\n"));
  11.817  }
  11.818  
  11.819  static VOID
  11.820  XenVbd_BackEndStateHandler(char *Path, PVOID Data)
  11.821  {
  11.822 -  PXENVBD_CHILD_DEVICE_DATA DeviceData;
  11.823 +  PXENVBD_TARGET_DATA TargetData;
  11.824 +  PXENVBD_DEVICE_DATA DeviceData;
  11.825    char TmpPath[128];
  11.826    char *Value;
  11.827    int NewState;
  11.828 @@ -656,12 +320,17 @@ XenVbd_BackEndStateHandler(char *Path, P
  11.829    grant_ref_t ref;
  11.830    blkif_sring_t *SharedRing;
  11.831    ULONG PFN;
  11.832 -  XENVBD_DEVICE_IDENTIFICATION_DESCRIPTION Description;
  11.833 +  //XENVBD_DEVICE_IDENTIFICATION_DESCRIPTION Description;
  11.834 +  KIRQL OldIrql;
  11.835    NTSTATUS status;
  11.836 +  int i;
  11.837  
  11.838 -  DeviceData = (PXENVBD_CHILD_DEVICE_DATA)Data;
  11.839 +  KdPrint((__DRIVER_NAME " --> BackEndStateHandler\n"));
  11.840  
  11.841 -  XenBusInterface.Read(XBT_NIL, Path, &Value);
  11.842 +  TargetData = (PXENVBD_TARGET_DATA)Data;
  11.843 +  DeviceData = (PXENVBD_DEVICE_DATA)TargetData->DeviceData;
  11.844 +
  11.845 +  DeviceData->XenDeviceData->XenBusInterface.Read(XBT_NIL, Path, &Value);
  11.846  
  11.847    NewState = atoi(Value);
  11.848    switch (NewState)
  11.849 @@ -677,111 +346,131 @@ XenVbd_BackEndStateHandler(char *Path, P
  11.850    case XenbusStateInitWait:
  11.851      KdPrint((__DRIVER_NAME "     Backend State Changed to InitWait\n"));  
  11.852  
  11.853 -    DeviceData->EventChannel = EvtChnInterface.AllocUnbound(0);
  11.854 -    EvtChnInterface.Bind(DeviceData->EventChannel, XenVbd_Interrupt, DeviceData);
  11.855 +    TargetData->EventChannel = DeviceData->XenDeviceData->EvtChnInterface.AllocUnbound(0);
  11.856 +    DeviceData->XenDeviceData->EvtChnInterface.Bind(TargetData->EventChannel, XenVbd_Interrupt, TargetData);
  11.857      Mdl = AllocatePage();
  11.858      PFN = *MmGetMdlPfnArray(Mdl);
  11.859      SharedRing = (blkif_sring_t *)MmGetMdlVirtualAddress(Mdl);
  11.860      SHARED_RING_INIT(SharedRing);
  11.861 -    FRONT_RING_INIT(&DeviceData->Ring, SharedRing, PAGE_SIZE);
  11.862 -    ref = GntTblInterface.GrantAccess(0, PFN, FALSE);
  11.863 -
  11.864 -    RtlStringCbCopyA(TmpPath, 128, DeviceData->Path);
  11.865 -    RtlStringCbCatA(TmpPath, 128, "/ring-ref");
  11.866 -    XenBusInterface.Printf(XBT_NIL, TmpPath, "%d", ref);
  11.867 +    FRONT_RING_INIT(&TargetData->Ring, SharedRing, PAGE_SIZE);
  11.868 +    ref = DeviceData->XenDeviceData->GntTblInterface.GrantAccess(0, PFN, FALSE);
  11.869  
  11.870 -    RtlStringCbCopyA(TmpPath, 128, DeviceData->Path);
  11.871 +    TargetData->shadow = ExAllocatePoolWithTag(NonPagedPool, sizeof(blkif_shadow_t) * BLK_RING_SIZE, XENVBD_POOL_TAG);
  11.872 +
  11.873 +    memset(TargetData->shadow, 0, sizeof(blkif_shadow_t) * BLK_RING_SIZE);
  11.874 +    for (i = 0; i < BLK_RING_SIZE; i++)
  11.875 +    {
  11.876 +      TargetData->shadow[i].req.id = i + 1;
  11.877 +      TargetData->shadow[i].Mdl = AllocatePages(BUF_PAGES_PER_SRB); // stupid that we have to do this!
  11.878 +      TargetData->shadow[i].Buf = MmGetMdlVirtualAddress(TargetData->shadow[i].Mdl);
  11.879 +    }
  11.880 +    TargetData->shadow_free = 0;
  11.881 +    TargetData->shadow[BLK_RING_SIZE - 1].req.id = 0x0fffffff;
  11.882 +
  11.883 +    RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  11.884 +    RtlStringCbCatA(TmpPath, 128, "/ring-ref");
  11.885 +    DeviceData->XenDeviceData->XenBusInterface.Printf(XBT_NIL, TmpPath, "%d", ref);
  11.886 +
  11.887 +    RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  11.888      RtlStringCbCatA(TmpPath, 128, "/event-channel");
  11.889 -    XenBusInterface.Printf(XBT_NIL, TmpPath, "%d", DeviceData->EventChannel);
  11.890 +    DeviceData->XenDeviceData->XenBusInterface.Printf(XBT_NIL, TmpPath, "%d", TargetData->EventChannel);
  11.891    
  11.892 -    RtlStringCbCopyA(TmpPath, 128, DeviceData->Path);
  11.893 +    RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  11.894      RtlStringCbCatA(TmpPath, 128, "/state");
  11.895 -    XenBusInterface.Printf(XBT_NIL, TmpPath, "%d", XenbusStateInitialised);
  11.896 +    DeviceData->XenDeviceData->XenBusInterface.Printf(XBT_NIL, TmpPath, "%d", XenbusStateInitialised);
  11.897  
  11.898      KdPrint((__DRIVER_NAME "     Set Frontend state to Initialised\n"));
  11.899      break;
  11.900  
  11.901    case XenbusStateInitialised:
  11.902      KdPrint((__DRIVER_NAME "     Backend State Changed to Initialised\n"));
  11.903 -    // create the device
  11.904      break;
  11.905  
  11.906    case XenbusStateConnected:
  11.907      KdPrint((__DRIVER_NAME "     Backend State Changed to Connected\n"));  
  11.908  
  11.909 -    WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&Description.Header, sizeof(Description));
  11.910 -
  11.911 -    Description.DeviceData = DeviceData;
  11.912 -
  11.913 -    RtlStringCbCopyA(TmpPath, 128, DeviceData->Path);
  11.914 +    RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  11.915      RtlStringCbCatA(TmpPath, 128, "/device-type");
  11.916 -    XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
  11.917 +    DeviceData->XenDeviceData->XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
  11.918      if (strcmp(Value, "disk") == 0)
  11.919      {
  11.920        KdPrint((__DRIVER_NAME "     DeviceType = Disk\n"));    
  11.921 -      DeviceData->DeviceType = XENVBD_DEVICETYPE_DISK;
  11.922 +      TargetData->DeviceType = XENVBD_DEVICETYPE_DISK;
  11.923      }
  11.924      else if (strcmp(Value, "cdrom") == 0)
  11.925      {
  11.926        KdPrint((__DRIVER_NAME "     DeviceType = CDROM\n"));    
  11.927 -      DeviceData->DeviceType = XENVBD_DEVICETYPE_CDROM;
  11.928 +      TargetData->DeviceType = XENVBD_DEVICETYPE_CDROM;
  11.929      }
  11.930      else
  11.931      {
  11.932        KdPrint((__DRIVER_NAME "     DeviceType = %s (This probably won't work!)\n", Value));
  11.933 +      TargetData->DeviceType = XENVBD_DEVICETYPE_UNKNOWN;
  11.934      }
  11.935  
  11.936 -    RtlStringCbCopyA(TmpPath, 128, DeviceData->BackendPath);
  11.937 +    RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
  11.938      RtlStringCbCatA(TmpPath, 128, "/type"); // should probably check that this is 'phy' or 'file' or at least not ''
  11.939 -    XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
  11.940 +    DeviceData->XenDeviceData->XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
  11.941      KdPrint((__DRIVER_NAME "     Backend Type = %s\n", Value));
  11.942  
  11.943 -    RtlStringCbCopyA(TmpPath, 128, DeviceData->BackendPath);
  11.944 +    RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
  11.945      RtlStringCbCatA(TmpPath, 128, "/mode"); // should store this...
  11.946 -    XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
  11.947 +    DeviceData->XenDeviceData->XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
  11.948      KdPrint((__DRIVER_NAME "     Backend Mode = %s\n", Value));
  11.949  
  11.950 -    RtlStringCbCopyA(TmpPath, 128, DeviceData->BackendPath);
  11.951 +    RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
  11.952      RtlStringCbCatA(TmpPath, 128, "/sector-size");
  11.953 -    XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
  11.954 +    DeviceData->XenDeviceData->XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
  11.955      // should complain if Value == NULL
  11.956 -    DeviceData->BytesPerSector = atoi(Value);
  11.957 +    TargetData->BytesPerSector = atoi(Value);
  11.958  
  11.959 -    KdPrint((__DRIVER_NAME "     BytesPerSector = %d\n", DeviceData->BytesPerSector));    
  11.960 +    KdPrint((__DRIVER_NAME "     BytesPerSector = %d\n", TargetData->BytesPerSector));    
  11.961  
  11.962 -    RtlStringCbCopyA(TmpPath, 128, DeviceData->BackendPath);
  11.963 +    RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
  11.964      RtlStringCbCatA(TmpPath, 128, "/sectors");
  11.965 -    XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
  11.966 +    DeviceData->XenDeviceData->XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
  11.967      // should complain if Value == NULL
  11.968 -    DeviceData->TotalSectors = (ULONGLONG)atol(Value);
  11.969 +    TargetData->TotalSectors = (ULONGLONG)atol(Value);
  11.970  
  11.971 -    KdPrint((__DRIVER_NAME "     TotalSectors = %d\n", DeviceData->TotalSectors));    
  11.972 +    KdPrint((__DRIVER_NAME "     TotalSectors = %d\n", TargetData->TotalSectors));    
  11.973  
  11.974      // should probably use the partition table (if one exists) here for the sectorspertrack and trackspercylinder values
  11.975 -    DeviceData->Geometry.MediaType = FixedMedia;
  11.976 -    DeviceData->Geometry.BytesPerSector = DeviceData->BytesPerSector;
  11.977 -    DeviceData->Geometry.SectorsPerTrack = 63;
  11.978 -    DeviceData->Geometry.TracksPerCylinder = 255;
  11.979 -    DeviceData->Geometry.Cylinders.QuadPart = DeviceData->TotalSectors / DeviceData->Geometry.SectorsPerTrack / DeviceData->Geometry.TracksPerCylinder;
  11.980 -    KdPrint((__DRIVER_NAME "     Geometry C/H/S = %d/%d/%d\n", DeviceData->Geometry.Cylinders.LowPart, DeviceData->Geometry.TracksPerCylinder, DeviceData->Geometry.SectorsPerTrack));
  11.981 +    TargetData->Geometry.MediaType = FixedMedia;
  11.982 +    TargetData->Geometry.BytesPerSector = TargetData->BytesPerSector;
  11.983 +    TargetData->Geometry.SectorsPerTrack = 63;
  11.984 +    TargetData->Geometry.TracksPerCylinder = 255;
  11.985 +    TargetData->Geometry.Cylinders.QuadPart = TargetData->TotalSectors / TargetData->Geometry.SectorsPerTrack / TargetData->Geometry.TracksPerCylinder;
  11.986 +    KdPrint((__DRIVER_NAME "     Geometry C/H/S = %d/%d/%d\n", TargetData->Geometry.Cylinders.LowPart, TargetData->Geometry.TracksPerCylinder, TargetData->Geometry.SectorsPerTrack));
  11.987 +    
  11.988 +// now ask windows to rescan the scsi bus...
  11.989 +    DeviceData->BusChangePending = 1;
  11.990  
  11.991 -    // if we detected something wrong, we should not enumarate the device and should instead initiate a close
  11.992 +/*
  11.993 +    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  11.994 +    OldIrql = KeRaiseIrqlToDpcLevel();
  11.995 +    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  11.996 +    ScsiPortNotification(BusChangeDetected, TargetData->DeviceData, 0);
  11.997 +    KeLowerIrql(OldIrql);
  11.998 +    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  11.999 +*/
 11.1000 +/*
 11.1001 +    // if we detected something wrong, we should not enumerate the device and should instead initiate a close
 11.1002  
 11.1003      status = WdfChildListAddOrUpdateChildDescriptionAsPresent(WdfFdoGetDefaultChildList(GlobalDevice), &Description.Header, NULL);
 11.1004      if (!NT_SUCCESS(status))
 11.1005      {
 11.1006        KdPrint((__DRIVER_NAME "     WdfChildListAddOrUpdateChildDescriptionAsPresent failed %08x\n", status));
 11.1007      } 
 11.1008 +*/
 11.1009  
 11.1010 -    RtlStringCbCopyA(TmpPath, 128, DeviceData->Path);
 11.1011 +    RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
 11.1012      RtlStringCbCatA(TmpPath, 128, "/state");
 11.1013 -    XenBusInterface.Printf(XBT_NIL, TmpPath, "%d", XenbusStateConnected);
 11.1014 +    DeviceData->XenDeviceData->XenBusInterface.Printf(XBT_NIL, TmpPath, "%d", XenbusStateConnected);
 11.1015  
 11.1016      KdPrint((__DRIVER_NAME "     Set Frontend state to Connected\n"));
 11.1017 -    InterlockedIncrement(&EnumeratedDevices);
 11.1018 -    KdPrint((__DRIVER_NAME "     Added a device, notifying\n"));
 11.1019 -    
 11.1020 -    KeSetEvent(&WaitDevicesEvent, 1, FALSE);
 11.1021 +    InterlockedIncrement(&DeviceData->EnumeratedDevices);
 11.1022 +    KdPrint((__DRIVER_NAME "     Added a device, notifying\n"));  
 11.1023 +    KeSetEvent(&DeviceData->WaitDevicesEvent, 1, FALSE);
 11.1024  
 11.1025      break;
 11.1026  
 11.1027 @@ -797,22 +486,25 @@ XenVbd_BackEndStateHandler(char *Path, P
 11.1028      KdPrint((__DRIVER_NAME "     Backend State Changed to Undefined = %d\n", NewState));
 11.1029      break;
 11.1030    }
 11.1031 +
 11.1032 +  KdPrint((__DRIVER_NAME " <-- BackEndStateHandler\n"));
 11.1033  }
 11.1034  
 11.1035  static VOID
 11.1036 -XenVbd_HotPlugHandler(char *Path, PVOID Data)
 11.1037 +XenVbd_WatchHandler(char *Path, PVOID DeviceExtension)
 11.1038  {
 11.1039 -  PXENVBD_CHILD_DEVICE_DATA DeviceData;
 11.1040 +  PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
 11.1041    char **Bits;
 11.1042    int Count;
 11.1043    char TmpPath[128];
 11.1044    char *Value;
 11.1045 -
 11.1046 -  UNREFERENCED_PARAMETER(Data);  
 11.1047 +  int VacantBus, VacantTarget;
 11.1048 +  PXENVBD_TARGET_DATA TargetData;
 11.1049 +  int i, j;
 11.1050  
 11.1051 -  //KdPrint((__DRIVER_NAME " --> HotPlugHandler\n"));
 11.1052 +  KdPrint((__DRIVER_NAME " --> WatchHandler (DeviceData = %08x)\n", DeviceData));
 11.1053  
 11.1054 -  //KdPrint((__DRIVER_NAME "     Path = %s\n", Path));
 11.1055 +  KdPrint((__DRIVER_NAME "     Path = %s\n", Path));
 11.1056  
 11.1057    Bits = SplitString(Path, '/', 4, &Count);
 11.1058    switch (Count)
 11.1059 @@ -824,799 +516,506 @@ XenVbd_HotPlugHandler(char *Path, PVOID 
 11.1060    case 3:
 11.1061      break;
 11.1062    case 4:
 11.1063 -    
 11.1064      if (strcmp(Bits[3], "state") != 0) // we only care when the state appears
 11.1065        break;
 11.1066 -    for (DeviceData = (PXENVBD_CHILD_DEVICE_DATA)DeviceListHead.Flink; DeviceData != (PXENVBD_CHILD_DEVICE_DATA)&DeviceListHead; DeviceData = (PXENVBD_CHILD_DEVICE_DATA)DeviceData->Entry.Flink)
 11.1067 +//    for (DeviceData = (PXENVBD_DEVICE_DATA)DeviceListHead.Flink; DeviceData != (PXENVBD_CHILD_DEVICE_DATA)&DeviceListHead; DeviceData = (PXENVBD_CHILD_DEVICE_DATA)DeviceData->Entry.Flink)
 11.1068 +//    {
 11.1069 +//    VacantBus = -1;
 11.1070 +//    VacantTarget = -1;
 11.1071 +    TargetData = NULL;
 11.1072 +//    VacantTarget = NULL;
 11.1073 +    
 11.1074 +    for (i = 0; i < SCSI_BUSES; i++)
 11.1075      {
 11.1076 -      if (strncmp(DeviceData->Path, Path, strlen(DeviceData->Path)) == 0 && Path[strlen(DeviceData->Path)] == '/')
 11.1077 +      for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
 11.1078        {
 11.1079 -        break;
 11.1080 +        if (j == 7) // don't use 7 - it would be for the controller
 11.1081 +          continue;
 11.1082 +        TargetData = &DeviceData->BusData[i].TargetData[j];
 11.1083 +        if (TargetData->Present && strncmp(TargetData->Path, Path, strlen(TargetData->Path)) == 0 && Path[strlen(TargetData->Path)] == '/')
 11.1084 +        {
 11.1085 +          FreeSplitString(Bits, Count);
 11.1086 +          KdPrint((__DRIVER_NAME " <-- WatchHandler (Already exists)\n"));
 11.1087 +          return;
 11.1088 +        }
 11.1089        }
 11.1090      }
 11.1091 -    if (DeviceData == (PXENVBD_CHILD_DEVICE_DATA)&DeviceListHead)
 11.1092 +    for (i = 0; i < SCSI_BUSES; i++)
 11.1093      {
 11.1094 -      DeviceData = ExAllocatePoolWithTag(NonPagedPool, sizeof(XENVBD_CHILD_DEVICE_DATA), XENVBD_POOL_TAG);
 11.1095 -      memset(DeviceData, 0, sizeof(XENVBD_CHILD_DEVICE_DATA));
 11.1096 -
 11.1097 -      //KdPrint((__DRIVER_NAME "     Allocated ChildDeviceData = %08x\n", DeviceData));
 11.1098 -      
 11.1099 -      InsertTailList(&DeviceListHead, &DeviceData->Entry);
 11.1100 -      RtlStringCbCopyA(DeviceData->Path, 128, Bits[0]);
 11.1101 -      RtlStringCbCatA(DeviceData->Path, 128, "/");
 11.1102 -      RtlStringCbCatA(DeviceData->Path, 128, Bits[1]);
 11.1103 -      RtlStringCbCatA(DeviceData->Path, 128, "/");
 11.1104 -      RtlStringCbCatA(DeviceData->Path, 128, Bits[2]);
 11.1105 +      for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
 11.1106 +      {
 11.1107 +        if (j == 7) // don't use 7 - it would be for the controller
 11.1108 +          continue;
 11.1109 +        TargetData = &DeviceData->BusData[i].TargetData[j];
 11.1110 +        if (!TargetData->Present)
 11.1111 +        {
 11.1112 +KdPrint((__DRIVER_NAME "     A\n"));    
 11.1113 +          TargetData->Present = 1;
 11.1114 +          RtlStringCbCopyA(TargetData->Path, 128, Bits[0]);
 11.1115 +          RtlStringCbCatA(TargetData->Path, 128, "/");
 11.1116 +          RtlStringCbCatA(TargetData->Path, 128, Bits[1]);
 11.1117 +          RtlStringCbCatA(TargetData->Path, 128, "/");
 11.1118 +          RtlStringCbCatA(TargetData->Path, 128, Bits[2]);
 11.1119  
 11.1120 -      DeviceData->DeviceIndex = atoi(Bits[2]);
 11.1121 +KdPrint((__DRIVER_NAME "     B\n"));    
 11.1122  
 11.1123 -      RtlStringCbCopyA(TmpPath, 128, DeviceData->Path);
 11.1124 -      RtlStringCbCatA(TmpPath, 128, "/backend");
 11.1125 -      XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
 11.1126 -      if (Value == NULL)
 11.1127 -      {
 11.1128 -        KdPrint((__DRIVER_NAME "     Read Failed\n"));
 11.1129 +          TargetData->DeviceIndex = atoi(Bits[2]);
 11.1130 +
 11.1131 +KdPrint((__DRIVER_NAME "     C\n"));
 11.1132 +
 11.1133 +          RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
 11.1134 +          RtlStringCbCatA(TmpPath, 128, "/backend");
 11.1135 +          DeviceData->XenDeviceData->XenBusInterface.Read(XBT_NIL, TmpPath, &Value);
 11.1136 +          if (Value == NULL)
 11.1137 +          {
 11.1138 +            KdPrint((__DRIVER_NAME "     Read Failed\n"));
 11.1139 +          }
 11.1140 +          else
 11.1141 +          {
 11.1142 +            RtlStringCbCopyA(TargetData->BackendPath, 128, Value);
 11.1143 +          }
 11.1144 +          RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
 11.1145 +          RtlStringCbCatA(TmpPath, 128, "/state");
 11.1146 +
 11.1147 +KdPrint((__DRIVER_NAME "     D\n"));
 11.1148 +
 11.1149 +          DeviceData->XenDeviceData->XenBusInterface.AddWatch(XBT_NIL, TmpPath, XenVbd_BackEndStateHandler, TargetData);
 11.1150 +
 11.1151 +KdPrint((__DRIVER_NAME "     E\n"));
 11.1152 +
 11.1153 +          FreeSplitString(Bits, Count);
 11.1154 +
 11.1155 +          KdPrint((__DRIVER_NAME " <-- WatchHandler (Added a new target)\n"));
 11.1156 +
 11.1157 +          return;
 11.1158 +        }
 11.1159        }
 11.1160 -      else
 11.1161 -      {
 11.1162 -        RtlStringCbCopyA(DeviceData->BackendPath, 128, Value);
 11.1163 -      }
 11.1164 -      RtlStringCbCopyA(TmpPath, 128, DeviceData->BackendPath);
 11.1165 -      RtlStringCbCatA(TmpPath, 128, "/state");
 11.1166 -      XenBusInterface.AddWatch(XBT_NIL, TmpPath, XenVbd_BackEndStateHandler, DeviceData);
 11.1167      }
 11.1168      break;
 11.1169    }
 11.1170    
 11.1171    FreeSplitString(Bits, Count);
 11.1172  
 11.1173 -  //KdPrint((__DRIVER_NAME " <-- HotPlugHandler\n"));  
 11.1174 +  KdPrint((__DRIVER_NAME " <-- WatchHandler\n"));  
 11.1175  
 11.1176    return;
 11.1177  }
 11.1178  
 11.1179 -static NTSTATUS
 11.1180 -XenVbd_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit)
 11.1181 +static VOID 
 11.1182 +XenVbd_CheckBusChangedTimer(PVOID DeviceExtension)
 11.1183  {
 11.1184 -  NTSTATUS status;
 11.1185 -  WDFDEVICE ChildDevice;
 11.1186 -  PXENVBD_DEVICE_IDENTIFICATION_DESCRIPTION XenVbdIdentificationDesc;
 11.1187 -  DECLARE_UNICODE_STRING_SIZE(buffer, 50);
 11.1188 -  WDF_OBJECT_ATTRIBUTES PdoAttributes;
 11.1189 -  DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
 11.1190 -  PXENVBD_CHILD_DEVICE_DATA ChildDeviceData;
 11.1191 -  WDF_IO_QUEUE_CONFIG IoQueueConfig;
 11.1192 -  unsigned int i;
 11.1193 -  WDF_DPC_CONFIG DpcConfig;
 11.1194 -  WDF_OBJECT_ATTRIBUTES DpcObjectAttributes;
 11.1195 -  WDF_DEVICE_STATE DeviceState;
 11.1196 -  UCHAR ScsiMinors[1] = { IRP_MN_SCSI_CLASS };
 11.1197 -
 11.1198 -  UNREFERENCED_PARAMETER(ChildList);
 11.1199 -
 11.1200 -  KdPrint((__DRIVER_NAME " --> ChildListCreateDevice\n"));
 11.1201 -
 11.1202 -  XenVbdIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENVBD_DEVICE_IDENTIFICATION_DESCRIPTION, Header);
 11.1203 -
 11.1204 -  ChildDeviceData = XenVbdIdentificationDesc->DeviceData;
 11.1205 -
 11.1206 -  // Capabilities = CM_DEVCAP_UNIQUEID
 11.1207 -  // Devnode Flages = DN_NEED_RESTART??? DN_DISABLEABLE???
 11.1208 -
 11.1209 -  switch (ChildDeviceData->DeviceType)
 11.1210 -  {
 11.1211 -  case XENVBD_DEVICETYPE_DISK:
 11.1212 -    WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_DISK);
 11.1213 -
 11.1214 -    status = RtlUnicodeStringPrintf(&buffer, L"XEN\\Disk\0");
 11.1215 -    //status = RtlUnicodeStringPrintf(&buffer, L"XEN\\Disk&Ven_James&Prod_James&Rev_1.00\0");
 11.1216 -    status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
 11.1217 -
 11.1218 -    status = RtlUnicodeStringPrintf(&buffer, L"%02d\0", ChildDeviceData->DeviceIndex);
 11.1219 -    status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
 11.1220 -
 11.1221 -    status = RtlUnicodeStringPrintf(&buffer, L"GenDisk\0");
 11.1222 -    status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
 11.1223 -    status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
 11.1224 -
 11.1225 -    status = RtlUnicodeStringPrintf(&buffer, L"Xen PV Disk (%d)", ChildDeviceData->DeviceIndex);
 11.1226 -    status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
 11.1227 -    break;
 11.1228 -  case XENVBD_DEVICETYPE_CDROM:
 11.1229 -    WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_MASS_STORAGE);
 11.1230 -    WdfDeviceInitSetCharacteristics(ChildInit, FILE_READ_ONLY_DEVICE|FILE_REMOVABLE_MEDIA, TRUE);
 11.1231 +  PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
 11.1232  
 11.1233 -    status = RtlUnicodeStringPrintf(&buffer, L"XEN\\CDROM\0");
 11.1234 -    status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
 11.1235 -
 11.1236 -    status = RtlUnicodeStringPrintf(&buffer, L"%02d\0", ChildDeviceData->DeviceIndex);
 11.1237 -    status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
 11.1238 -
 11.1239 -    status = RtlUnicodeStringPrintf(&buffer, L"GenCdRom\0");
 11.1240 -    status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
 11.1241 -    status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
 11.1242 -
 11.1243 -    status = RtlUnicodeStringPrintf(&buffer, L"Xen PV CDROM (%d)\0", ChildDeviceData->DeviceIndex);
 11.1244 -    status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
 11.1245 -    break;
 11.1246 -  default:
 11.1247 -    // wtf?
 11.1248 -    break;
 11.1249 +  if (DeviceData->BusChangePending)
 11.1250 +  {
 11.1251 +    ScsiPortNotification(BusChangeDetected, DeviceData, 0);
 11.1252 +    DeviceData->BusChangePending = 0;
 11.1253    }
 11.1254 -
 11.1255 -  WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
 11.1256 -  
 11.1257 -  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&PdoAttributes, PXENVBD_CHILD_DEVICE_DATA);
 11.1258 -
 11.1259 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSCSI, IRP_MJ_SCSI, NULL, 0);
 11.1260 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpDEVICE_CONTROL, IRP_MJ_DEVICE_CONTROL, NULL, 0);
 11.1261 +  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusChangedTimer, 1000000);
 11.1262 +}
 11.1263  
 11.1264 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_CLEANUP, NULL, 0);
 11.1265 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_CLOSE, NULL, 0);
 11.1266 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_CREATE, NULL, 0);
 11.1267 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_DIRECTORY_CONTROL, NULL, 0);
 11.1268 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_FILE_SYSTEM_CONTROL, NULL, 0);
 11.1269 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_FLUSH_BUFFERS, NULL, 0);
 11.1270 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_LOCK_CONTROL, NULL, 0);
 11.1271 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_POWER, NULL, 0);
 11.1272 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_QUERY_EA, NULL, 0);
 11.1273 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_QUERY_INFORMATION, NULL, 0);
 11.1274 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_QUERY_SECURITY, NULL, 0);
 11.1275 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_QUERY_VOLUME_INFORMATION, NULL, 0);
 11.1276 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_READ, NULL, 0);
 11.1277 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_SET_INFORMATION, NULL, 0);
 11.1278 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_SET_SECURITY, NULL, 0);
 11.1279 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_SET_VOLUME_INFORMATION, NULL, 0);
 11.1280 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_SHUTDOWN, NULL, 0);
 11.1281 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_SYSTEM_CONTROL, NULL, 0);
 11.1282 -  WdfDeviceInitAssignWdmIrpPreprocessCallback(ChildInit, XenVbd_Child_PreprocessWdmIrpSomethingSomething, IRP_MJ_WRITE, NULL, 0);
 11.1283 +static BOOLEAN
 11.1284 +XenVbd_HwScsiInitialize(PVOID DeviceExtension)
 11.1285 +{
 11.1286 +  PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
 11.1287 +  unsigned int i, j;
 11.1288 +  NTSTATUS Status;
 11.1289 +  char **VbdDevices;
 11.1290 +  char *msg;
 11.1291 +  char buffer[128];
 11.1292 +  LARGE_INTEGER WaitTimeout;
 11.1293  
 11.1294 -  WdfDeviceInitSetIoType(ChildInit, WdfDeviceIoDirect);
 11.1295 -
 11.1296 -  //WdfDeviceInitSetPowerNotPageable(ChildInit);
 11.1297 +  KdPrint((__DRIVER_NAME " --> HwScsiInitialize\n"));
 11.1298 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 11.1299  
 11.1300 -  status = WdfDeviceCreate(&ChildInit, &PdoAttributes, &ChildDevice);
 11.1301 -  if (!NT_SUCCESS(status))
 11.1302 +  for (i = 0; i < SCSI_BUSES; i++)
 11.1303    {
 11.1304 -    KdPrint((__DRIVER_NAME "     WdfDeviceCreate status = %08X\n", status));
 11.1305 +    for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
 11.1306 +    {
 11.1307 +      DeviceData->BusData[i].TargetData[j].Present = 0;
 11.1308 +      DeviceData->BusData[i].TargetData[j].DeviceData = DeviceData;
 11.1309 +    }
 11.1310    }
 11.1311  
 11.1312 -  switch (ChildDeviceData->DeviceType)
 11.1313 -  {
 11.1314 -  case XENVBD_DEVICETYPE_DISK:
 11.1315 -    WDF_DEVICE_STATE_INIT(&DeviceState);
 11.1316 -    DeviceState.NotDisableable = WdfTrue;
 11.1317 -    WdfDeviceSetDeviceState(ChildDevice, &DeviceState);
 11.1318 -    WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFilePaging, TRUE);
 11.1319 -    WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileHibernation, TRUE);
 11.1320 -    WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileDump, TRUE);
 11.1321 -    break;
 11.1322 -  case XENVBD_DEVICETYPE_CDROM:
 11.1323 -    break;
 11.1324 -  }
 11.1325 -  *GetChildDeviceData(ChildDevice) = ChildDeviceData;
 11.1326 -
 11.1327 -  ChildDeviceData->FastPathUsed = 0;
 11.1328 -  ChildDeviceData->SlowPathUsed = 0;
 11.1329 -  ChildDeviceData->IrpAddedToList = 0;
 11.1330 -  ChildDeviceData->IrpRemovedFromList = 0;
 11.1331 -  ChildDeviceData->IrpAddedToRing = 0;
 11.1332 -  ChildDeviceData->IrpAddedToRingAtLastNotify = 0;
 11.1333 -  ChildDeviceData->IrpAddedToRingAtLastInterrupt = 0;
 11.1334 -  ChildDeviceData->IrpAddedToRingAtLastDpc = 0;
 11.1335 -  ChildDeviceData->IrpRemovedFromRing = 0;
 11.1336 -  ChildDeviceData->IrpCompleted = 0;
 11.1337 -
 11.1338 -  ChildDeviceData->Device = ChildDevice;
 11.1339 -  
 11.1340 -  KeInitializeSpinLock(&ChildDeviceData->Lock);
 11.1341 -  KeInitializeSpinLock(&ChildDeviceData->IrpListLock);
 11.1342 -  InitializeListHead(&ChildDeviceData->IrpListHead);
 11.1343 -
 11.1344 -  ChildDeviceData->shadow = ExAllocatePoolWithTag(NonPagedPool, sizeof(blkif_shadow_t) * BLK_RING_SIZE, XENVBD_POOL_TAG);
 11.1345 -  memset(ChildDeviceData->shadow, 0, sizeof(blkif_shadow_t) * BLK_RING_SIZE);
 11.1346 -  //KdPrint((__DRIVER_NAME "     Allocated shadow = %08x\n", ChildDeviceData->shadow));
 11.1347 -  for (i = 0; i < BLK_RING_SIZE; i++)
 11.1348 -    ChildDeviceData->shadow[i].req.id = i + 1;
 11.1349 -  ChildDeviceData->shadow_free = 0;
 11.1350 -  ChildDeviceData->shadow[BLK_RING_SIZE - 1].req.id = 0x0fffffff;
 11.1351 -
 11.1352 -  WDF_DPC_CONFIG_INIT(&DpcConfig, XenVbd_DpcThreadProc);
 11.1353 -  WDF_OBJECT_ATTRIBUTES_INIT(&DpcObjectAttributes);
 11.1354 -  DpcObjectAttributes.ParentObject = ChildDevice;
 11.1355 -  WdfDpcCreate(&DpcConfig, &DpcObjectAttributes, &ChildDeviceData->Dpc);
 11.1356 -
 11.1357 -  KdPrint((__DRIVER_NAME " <-- ChildListCreateDevice (status = %08x)\n", status));
 11.1358 -
 11.1359 -  return status;
 11.1360 -}
 11.1361 -
 11.1362 -
 11.1363 -// if the list isn't empty, then we should always add the request to the end of the list and then try and clear the list onto the ring
 11.1364 -
 11.1365 -// Call with device lock held
 11.1366 -static VOID
 11.1367 -XenVbd_PutIrpOnRing(WDFDEVICE Device, PIRP Irp)
 11.1368 -{
 11.1369 -  char *DataBuffer;
 11.1370 -  PSCSI_REQUEST_BLOCK Srb;
 11.1371 -  PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
 11.1372 -  PXENVBD_CHILD_DEVICE_DATA ChildDeviceData;
 11.1373 -  blkif_request_t *req;
 11.1374 -  int i;
 11.1375 -  int j;
 11.1376 -  int BlockCount;
 11.1377 -  int sect_offset;
 11.1378 -  PUCHAR ptr;
 11.1379 -  int sum;
 11.1380 -
 11.1381 -  ChildDeviceData = *GetChildDeviceData(Device);
 11.1382 -
 11.1383 -  if (ChildDeviceData->DeviceType == XENVBD_DEVICETYPE_CDROM)
 11.1384 -    KdPrint((__DRIVER_NAME " --> PutIrpOnRing\n"));
 11.1385 -
 11.1386 -  if (RING_FULL(&ChildDeviceData->Ring))
 11.1387 -  {
 11.1388 -    KdPrint((__DRIVER_NAME "     RING IS FULL - EXPECT BADNESS\n"));
 11.1389 -  }
 11.1390 -
 11.1391 -  req = RING_GET_REQUEST(&ChildDeviceData->Ring, ChildDeviceData->Ring.req_prod_pvt);
 11.1392 -
 11.1393 -  //KdPrint((__DRIVER_NAME "     req = %08x\n", req));
 11.1394 +  DeviceData->XenDeviceData->WatchContext = DeviceExtension;
 11.1395 +  KeMemoryBarrier();
 11.1396 +  DeviceData->XenDeviceData->WatchHandler = XenVbd_WatchHandler;
 11.1397  
 11.1398 -  Srb = irpSp->Parameters.Scsi.Srb;
 11.1399 -
 11.1400 -  req->sector_number = (Srb->Cdb[2] << 24) | (Srb->Cdb[3] << 16) | (Srb->Cdb[4] << 8) | Srb->Cdb[5];
 11.1401 -  BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
 11.1402 -
 11.1403 -  req->id = GET_ID_FROM_FREELIST(ChildDeviceData);
 11.1404 -
 11.1405 -  if (req->id == 0x0fffffff)
 11.1406 +  KeInitializeEvent(&DeviceData->WaitDevicesEvent, SynchronizationEvent, FALSE);  
 11.1407 +  DeviceData->EnumeratedDevices = 0;
 11.1408 +  if (DeviceData->XenDeviceData->AutoEnumerate)
 11.1409    {
 11.1410 -    KdPrint((__DRIVER_NAME "     Something is horribly wrong in PutIrpOnRing\n"));
 11.1411 +    msg = DeviceData->XenDeviceData->XenBusInterface.List(XBT_NIL, "device/vbd", &VbdDevices);
 11.1412 +    if (!msg) {
 11.1413 +      for (i = 0; VbdDevices[i]; i++)
 11.1414 +      {
 11.1415 +        KdPrint((__DRIVER_NAME "     found existing vbd device %s\n", VbdDevices[i]));
 11.1416 +        RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/vbd/%s/state", VbdDevices[i]);
 11.1417 +        XenVbd_WatchHandler(buffer, DeviceData);
 11.1418 +        //ExFreePoolWithTag(bdDevices[i], XENPCI_POOL_TAG);
 11.1419 +      }
 11.1420 +      KdPrint((__DRIVER_NAME "     Waiting for %d devices to be enumerated\n", i));
 11.1421 +      while (DeviceData->EnumeratedDevices < i)
 11.1422 +      {
 11.1423 +        WaitTimeout.QuadPart = -600000000;
 11.1424 +        if (KeWaitForSingleObject(&DeviceData->WaitDevicesEvent, Executive, KernelMode, FALSE, &WaitTimeout) == STATUS_TIMEOUT)
 11.1425 +        {
 11.1426 +          KdPrint((__DRIVER_NAME "     Wait timed out\n"));
 11.1427 +          break;
 11.1428 +        }
 11.1429 +        KdPrint((__DRIVER_NAME "     %d out of %d devices enumerated\n", DeviceData->EnumeratedDevices, i));
 11.1430 +      }  
 11.1431 +    }
 11.1432 +    ScsiPortNotification(BusChangeDetected, DeviceData, 0);
 11.1433 +    DeviceData->BusChangePending = 0;
 11.1434    }
 11.1435 -
 11.1436 -  //KdPrint((__DRIVER_NAME "     id = %d\n", req->id));
 11.1437 -
 11.1438 -  req->handle = 0;
 11.1439 -  req->operation = (Srb->Cdb[0] == SCSIOP_READ)?BLKIF_OP_READ:BLKIF_OP_WRITE;
 11.1440 -  ChildDeviceData->shadow[req->id].Irp = Irp;
 11.1441 -
 11.1442 -  KdPrint((__DRIVER_NAME "     %s: Sector = %d, Length = %d\n", (Srb->Cdb[0] == SCSIOP_READ)?"READ":"WRITE", (int)(req->sector_number), BlockCount * 512));
 11.1443 -
 11.1444 -  if (0) //(MmGetMdlByteOffset(Irp->MdlAddress) & 0x1ff) == 0) // 0x1ff shouldn't be hardcoded...
 11.1445 -  {
 11.1446 -    // fast path - zero copy
 11.1447 -    ChildDeviceData->shadow[req->id].Mdl = Irp->MdlAddress;
 11.1448 -    ChildDeviceData->shadow[req->id].Buf = NULL; // we don't need the virtual address
 11.1449 -    ChildDeviceData->FastPathUsed++;
 11.1450 -  }
 11.1451 -  else
 11.1452 -  {
 11.1453 -    // slow path - copy to bounce buffer
 11.1454 -    ChildDeviceData->shadow[req->id].Mdl = AllocatePages((BlockCount * ChildDeviceData->BytesPerSector + PAGE_SIZE - 1) / PAGE_SIZE);
 11.1455 -    //ChildDeviceData->shadow[req->id].Buf = MmGetMdlVirtualAddress(ChildDeviceData->shadow[req->id].Mdl);
 11.1456 -    ChildDeviceData->shadow[req->id].Buf = MmGetSystemAddressForMdlSafe(ChildDeviceData->shadow[req->id].Mdl, HighPagePriority);
 11.1457 -    if (ChildDeviceData->shadow[req->id].Buf == NULL)
 11.1458 -    {
 11.1459 -      KdPrint((__DRIVER_NAME "     MmGetSystemAddressForMdlSafe returned NULL in PutIrpOnRing\n"));
 11.1460 -    }
 11.1461 -    ChildDeviceData->SlowPathUsed++;
 11.1462 -  }
 11.1463 +  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusChangedTimer, 1000000);
 11.1464  
 11.1465 -/*
 11.1466 -  if (((ChildDeviceData->FastPathUsed + ChildDeviceData->SlowPathUsed) & 0x3F) == 0)
 11.1467 -  {
 11.1468 -    KdPrint((__DRIVER_NAME "     Fast Path = %d, Slow Path = %d\n", ChildDeviceData->FastPathUsed, ChildDeviceData->SlowPathUsed));
 11.1469 -//    KdPrint((__DRIVER_NAME "     AddedToList = %d, RemovedFromList = %d, AddedToRing = %d, AddedToRingAtLastNotify = %d, AddedToRingAtLastInterrupt = %d, AddedToRingAtLastDpc = %d, RemovedFromRing = %d, IrpCompleted = %d\n", ChildDeviceData->IrpAddedToList, ChildDeviceData->IrpRemovedFromList, ChildDeviceData->IrpAddedToRing, ChildDeviceData->IrpAddedToRingAtLastNotify, ChildDeviceData->IrpAddedToRingAtLastInterrupt, ChildDeviceData->IrpAddedToRingAtLastDpc, ChildDeviceData->IrpRemovedFromRing, ChildDeviceData->IrpCompleted));
 11.1470 -  }
 11.1471 -*/
 11.1472 -
 11.1473 -  if (Srb->Cdb[0] == SCSIOP_WRITE && ChildDeviceData->shadow[req->id].Buf != NULL)
 11.1474 -  {
 11.1475 -    DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
 11.1476 -    if (DataBuffer == NULL)
 11.1477 -      KdPrint((__DRIVER_NAME "     MmGetSystemAddressForMdlSafe failed in PutIrpOnRing\n"));
 11.1478 -    memcpy(ChildDeviceData->shadow[req->id].Buf, DataBuffer, BlockCount * ChildDeviceData->BytesPerSector);
 11.1479 -    for (i = 0, sum = 0, ptr = ChildDeviceData->shadow[req->id].Buf; i < BlockCount * ChildDeviceData->BytesPerSector; i++, ptr++)
 11.1480 -    {
 11.1481 -      sum += *ptr;
 11.1482 -    }
 11.1483 -    KdPrint((__DRIVER_NAME "     WRITE sum = %08X\n", sum));
 11.1484 -  }
 11.1485 -
 11.1486 +  KdPrint((__DRIVER_NAME " <-- HwScsiInitialize\n"));
 11.1487  
 11.1488 -  sect_offset = MmGetMdlByteOffset(ChildDeviceData->shadow[req->id].Mdl) >> 9;
 11.1489 -
 11.1490 -  KdPrint((__DRIVER_NAME "     Pages = %d, Page[0] = %08X, Offset = %08X\n", ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(ChildDeviceData->shadow[req->id].Mdl), MmGetMdlByteCount(ChildDeviceData->shadow[req->id].Mdl)), *MmGetMdlPfnArray(ChildDeviceData->shadow[req->id].Mdl), MmGetMdlByteOffset(ChildDeviceData->shadow[req->id].Mdl)));
 11.1491 -
 11.1492 -  for (i = 0, req->nr_segments = 0; i < BlockCount; req->nr_segments++)
 11.1493 -  {
 11.1494 -    req->seg[req->nr_segments].gref = GntTblInterface.GrantAccess(0, MmGetMdlPfnArray(ChildDeviceData->shadow[req->id].Mdl)[req->nr_segments], FALSE);
 11.1495 -    req->seg[req->nr_segments].first_sect = sect_offset;
 11.1496 -    for (j = sect_offset; i < BlockCount && j < PAGE_SIZE / ChildDeviceData->BytesPerSector; j++, i++)
 11.1497 -      req->seg[req->nr_segments].last_sect = (uint8_t)j;
 11.1498 -    sect_offset = 0;
 11.1499 -  }
 11.1500 -  KdPrint((__DRIVER_NAME "     Segments = %d\n", req->nr_segments));
 11.1501 -
 11.1502 -  ChildDeviceData->shadow[req->id].req = *req;
 11.1503 -
 11.1504 -  ChildDeviceData->Ring.req_prod_pvt++;
 11.1505 -
 11.1506 -  ChildDeviceData->IrpAddedToRing++;
 11.1507 -
 11.1508 -//  if (ChildDeviceData->DeviceType == XENVBD_DEVICETYPE_CDROM)
 11.1509 -//    KdPrint((__DRIVER_NAME " <-- PutIrpOnRing\n"));
 11.1510 +  return TRUE;
 11.1511  }
 11.1512  
 11.1513  static ULONG
 11.1514 -XenVBD_FillModePage(PXENVBD_CHILD_DEVICE_DATA ChildDeviceData, UCHAR PageCode, PUCHAR DataBuffer, ULONG BufferLength, PULONG Offset)
 11.1515 +XenVbd_FillModePage(PXENVBD_DEVICE_DATA DeviceData, UCHAR PageCode, PUCHAR DataBuffer, ULONG BufferLength, PULONG Offset)
 11.1516  {
 11.1517    PMODE_RIGID_GEOMETRY_PAGE ModeRigidGeometry;
 11.1518  
 11.1519 -//  KdPrint((__DRIVER_NAME " --> FillModePage (PageCode = %d)\n", PageCode));
 11.1520 -
 11.1521    switch (PageCode)
 11.1522    {
 11.1523 +/*
 11.1524    case MODE_PAGE_RIGID_GEOMETRY:
 11.1525 -    if (ChildDeviceData->DeviceType == XENVBD_DEVICETYPE_DISK)
 11.1526 +    if (DeviceData->ScsiData->DeviceType == XENVBD_DEVICETYPE_CDROM)
 11.1527      {
 11.1528      KdPrint((__DRIVER_NAME "     MODE_PAGE_RIGID_GEOMETRY\n"));
 11.1529 -    *Offset += sizeof(MODE_RIGID_GEOMETRY_PAGE);
 11.1530 -    if (*Offset > BufferLength)
 11.1531 -      break;
 11.1532 +    if (*Offset + sizeof(MODE_RIGID_GEOMETRY_PAGE) > BufferLength)
 11.1533 +      return 1;
 11.1534      ModeRigidGeometry = (PMODE_RIGID_GEOMETRY_PAGE)(DataBuffer + *Offset);
 11.1535      memset(ModeRigidGeometry, 0, sizeof(MODE_RIGID_GEOMETRY_PAGE));
 11.1536      ModeRigidGeometry->PageCode = PageCode;
 11.1537      ModeRigidGeometry->PageSavable = 0;
 11.1538      ModeRigidGeometry->PageLength = sizeof(MODE_RIGID_GEOMETRY_PAGE);
 11.1539 -    ModeRigidGeometry->NumberOfCylinders[0] = (ChildDeviceData->Geometry.Cylinders.LowPart >> 16) & 0xFF;
 11.1540 -    ModeRigidGeometry->NumberOfCylinders[1] = (ChildDeviceData->Geometry.Cylinders.LowPart >> 8) & 0xFF;
 11.1541 -    ModeRigidGeometry->NumberOfCylinders[2] = (ChildDeviceData->Geometry.Cylinders.LowPart >> 0) & 0xFF;
 11.1542 -    ModeRigidGeometry->NumberOfHeads = ChildDeviceData->Geometry.TracksPerCylinder;
 11.1543 +    ModeRigidGeometry->NumberOfCylinders[0] = (DeviceData->Geometry.Cylinders.LowPart >> 16) & 0xFF;
 11.1544 +    ModeRigidGeometry->NumberOfCylinders[1] = (DeviceData->Geometry.Cylinders.LowPart >> 8) & 0xFF;
 11.1545 +    ModeRigidGeometry->NumberOfCylinders[2] = (DeviceData->Geometry.Cylinders.LowPart >> 0) & 0xFF;
 11.1546 +    ModeRigidGeometry->NumberOfHeads = DeviceData->Geometry.TracksPerCylinder;
 11.1547      //ModeRigidGeometry->LandZoneCyclinder = 0;
 11.1548      ModeRigidGeometry->RoataionRate[0] = 0x05;
 11.1549      ModeRigidGeometry->RoataionRate[0] = 0x39;
 11.1550 +    *Offset += sizeof(MODE_RIGID_GEOMETRY_PAGE);
 11.1551      }
 11.1552      break;
 11.1553 +*/
 11.1554    case MODE_PAGE_FAULT_REPORTING:
 11.1555      break;
 11.1556    default:
 11.1557      break;
 11.1558    }
 11.1559 -
 11.1560 -//  KdPrint((__DRIVER_NAME " <-- FillModePage\n", PageCode));
 11.1561 -
 11.1562    return 0;
 11.1563  }
 11.1564  
 11.1565 -static NTSTATUS
 11.1566 -XenVbd_Child_PreprocessWdmIrpDEVICE_CONTROL(WDFDEVICE Device, PIRP Irp)
 11.1567 +// Call with device lock held
 11.1568 +static VOID
 11.1569 +XenVbd_PutSrbOnRing(PXENVBD_TARGET_DATA TargetData, PSCSI_REQUEST_BLOCK Srb)
 11.1570  {
 11.1571 -  NTSTATUS Status;
 11.1572 -  PIO_STACK_LOCATION IrpStack;
 11.1573 -  PSCSI_ADDRESS ScsiAddress;
 11.1574 -  PXENVBD_CHILD_DEVICE_DATA ChildDeviceData;  
 11.1575 -  PSTORAGE_PROPERTY_QUERY Spq;
 11.1576 -  PSTORAGE_ADAPTER_DESCRIPTOR Sad;
 11.1577 -  PSTORAGE_DEVICE_DESCRIPTOR Sdd;
 11.1578 -  PSTORAGE_DEVICE_ID_DESCRIPTOR Sdid;
 11.1579 -  PSTORAGE_IDENTIFIER Si;
 11.1580 -//  ULONG Information;
 11.1581 -  int StructEndOffset;
 11.1582 +  //PUCHAR DataBuffer;
 11.1583 +  blkif_request_t *req;
 11.1584 +  int i;
 11.1585 +  int j;
 11.1586 +  int BlockCount;
 11.1587 +  int sect_offset;
 11.1588 +  PVOID CurrentVirtual;
 11.1589 +  ULONG CurrentLength;
 11.1590 +  ULONG SegmentLength;
 11.1591 +  SCSI_PHYSICAL_ADDRESS PageAddress;
 11.1592 +  int Iterations;
 11.1593 +  PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)TargetData->DeviceData;
 11.1594  
 11.1595 -  KdPrint((__DRIVER_NAME " --> PreprocessWdmIrpDEVICE_CONTROL\n"));
 11.1596 +// can use SRB_STATUS_BUSY to push the SRB back to windows...
 11.1597  
 11.1598 -  ChildDeviceData = *GetChildDeviceData(Device);
 11.1599 +//  KdPrint((__DRIVER_NAME " --> PutSrbOnRing\n"));
 11.1600  
 11.1601 -  IrpStack = IoGetCurrentIrpStackLocation(Irp);
 11.1602 -
 11.1603 -  switch (IrpStack->Parameters.DeviceIoControl.IoControlCode)
 11.1604 +  if (RING_FULL(&TargetData->Ring))
 11.1605    {
 11.1606 -  case IOCTL_SCSI_GET_ADDRESS:
 11.1607 -    KdPrint((__DRIVER_NAME "     IOCTL_SCSI_GET_ADDRESS\n"));
 11.1608 -    Irp->IoStatus.Information = sizeof(SCSI_ADDRESS);
 11.1609 -    if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(SCSI_ADDRESS))
 11.1610 -    {
 11.1611 -      ScsiAddress = (PSCSI_ADDRESS)Irp->AssociatedIrp.SystemBuffer;
 11.1612 -      ScsiAddress->Length = sizeof(SCSI_ADDRESS);
 11.1613 -      ScsiAddress->PortNumber = 0;
 11.1614 -      ScsiAddress->PathId = 0;
 11.1615 -      ScsiAddress->TargetId = 0;
 11.1616 -      ScsiAddress->Lun = 0;
 11.1617 -      Status = STATUS_SUCCESS;
 11.1618 -      Irp->IoStatus.Status = Status;
 11.1619 -      IoCompleteRequest(Irp, IO_NO_INCREMENT);      
 11.1620 -    }
 11.1621 -    else
 11.1622 -    {
 11.1623 -      KdPrint((__DRIVER_NAME "     (Buffer size too small @ %d\n", IrpStack->Parameters.DeviceIoControl.OutputBufferLength));    
 11.1624 -    }
 11.1625 -    break;
 11.1626 -  case IOCTL_STORAGE_QUERY_PROPERTY:
 11.1627 -    KdPrint((__DRIVER_NAME "     IOCTL_STORAGE_QUERY_PROPERTY\n"));    
 11.1628 -    Spq = (PSTORAGE_PROPERTY_QUERY)Irp->AssociatedIrp.SystemBuffer;
 11.1629 -    if (Spq->PropertyId == StorageAdapterProperty && Spq->QueryType == PropertyStandardQuery)
 11.1630 -    {
 11.1631 -      KdPrint((__DRIVER_NAME "     PropertyId = StorageAdapterProperty, QueryType = PropertyStandardQuery\n"));
 11.1632 -      Irp->IoStatus.Information = 0;
 11.1633 -      if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength >= 8)
 11.1634 -      {
 11.1635 -        Irp->IoStatus.Information = 8;
 11.1636 -        Sad = (PSTORAGE_ADAPTER_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
 11.1637 -        Sad->Version = 1;
 11.1638 -        Sad->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
 11.1639 -        if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength >= Sad->Size)
 11.1640 -        {
 11.1641 -          Irp->IoStatus.Information = Sad->Size;
 11.1642 -          Sad->MaximumTransferLength = 45056;
 11.1643 -          Sad->MaximumPhysicalPages = 11;
 11.1644 -          Sad->AlignmentMask = 0;
 11.1645 -          Sad->AdapterUsesPio = FALSE;
 11.1646 -          Sad->AdapterScansDown = FALSE;
 11.1647 -          Sad->CommandQueueing = FALSE;
 11.1648 -          Sad->AcceleratedTransfer = FALSE;
 11.1649 -          Sad->BusType = BusTypeScsi;
 11.1650 -          Sad->BusMajorVersion = 0;
 11.1651 -          Sad->BusMinorVersion = 0;
 11.1652 -        }
 11.1653 -      }
 11.1654 -      Status = STATUS_SUCCESS;
 11.1655 -      Irp->IoStatus.Status = Status;
 11.1656 -      IoCompleteRequest(Irp, IO_NO_INCREMENT);      
 11.1657 -    }
 11.1658 -    else if (Spq->PropertyId == StorageDeviceProperty && Spq->QueryType == PropertyStandardQuery)
 11.1659 -    {
 11.1660 -      KdPrint((__DRIVER_NAME "     PropertyId = StorageDeviceProperty, QueryType = PropertyStandardQuery\n"));
 11.1661 -      Irp->IoStatus.Information = 0;
 11.1662 -      if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength >= 8)
 11.1663 -      {
 11.1664 -        Irp->IoStatus.Information = 8;
 11.1665 -        Sdd = (PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
 11.1666 -        Sdd->Version = 1;
 11.1667 -        Sdd->Size = &Sdd->RawDeviceProperties[36] - (PUCHAR)Sdd + 1;
 11.1668 -        // 0       0        1         2       3
 11.1669 -        // 0       7        5         4       1
 11.1670 -        //"VENDOR\0PRODUCT\0Revision\0Serial\0"
 11.1671 -        if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength >= Sdd->Size)
 11.1672 -        {
 11.1673 -          Irp->IoStatus.Information = Sdd->Size;
 11.1674 -          switch (ChildDeviceData->DeviceType)
 11.1675 -          { 
 11.1676 -          case XENVBD_DEVICETYPE_DISK:
 11.1677 -            Sdd->DeviceType = DIRECT_ACCESS_DEVICE;
 11.1678 -            Sdd->DeviceTypeModifier = 0x00;
 11.1679 -            Sdd->RemovableMedia = FALSE;
 11.1680 -            break;
 11.1681 -          case XENVBD_DEVICETYPE_CDROM:
 11.1682 -            Sdd->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
 11.1683 -            Sdd->DeviceTypeModifier = 0x00;
 11.1684 -            Sdd->RemovableMedia = TRUE;
 11.1685 -            break;
 11.1686 -          default:
 11.1687 -            // wtf
 11.1688 -            break;
 11.1689 -          }
 11.1690 -          Sdd->CommandQueueing = FALSE;
 11.1691 -          StructEndOffset = Sdd->RawDeviceProperties - (PUCHAR)Sdd;
 11.1692 -          Sdd->VendorIdOffset = StructEndOffset + 0;
 11.1693 -          Sdd->ProductIdOffset = StructEndOffset + 7;
 11.1694 -          Sdd->ProductRevisionOffset = StructEndOffset + 15;
 11.1695 -          Sdd->SerialNumberOffset = StructEndOffset + 24;
 11.1696 -          Sdd->BusType = BusTypeScsi;
 11.1697 -          Sdd->RawPropertiesLength = 36;
 11.1698 -          memcpy(Sdd->RawDeviceProperties, "VENDOR\0PRODUCT\0Revision\0Serial99999\0", 36);
 11.1699 -        }
 11.1700 -      }
 11.1701 -      Status = STATUS_SUCCESS;
 11.1702 -      Irp->IoStatus.Status = Status;
 11.1703 -      IoCompleteRequest(Irp, IO_NO_INCREMENT);      
 11.1704 -    }
 11.1705 -    else if (Spq->PropertyId == StorageDeviceIdProperty && Spq->QueryType == PropertyStandardQuery)
 11.1706 -    {
 11.1707 -      KdPrint((__DRIVER_NAME "     PropertyId = StorageDeviceIdProperty, QueryType = PropertyStandardQuery\n"));
 11.1708 -      Irp->IoStatus.Information = 0;
 11.1709 -      if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength >= 8)
 11.1710 -      {
 11.1711 -        Irp->IoStatus.Information = 8;
 11.1712 -        Sdid = (PSTORAGE_DEVICE_ID_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
 11.1713 -        Sdid->Version = 1;
 11.1714 -        Si = (PSTORAGE_IDENTIFIER)Sdid->Identifiers;
 11.1715 -        Sdid->Size = &Si->Identifier[8] - (PUCHAR)Sdid + 1;
 11.1716 -        if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength >= Sdid->Size)
 11.1717 -        {
 11.1718 -          Irp->IoStatus.Information = Sdid->Size;
 11.1719 -          Sdid->NumberOfIdentifiers = 1;
 11.1720 -          Si->CodeSet = StorageIdCodeSetAscii;
 11.1721 -          Si->Type = StorageIdTypeScsiNameString;
 11.1722 -          //Si->CodeSet = StorageIdCodeSetBinary;
 11.1723 -          //Si->Type = StorageIdTypeEUI64;
 11.1724 -          Si->IdentifierSize = 9;
 11.1725 -          Si->NextOffset = 0;
 11.1726 -          Si->Association = StorageIdAssocPort;
 11.1727 -          Si->Identifier[0] = 'S';
 11.1728 -          Si->Identifier[1] = 'e';
 11.1729 -          Si->Identifier[2] = 'r';
 11.1730 -          Si->Identifier[3] = 'i';
 11.1731 -          Si->Identifier[4] = 'a';
 11.1732 -          Si->Identifier[5] = 'l';
 11.1733 -          Si->Identifier[6] = '9';
 11.1734 -          Si->Identifier[7] = '9';
 11.1735 -          Si->Identifier[6] = '9';
 11.1736 -          Si->Identifier[7] = '9';
 11.1737 -          Si->Identifier[8] = '9';
 11.1738 -          //Si->Identifier[8] = 0;
 11.1739 -        }
 11.1740 -      }
 11.1741 -      Status = STATUS_SUCCESS;
 11.1742 -      Irp->IoStatus.Status = Status;
 11.1743 -      IoCompleteRequest(Irp, IO_NO_INCREMENT);      
 11.1744 -    }
 11.1745 -    else
 11.1746 -    {
 11.1747 -      KdPrint((__DRIVER_NAME "     Not Implemented\n"));
 11.1748 -      switch (Spq->PropertyId)
 11.1749 -      {
 11.1750 -      case StorageDeviceProperty:
 11.1751 -        KdPrint((__DRIVER_NAME "     StorageDeviceProperty\n"));
 11.1752 -        break;        
 11.1753 -      case StorageAccessAlignmentProperty:
 11.1754 -        KdPrint((__DRIVER_NAME "     StorageAccessAlignmentProperty\n"));
 11.1755 -        break;
 11.1756 -      case StorageAdapterProperty:
 11.1757 -        KdPrint((__DRIVER_NAME "     StorageAdapterProperty\n"));
 11.1758 -        break;
 11.1759 -      case StorageDeviceIdProperty:
 11.1760 -        KdPrint((__DRIVER_NAME "     StorageDeviceIdProperty\n"));
 11.1761 -        break;
 11.1762 -      case StorageDeviceUniqueIdProperty:
 11.1763 -        KdPrint((__DRIVER_NAME "     StorageDeviceUniqueIdProperty\n"));
 11.1764 -        break;
 11.1765 -      case StorageDeviceWriteCacheProperty:
 11.1766 -        KdPrint((__DRIVER_NAME "     StorageDeviceWriteCacheProperty\n"));
 11.1767 -        break;
 11.1768 -      default:
 11.1769 -        KdPrint((__DRIVER_NAME "     Unknown Property %08x\n", Spq->PropertyId));
 11.1770 -        break;
 11.1771 -      }
 11.1772 -      switch (Spq->QueryType)
 11.1773 -      {
 11.1774 -      case PropertyStandardQuery:
 11.1775 -        KdPrint((__DRIVER_NAME "     PropertyStandardQuery\n"));
 11.1776 -        break;        
 11.1777 -      case PropertyExistsQuery:
 11.1778 -        KdPrint((__DRIVER_NAME "     PropertyExistsQuery\n"));
 11.1779 -        break;        
 11.1780 -      default:
 11.1781 -        KdPrint((__DRIVER_NAME "     Unknown Query %08x\n", Spq->QueryType));
 11.1782 -        break;
 11.1783 -      }
 11.1784 -      Status = STATUS_NOT_IMPLEMENTED;
 11.1785 -      Irp->IoStatus.Status = Status;
 11.1786 -      IoCompleteRequest(Irp, IO_NO_INCREMENT);      
 11.1787 -    }
 11.1788 -    break;
 11.1789 -  // http://www.osronline.com/article.cfm?article=229
 11.1790 -  // 0x00560030 device = 0x56, Function = 0x00c = 
 11.1791 -/*
 11.1792 -  case IOCTL_DISK_GET_DRIVE_GEOMETRY:
 11.1793 -    KdPrint((__DRIVER_NAME "     IOCTL_DISK_GET_DRIVE_GEOMETRY\n"));
 11.1794 -    memcpy(Irp->AssociatedIrp.SystemBuffer, &ChildDeviceData->Geometry, sizeof(DISK_GEOMETRY));
 11.1795 -    Status = STATUS_SUCCESS;
 11.1796 -    Irp->IoStatus.Status = Status;
 11.1797 -    Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
 11.1798 -    IoCompleteRequest(Irp, IO_NO_INCREMENT);      
 11.1799 -    break;
 11.1800 -*/
 11.1801 -  case FT_BALANCED_READ_MODE: // just pretend we know what this is...
 11.1802 -    KdPrint((__DRIVER_NAME "     FT_BALANCED_READ_MODE\n"));
 11.1803 -    Status = STATUS_SUCCESS;
 11.1804 -    Irp->IoStatus.Status = Status;
 11.1805 -    IoCompleteRequest(Irp, IO_NO_INCREMENT);      
 11.1806 -    break;
 11.1807 -  default:
 11.1808 -    KdPrint((__DRIVER_NAME "     Control Code = %08x\n", IrpStack->Parameters.DeviceIoControl.IoControlCode));
 11.1809 -    Status = STATUS_NOT_IMPLEMENTED;
 11.1810 -    Irp->IoStatus.Status = Status;
 11.1811 -    IoCompleteRequest(Irp, IO_NO_INCREMENT);      
 11.1812 +    KdPrint((__DRIVER_NAME "     RING IS FULL - EXPECT BADNESS\n"));
 11.1813 +    // TODO: Fail badly here
 11.1814    }
 11.1815  
 11.1816 -  KdPrint((__DRIVER_NAME " <-- PreprocessWdmIrpDEVICE_CONTROL\n"));
 11.1817 +  req = RING_GET_REQUEST(&TargetData->Ring, TargetData->Ring.req_prod_pvt);
 11.1818  
 11.1819 -  return Status;
 11.1820 +  req->sector_number = (Srb->Cdb[2] << 24) | (Srb->Cdb[3] << 16) | (Srb->Cdb[4] << 8) | Srb->Cdb[5];
 11.1821 +  BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
 11.1822 +
 11.1823 +  req->id = GET_ID_FROM_FREELIST(TargetData);
 11.1824 +
 11.1825 +  if (req->id == 0x0fffffff)
 11.1826 +  {
 11.1827 +    KdPrint((__DRIVER_NAME "     Something is horribly wrong in PutSrbOnRing\n"));
 11.1828 +  }
 11.1829 +
 11.1830 +  req->handle = 0;
 11.1831 +  req->operation = (Srb->Cdb[0] == SCSIOP_READ)?BLKIF_OP_READ:BLKIF_OP_WRITE;
 11.1832 +  TargetData->shadow[req->id].Srb = Srb;
 11.1833 +
 11.1834 +//  KdPrint((__DRIVER_NAME "     DataBuffer = %08X\n", Srb->DataBuffer));
 11.1835 +//  KdPrint((__DRIVER_NAME "     BlockCount = %08X\n", BlockCount));
 11.1836 +
 11.1837 +  req->nr_segments = (BlockCount * TargetData->BytesPerSector + PAGE_SIZE - 1) / PAGE_SIZE;
 11.1838 +//  KdPrint((__DRIVER_NAME "     req->nr_segments = %08X\n", req->nr_segments));
 11.1839 +
 11.1840 +  for (i = 0; i < req->nr_segments; i++)
 11.1841 +  {
 11.1842 +    req->seg[i].gref = DeviceData->XenDeviceData->GntTblInterface.GrantAccess(0, MmGetMdlPfnArray(TargetData->shadow[req->id].Mdl)[i], FALSE);
 11.1843 +    req->seg[i].first_sect = 0;
 11.1844 +    if (i == req->nr_segments - 1)
 11.1845 +      req->seg[i].last_sect = (BlockCount - 1) % (PAGE_SIZE / TargetData->BytesPerSector);
 11.1846 +    else
 11.1847 +      req->seg[i].last_sect = PAGE_SIZE / TargetData->BytesPerSector - 1;
 11.1848 +//    KdPrint((__DRIVER_NAME "     Page %d, first_sect = %d, last_sect = %d\n", i, req->seg[i].first_sect, req->seg[i].last_sect));
 11.1849 +  }
 11.1850 +  if (Srb->Cdb[0] == SCSIOP_WRITE)
 11.1851 +    memcpy(TargetData->shadow[req->id].Buf, Srb->DataBuffer, BlockCount * TargetData->BytesPerSector);
 11.1852 +  TargetData->shadow[req->id].req = *req;
 11.1853 +  TargetData->Ring.req_prod_pvt++;
 11.1854 +
 11.1855 +//  KdPrint((__DRIVER_NAME " <-- PutSrbOnRing\n"));
 11.1856  }
 11.1857  
 11.1858 -static NTSTATUS
 11.1859 -XenVbd_Child_PreprocessWdmIrpSomethingSomething(WDFDEVICE Device, PIRP Irp)
 11.1860 +static BOOLEAN
 11.1861 +XenVbd_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
 11.1862  {
 11.1863 -  NTSTATUS Status;
 11.1864 -  PIO_STACK_LOCATION IrpStack;
 11.1865 -
 11.1866 -  KdPrint((__DRIVER_NAME " --> XenVbd_Child_PreprocessWdmIrpSomethingSomething\n"));
 11.1867 -
 11.1868 -  IrpStack = IoGetCurrentIrpStackLocation(Irp);
 11.1869 -  KdPrint((__DRIVER_NAME "     Major = %02X, Minor = %02X\n", IrpStack->MajorFunction, IrpStack->MinorFunction));
 11.1870 -
 11.1871 -  IoSkipCurrentIrpStackLocation(Irp);
 11.1872 -
 11.1873 -  Status = WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
 11.1874 -
 11.1875 -  KdPrint((__DRIVER_NAME " <-- XenVbd_Child_PreprocessWdmIrpSomethingSomething\n"));
 11.1876 -
 11.1877 -  return Status;
 11.1878 -}
 11.1879 +  PUCHAR DataBuffer;
 11.1880 +  PCDB cdb;
 11.1881 +  PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
 11.1882 +  PXENVBD_TARGET_DATA TargetData;
 11.1883 +  unsigned int i;
 11.1884 +  KIRQL KIrql;
 11.1885 +  int notify;
 11.1886 +  SCSI_PHYSICAL_ADDRESS ScsiPhysicalAddress;
 11.1887 +  ULONG Length;
 11.1888  
 11.1889 -static NTSTATUS
 11.1890 -XenVbd_Child_PreprocessWdmIrpSCSI(WDFDEVICE Device, PIRP Irp)
 11.1891 -{
 11.1892 -  char *DataBuffer;
 11.1893 -  NTSTATUS status = STATUS_SUCCESS;
 11.1894 -  PSCSI_REQUEST_BLOCK Srb;
 11.1895 -  PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
 11.1896 -  PXENVBD_CHILD_DEVICE_DATA ChildDeviceData;
 11.1897 -  KIRQL KIrql;
 11.1898 -  XenVbd_ListEntry *ListEntry;
 11.1899 -  int notify;
 11.1900 -  PCDB cdb;
 11.1901 -  //PUCHAR Ptr;
 11.1902 -  ULONG i;
 11.1903 +//  KdPrint((__DRIVER_NAME " --> HwScsiStartIo PathId = %d, TargetId = %d, Lun = %d\n", Srb->PathId, Srb->TargetId, Srb->Lun));
 11.1904 +//  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 11.1905  
 11.1906 -  ChildDeviceData = *GetChildDeviceData(Device);
 11.1907 +  if (Srb->PathId >= SCSI_BUSES || Srb->TargetId >= SCSI_TARGETS_PER_BUS)
 11.1908 +  {
 11.1909 +    Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
 11.1910 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 11.1911 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 11.1912 +    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Out of bounds)\n"));
 11.1913 +    return TRUE;
 11.1914 +  }
 11.1915  
 11.1916 -//  if (ChildDeviceData->DeviceType == XENVBD_DEVICETYPE_CDROM)
 11.1917 -//    KdPrint((__DRIVER_NAME " --> WdmIrpPreprocessSCSI\n"));
 11.1918 +  TargetData = &DeviceData->BusData[Srb->PathId].TargetData[Srb->TargetId];
 11.1919  
 11.1920 -  //KdPrint((__DRIVER_NAME "     SCSI Minor = %02X\n", irpSp->MinorFunction));
 11.1921 -
 11.1922 -  Srb = irpSp->Parameters.Scsi.Srb;
 11.1923 +  if (!TargetData->Present)
 11.1924 +  {
 11.1925 +    Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
 11.1926 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 11.1927 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 11.1928 +    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Not Present)\n"));
 11.1929 +    return TRUE;
 11.1930 +  }
 11.1931  
 11.1932    switch (Srb->Function)
 11.1933    {
 11.1934    case SRB_FUNCTION_EXECUTE_SCSI:
 11.1935      cdb = (PCDB)Srb->Cdb;
 11.1936 -//    if (ChildDeviceData->DeviceType == XENVBD_DEVICETYPE_CDROM)
 11.1937 -    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_EXECUTE_SCSI\n"));
 11.1938 -    switch(cdb->CDB6GENERIC.OperationCode) //Srb->Cdb[0])
 11.1939 +//    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_EXECUTE_SCSI\n"));
 11.1940 +    switch(cdb->CDB6GENERIC.OperationCode)
 11.1941      {
 11.1942      case SCSIOP_TEST_UNIT_READY:
 11.1943 -//      if (ChildDeviceData->DeviceType == XENVBD_DEVICETYPE_CDROM)
 11.1944        KdPrint((__DRIVER_NAME "     Command = TEST_UNIT_READY\n"));
 11.1945        Srb->SrbStatus = SRB_STATUS_SUCCESS;
 11.1946        Srb->ScsiStatus = 0;
 11.1947 -      status = STATUS_SUCCESS;
 11.1948 -      Irp->IoStatus.Status = status;
 11.1949 -      Irp->IoStatus.Information = 0;
 11.1950 -      IoCompleteRequest(Irp, IO_NO_INCREMENT);
 11.1951 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 11.1952 +      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 11.1953        break;
 11.1954      case SCSIOP_INQUIRY:
 11.1955        KdPrint((__DRIVER_NAME "     Command = INQUIRY\n"));
 11.1956        KdPrint((__DRIVER_NAME "     (LUN = %d, EVPD = %d, Page Code = %02X)\n", Srb->Cdb[1] >> 5, Srb->Cdb[1] & 1, Srb->Cdb[2]));
 11.1957 -      if ((Srb->Cdb[1] & 1) == 0)
 11.1958 +      KdPrint((__DRIVER_NAME "     (Length = %d)\n", Srb->DataTransferLength));
 11.1959 +      KdPrint((__DRIVER_NAME "     (Srb->Databuffer = %08x)\n", Srb->DataBuffer));
 11.1960 +//      KdPrint((__DRIVER_NAME "     PhysicalAddress.LowPart = %08x\n", ScsiPortGetPhysicalAddress(DeviceData, Srb, Srb->DataBuffer, &Length).LowPart));
 11.1961 +//      DataBuffer = ScsiPortGetVirtualAddress(DeviceData, ScsiPortGetPhysicalAddress(DeviceData, Srb, Srb->DataBuffer, &Length));
 11.1962 +//      KdPrint((__DRIVER_NAME "     (Databuffer = %08x)\n", DataBuffer));
 11.1963 +//      break;
 11.1964 +      DataBuffer = Srb->DataBuffer;
 11.1965 +      RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
 11.1966 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
 11.1967 +      switch (TargetData->DeviceType)
 11.1968        {
 11.1969 -//        DataBuffer = Srb->DataBuffer;
 11.1970 -        DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
 11.1971 -        RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
 11.1972 -
 11.1973 -        DataBuffer[0] = 0x00; // disk
 11.1974 -        DataBuffer[1] = 0x00; // not removable
 11.1975 -        memcpy(DataBuffer + 8, "James   ", 8); // vendor id
 11.1976 -        memcpy(DataBuffer + 16, "XenVBD          ", 8); // product id
 11.1977 -        memcpy(DataBuffer + 32, "000", 8); // product revision level
 11.1978 -        Srb->SrbStatus = SRB_STATUS_SUCCESS;
 11.1979 +      case XENVBD_DEVICETYPE_DISK:
 11.1980 +        if ((Srb->Cdb[1] & 1) == 0)
 11.1981 +        {
 11.1982 +          DataBuffer[0] = DIRECT_ACCESS_DEVICE;
 11.1983 +          DataBuffer[1] = 0x00; // not removable
 11.1984 +          DataBuffer[3] = 32;
 11.1985 +          memcpy(DataBuffer + 8, "XEN     ", 8); // vendor id
 11.1986 +          memcpy(DataBuffer + 16, "PV VBD          ", 16); // product id
 11.1987 +          memcpy(DataBuffer + 32, "0000", 4); // product revision level
 11.1988 +        }
 11.1989 +        else
 11.1990 +        {
 11.1991 +          switch (Srb->Cdb[2])
 11.1992 +          {
 11.1993 +          case 0x00:
 11.1994 +            DataBuffer[0] = DIRECT_ACCESS_DEVICE;
 11.1995 +            DataBuffer[1] = 0x00;
 11.1996 +            DataBuffer[2] = 0x00;
 11.1997 +            DataBuffer[3] = 2;
 11.1998 +            DataBuffer[4] = 0x00;
 11.1999 +            DataBuffer[5] = 0x80;
 11.2000 +            break;
 11.2001 +          case 0x80:
 11.2002 +            DataBuffer[0] = DIRECT_ACCESS_DEVICE;
 11.2003 +            DataBuffer[1] = 0x80;
 11.2004 +            DataBuffer[2] = 0x00;
 11.2005 +            DataBuffer[3] = 8;
 11.2006 +            DataBuffer[4] = 0x31;
 11.2007 +            DataBuffer[5] = 0x32;
 11.2008 +            DataBuffer[6] = 0x33;
 11.2009 +            DataBuffer[7] = 0x34;
 11.2010 +            DataBuffer[8] = 0x35;
 11.2011 +            DataBuffer[9] = 0x36;
 11.2012 +            DataBuffer[10] = 0x37;
 11.2013 +            DataBuffer[11] = 0x38;
 11.2014 +            break;
 11.2015 +          default:
 11.2016 +            KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", Srb->Cdb[2]));
 11.2017 +            Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 11.2018 +            break;
 11.2019 +          }
 11.2020 +        }
 11.2021 +        break;
 11.2022 +      case XENVBD_DEVICETYPE_CDROM:
 11.2023 +        if ((Srb->Cdb[1] & 1) == 0)
 11.2024 +        {
 11.2025 +          DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
 11.2026 +          DataBuffer[1] = 0x01; // removable
 11.2027 +          DataBuffer[3] = 32;
 11.2028 +          memcpy(DataBuffer + 8, "XEN     ", 8); // vendor id
 11.2029 +          memcpy(DataBuffer + 16, "PV VBD          ", 16); // product id
 11.2030 +          memcpy(DataBuffer + 32, "0000", 4); // product revision level
 11.2031 +        }
 11.2032 +        else
 11.2033 +        {
 11.2034 +          switch (Srb->Cdb[2])
 11.2035 +          {
 11.2036 +          case 0x00:
 11.2037 +            DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
 11.2038 +            DataBuffer[1] = 0x00;
 11.2039 +            DataBuffer[2] = 0x00;
 11.2040 +            DataBuffer[3] = 2;
 11.2041 +            DataBuffer[4] = 0x00;
 11.2042 +            DataBuffer[5] = 0x80;
 11.2043 +            break;
 11.2044 +          case 0x80:
 11.2045 +            DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
 11.2046 +            DataBuffer[1] = 0x80;
 11.2047 +            DataBuffer[2] = 0x00;
 11.2048 +            DataBuffer[3] = 8;
 11.2049 +            DataBuffer[4] = 0x31;
 11.2050 +            DataBuffer[5] = 0x32;
 11.2051 +            DataBuffer[6] = 0x33;
 11.2052 +            DataBuffer[7] = 0x34;
 11.2053 +            DataBuffer[8] = 0x35;
 11.2054 +            DataBuffer[9] = 0x36;
 11.2055 +            DataBuffer[10] = 0x37;
 11.2056 +            DataBuffer[11] = 0x38;
 11.2057 +            break;
 11.2058 +          default:
 11.2059 +            KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", Srb->Cdb[2]));
 11.2060 +            Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 11.2061 +            break;
 11.2062 +          }
 11.2063 +        }
 11.2064 +        break;
 11.2065 +      default:
 11.2066 +        KdPrint((__DRIVER_NAME "     Unknown DeviceType %02x requested\n", TargetData->DeviceType));
 11.2067 +        Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 11.2068 +        break;
 11.2069        }
 11.2070 -      else
 11.2071 -      {
 11.2072 -        KdPrint((__DRIVER_NAME "     Command = INQUIRY (LUN = %d, EVPD = %d, Page Code = %02X)\n", Srb->Cdb[1] >> 5, Srb->Cdb[1] & 1, Srb->Cdb[2]));
 11.2073 -        Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 11.2074 -      }
 11.2075 -      Srb->ScsiStatus = 0;
 11.2076 -      status = STATUS_SUCCESS;
 11.2077 -      Irp->IoStatus.Status = status;
 11.2078 -      Irp->IoStatus.Information = 0;
 11.2079 -      IoCompleteRequest(Irp, IO_NO_INCREMENT);
 11.2080 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 11.2081 +      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 11.2082        break;
 11.2083      case SCSIOP_READ_CAPACITY:
 11.2084 -//      if (ChildDeviceData->DeviceType == XENVBD_DEVICETYPE_CDROM)
 11.2085 -      KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY, RelAdr = %d, LBA = %02x%02x%02x%02x, PMI=%d, Control=%d\n", Srb->Cdb[1] & 1, Srb->Cdb[2], Srb->Cdb[3], Srb->Cdb[4], Srb->Cdb[5], Srb->Cdb[8] & 1, Srb->Cdb[9]));
 11.2086 -      KdPrint((__DRIVER_NAME "     Length = %d\n", Srb->DataTransferLength));
 11.2087 -//      DataBuffer = Srb->DataBuffer;
 11.2088 -
 11.2089 -      DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
 11.2090 +      KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
 11.2091 +      DataBuffer = Srb->DataBuffer;
 11.2092        RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
 11.2093 -      DataBuffer[0] = (unsigned char)((ChildDeviceData->TotalSectors - 1) >> 24) & 0xff;
 11.2094 -      DataBuffer[1] = (unsigned char)((ChildDeviceData->TotalSectors - 1) >> 16) & 0xff;
 11.2095 -      DataBuffer[2] = (unsigned char)((ChildDeviceData->TotalSectors - 1) >> 8) & 0xff;
 11.2096 -      DataBuffer[3] = (unsigned char)((ChildDeviceData->TotalSectors - 1) >> 0) & 0xff;
 11.2097 -      DataBuffer[4] = (unsigned char)(ChildDeviceData->BytesPerSector >> 24) & 0xff;
 11.2098 -      DataBuffer[5] = (unsigned char)(ChildDeviceData->BytesPerSector >> 16) & 0xff;
 11.2099 -      DataBuffer[6] = (unsigned char)(ChildDeviceData->BytesPerSector >> 8) & 0xff;
 11.2100 -      DataBuffer[7] = (unsigned char)(ChildDeviceData->BytesPerSector >> 0) & 0xff;
 11.2101 +      DataBuffer[0] = (unsigned char)(TargetData->TotalSectors >> 24) & 0xff;
 11.2102 +      DataBuffer[1] = (unsigned char)(TargetData->TotalSectors >> 16) & 0xff;
 11.2103 +      DataBuffer[2] = (unsigned char)(TargetData->TotalSectors >> 8) & 0xff;
 11.2104 +      DataBuffer[3] = (unsigned char)(TargetData->TotalSectors >> 0) & 0xff;
 11.2105 +      DataBuffer[4] = (unsigned char)(TargetData->BytesPerSector >> 24) & 0xff;
 11.2106 +      DataBuffer[5] = (unsigned char)(TargetData->BytesPerSector >> 16) & 0xff;
 11.2107 +      DataBuffer[6] = (unsigned char)(TargetData->BytesPerSector >> 8) & 0xff;
 11.2108 +      DataBuffer[7] = (unsigned char)(TargetData->BytesPerSector >> 0) & 0xff;
 11.2109        Srb->ScsiStatus = 0;
 11.2110        Srb->SrbStatus = SRB_STATUS_SUCCESS;
 11.2111 -      status = STATUS_SUCCESS;
 11.2112 -      Irp->IoStatus.Status = status;
 11.2113 -      Irp->IoStatus.Information = Srb->DataTransferLength;
 11.2114 -      IoCompleteRequest(Irp, IO_NO_INCREMENT);
 11.2115 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 11.2116 +      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 11.2117        break;
 11.2118 -/*
 11.2119      case SCSIOP_MODE_SENSE:
 11.2120 -      KdPrint((__DRIVER_NAME "     Command = MODE_SENSE (DBD = %d, PC = %d, Page Code = %02x)\n", Srb->Cdb[1] & 0x10, Srb->Cdb[2] & 0xC0, cdb->MODE_SENSE.PageCode));
 11.2121 +      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));
 11.2122        KdPrint((__DRIVER_NAME "     Length = %d\n", Srb->DataTransferLength));
 11.2123  
 11.2124 -      status = STATUS_SUCCESS; 
 11.2125 -      DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
 11.2126 -//      DataBuffer = Srb->DataBuffer;
 11.2127 +      Srb->ScsiStatus = 0;
 11.2128 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
 11.2129 +      Srb->DataTransferLength = 0;
 11.2130 +//      ScsiPhysicalAddress = ScsiPortGetPhysicalAddress(DeviceData, Srb, Srb->DataBuffer, &Srb->DataTransferLength);
 11.2131 +//      DataBuffer = ScsiPortGetVirtualAddress(DeviceData, ScsiPhysicalAddress);
 11.2132 +      DataBuffer = Srb->DataBuffer;
 11.2133        RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
 11.2134 -      switch(cdb->MODE_SENSE.PageCode) //Srb->Cdb[2] & 0x3F)
 11.2135 +      switch(cdb->MODE_SENSE.PageCode)
 11.2136        {
 11.2137        case MODE_SENSE_RETURN_ALL:
 11.2138 -        Irp->IoStatus.Information = 0;
 11.2139          //Ptr = (UCHAR *)Srb->DataBuffer;
 11.2140          for (i = 0; i < MODE_SENSE_RETURN_ALL; i++)
 11.2141          {
 11.2142 -          XenVBD_FillModePage(ChildDeviceData, i, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Irp->IoStatus.Information);
 11.2143 +          if (XenVbd_FillModePage(DeviceData, cdb->MODE_SENSE.PageCode, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Srb->DataTransferLength))
 11.2144 +          {
 11.2145 +            break;
 11.2146 +          }
 11.2147          }
 11.2148          break;
 11.2149        default:
 11.2150 -        XenVBD_FillModePage(ChildDeviceData, cdb->MODE_SENSE.PageCode, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Irp->IoStatus.Information);
 11.2151 +        XenVbd_FillModePage(DeviceData, cdb->MODE_SENSE.PageCode, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Srb->DataTransferLength);
 11.2152          break;
 11.2153        }
 11.2154 -      if (Irp->IoStatus.Information > Srb->DataTransferLength)
 11.2155 -        Srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
 11.2156 -      else
 11.2157 -        Srb->SrbStatus = SRB_STATUS_SUCCESS;
 11.2158 -      status = STATUS_SUCCESS;
 11.2159 -      Irp->IoStatus.Status = status;
 11.2160 -      IoCompleteRequest(Irp, IO_NO_INCREMENT);
 11.2161 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 11.2162 +      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 11.2163        break;
 11.2164 -*/
 11.2165      case SCSIOP_READ:
 11.2166      case SCSIOP_WRITE:
 11.2167 -//      if (ChildDeviceData->DeviceType == XENVBD_DEVICETYPE_CDROM)
 11.2168 -//        KdPrint((__DRIVER_NAME "     Command = READ/WRITE\n"));
 11.2169 -
 11.2170 -      IoMarkIrpPending(Irp);
 11.2171 -
 11.2172 -      //KdPrint((__DRIVER_NAME "     Irp Acquiring Lock\n"));
 11.2173 -      KeAcquireSpinLock(&ChildDeviceData->Lock, &KIrql);
 11.2174 -      //KdPrint((__DRIVER_NAME "A    Got It\n"));
 11.2175 -
 11.2176 -      if (RING_FULL(&ChildDeviceData->Ring))
 11.2177 +//      KdPrint((__DRIVER_NAME "     Command = READ/WRITE\n"));
 11.2178 +/*
 11.2179 +      for (i = 0; i < 10; i++)
 11.2180        {
 11.2181 -        //KdPrint((__DRIVER_NAME "A    Inserting into list\n"));
 11.2182 -        ListEntry = (XenVbd_ListEntry *)ExAllocatePoolWithTag(NonPagedPool, sizeof(XenVbd_ListEntry), XENVBD_POOL_TAG);
 11.2183 -        //KdPrint((__DRIVER_NAME "     Allocate ListEntry = %08x\n", ListEntry));
 11.2184 -        if (ListEntry == NULL)
 11.2185 -        {
 11.2186 -          KdPrint((__DRIVER_NAME "     CANNOT ALLOCATE MEMORY FOR ListEntry!!!\n"));
 11.2187 -        }
 11.2188 -        ListEntry->Irp = Irp;
 11.2189 -        InsertTailList(&ChildDeviceData->IrpListHead, &ListEntry->Entry);
 11.2190 -        ChildDeviceData->IrpAddedToList++;
 11.2191 +        KdPrint((__DRIVER_NAME "     %02x: %02x\n", i, Srb->Cdb[i]));
 11.2192        }
 11.2193 -      else
 11.2194 -      {
 11.2195 -        XenVbd_PutIrpOnRing(Device, Irp);
 11.2196 -        //KeMemoryBarrier(); no need, the next function does it already
 11.2197 -        RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&ChildDeviceData->Ring, notify);
 11.2198 -        if (notify)
 11.2199 -          EvtChnInterface.Notify(ChildDeviceData->EventChannel);
 11.2200 -        //KdPrint((__DRIVER_NAME "     WdmIrpPreprocessSCSI (AddedToList = %d, RemovedFromList = %d, AddedToRing = %d, AddedToRingAtLastNotify = %d, AddedToRingAtLastInterrupt = %d, AddedToRingAtLastDpc = %d, RemovedFromRing = %d, IrpCompleted = %d)\n", ChildDeviceData->IrpAddedToList, ChildDeviceData->IrpRemovedFromList, ChildDeviceData->IrpAddedToRing, ChildDeviceData->IrpAddedToRingAtLastNotify, ChildDeviceData->IrpAddedToRingAtLastInterrupt, ChildDeviceData->IrpAddedToRingAtLastDpc, ChildDeviceData->IrpRemovedFromRing, ChildDeviceData->IrpCompleted));
 11.2201 -      }
 11.2202 -      KeReleaseSpinLock(&ChildDeviceData->Lock, KIrql);
 11.2203 -      status = STATUS_PENDING;
 11.2204 +*/
 11.2205 +      //KeAcquireSpinLock(&DeviceData->Lock, &KIrql);
 11.2206 +
 11.2207 +      XenVbd_PutSrbOnRing(TargetData, Srb);
 11.2208 +      RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&TargetData->Ring, notify);
 11.2209 +      if (notify)
 11.2210 +        DeviceData->XenDeviceData->EvtChnInterface.Notify(TargetData->EventChannel);
 11.2211 +      //KeReleaseSpinLock(&DeviceData->Lock, KIrql);
 11.2212 +//      Srb->SrbStatus = SRB_STATUS_SUCCESS;
 11.2213 +//      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 11.2214 +      if (!RING_FULL(&TargetData->Ring))
 11.2215 +        ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 11.2216        break;
 11.2217 -    case SCSIOP_VERIFY: // We just fake this for now...
 11.2218 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;
 11.2219 -      Srb->ScsiStatus = 0;
 11.2220 -      status = STATUS_SUCCESS;
 11.2221 -      Irp->IoStatus.Status = status;
 11.2222 -      Irp->IoStatus.Information = Srb->DataTransferLength;
 11.2223 -      IoCompleteRequest(Irp, IO_NO_INCREMENT);
 11.2224 +    case SCSIOP_REPORT_LUNS:
 11.2225 +      KdPrint((__DRIVER_NAME "     Command = REPORT_LUNS\n"));
 11.2226 +      Srb->SrbStatus = SRB_STATUS_SUCCESS; //SRB_STATUS_INVALID_REQUEST;
 11.2227 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 11.2228 +      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 11.2229        break;
 11.2230      case SCSIOP_READ_TOC:
 11.2231 -      DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
 11.2232 +      DataBuffer = Srb->DataBuffer;
 11.2233 +//      DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
 11.2234  /*
 11.2235  #define READ_TOC_FORMAT_TOC         0x00
 11.2236  #define READ_TOC_FORMAT_SESSION     0x01
 11.2237 @@ -1656,73 +1055,108 @@ XenVbd_Child_PreprocessWdmIrpSCSI(WDFDEV
 11.2238          Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 11.2239          break;
 11.2240        }
 11.2241 -      Irp->IoStatus.Status = status;
 11.2242 -      IoCompleteRequest(Irp, IO_NO_INCREMENT);
 11.2243 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 11.2244 +      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 11.2245        break;
 11.2246 -/*
 11.2247 -    case SCSIOP_GET_CONFIGURATION:
 11.2248 -#define SCSI_GET_CONFIGURATION_REQUEST_TYPE_ALL     0x0
 11.2249 -#define SCSI_GET_CONFIGURATION_REQUEST_TYPE_CURRENT 0x1
 11.2250 -#define SCSI_GET_CONFIGURATION_REQUEST_TYPE_ONE     0x2
 11.2251 -
 11.2252 -        UCHAR OperationCode;       // 0x46 - SCSIOP_GET_CONFIGURATION
 11.2253 -        UCHAR RequestType : 2;     // SCSI_GET_CONFIGURATION_REQUEST_TYPE_*
 11.2254 -        UCHAR Reserved1   : 6;     // includes obsolete LUN field
 11.2255 -        UCHAR StartingFeature[2];
 11.2256 -        UCHAR Reserved2[3];
 11.2257 -        UCHAR AllocationLength[2];
 11.2258 -        UCHAR Control;
 11.2259 -      break;
 11.2260 -*/     
 11.2261      default:
 11.2262        KdPrint((__DRIVER_NAME "     Unhandled EXECUTE_SCSI Command = %02X\n", Srb->Cdb[0]));
 11.2263        Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 11.2264 -      Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
 11.2265 -      IoCompleteRequest(Irp, IO_NO_INCREMENT);
 11.2266 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 11.2267 +      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 11.2268        break;
 11.2269      }
 11.2270 -    //status = WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
 11.2271      break;
 11.2272    case SRB_FUNCTION_CLAIM_DEVICE:
 11.2273 -//    if (ChildDeviceData->DeviceType == XENVBD_DEVICETYPE_CDROM)
 11.2274 -//      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_CLAIM_DEVICE\n"));
 11.2275 -    ObReferenceObject(WdfDeviceWdmGetDeviceObject(Device));
 11.2276 -    Srb->DataBuffer = WdfDeviceWdmGetDeviceObject(Device);
 11.2277 -//    Srb->DataBuffer = WdfDeviceWdmGetAttachedDevice(Device);
 11.2278 +    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_CLAIM_DEVICE\n"));
 11.2279 +//    ObReferenceObject(WdfDeviceWdmGetDeviceObject(Device));
 11.2280 +//    Srb->DataBuffer = WdfDeviceWdmGetDeviceObject(Device);
 11.2281      Srb->SrbStatus = SRB_STATUS_SUCCESS;
 11.2282 -    status = STATUS_SUCCESS;
 11.2283 -    Irp->IoStatus.Status = status;
 11.2284 -    Irp->IoStatus.Information = 0;
 11.2285 -    IoCompleteRequest(Irp, IO_NO_INCREMENT);
 11.2286 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 11.2287 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 11.2288      break;
 11.2289    case SRB_FUNCTION_IO_CONTROL:
 11.2290 -//    if (ChildDeviceData->DeviceType == XENVBD_DEVICETYPE_CDROM)
 11.2291      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_IO_CONTROL\n"));
 11.2292 -    //status = WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
 11.2293      Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 11.2294 -    status = STATUS_NOT_IMPLEMENTED;
 11.2295 -    //Irp->IoStatus.Status = status;
 11.2296 -    //Irp->IoStatus.Information = 0;
 11.2297 -    IoCompleteRequest(Irp, IO_NO_INCREMENT);
 11.2298 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 11.2299 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 11.2300      break;
 11.2301    case SRB_FUNCTION_FLUSH:
 11.2302 -//    if (ChildDeviceData->DeviceType == XENVBD_DEVICETYPE_CDROM)
 11.2303      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH\n"));
 11.2304 -    Srb->SrbStatus = SRB_STATUS_SUCCESS;
 11.2305 -    status = STATUS_SUCCESS;
 11.2306 -    Irp->IoStatus.Status = status;
 11.2307 -    Irp->IoStatus.Information = 0;
 11.2308 -    IoCompleteRequest(Irp, IO_NO_INCREMENT);
 11.2309 +    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 11.2310 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 11.2311 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 11.2312      break;
 11.2313    default:
 11.2314      KdPrint((__DRIVER_NAME "     Unhandled Srb->Function = %08X\n", Srb->Function));
 11.2315 -    status = WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
 11.2316 +    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 11.2317 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 11.2318 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 11.2319      break;
 11.2320    }
 11.2321  
 11.2322 -//  if (ChildDeviceData->DeviceType == XENVBD_DEVICETYPE_CDROM)
 11.2323 -//    KdPrint((__DRIVER_NAME " <-- WdmIrpPreprocessSCSI (AddedToList = %d, RemovedFromList = %d, AddedToRing = %d, AddedToRingAtLastNotify = %d, AddedToRingAtLastInterrupt = %d, RemovedFromRing = %d)\n", ChildDeviceData->IrpAddedToList, ChildDeviceData->IrpRemovedFromList, ChildDeviceData->IrpAddedToRing, ChildDeviceData->IrpAddedToRingAtLastNotify, ChildDeviceData->IrpAddedToRingAtLastInterrupt, ChildDeviceData->IrpCompleted));
 11.2324 -  //KdPrint((__DRIVER_NAME " <-- WdmIrpPreprocessSCSI\n"));
 11.2325 +//  KdPrint((__DRIVER_NAME " <-- HwScsiStartIo\n"));
 11.2326  
 11.2327 -  return status;
 11.2328 +  return TRUE;
 11.2329  }
 11.2330 +
 11.2331 +static BOOLEAN
 11.2332 +XenVbd_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId)
 11.2333 +{
 11.2334 +  KdPrint((__DRIVER_NAME " --> HwScsiResetBus\n"));
 11.2335 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 11.2336 +
 11.2337 +  KdPrint((__DRIVER_NAME " <-- HwScsiResetBus\n"));
 11.2338 +
 11.2339 +  return TRUE;
 11.2340 +}
 11.2341 +
 11.2342 +
 11.2343 +static BOOLEAN
 11.2344 +XenVbd_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState)
 11.2345 +{
 11.2346 +  KdPrint((__DRIVER_NAME " --> HwScsiAdapterState\n"));
 11.2347 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 11.2348 +
 11.2349 +  KdPrint((__DRIVER_NAME " <-- HwScsiAdapterState\n"));
 11.2350 +
 11.2351 +  return TRUE;
 11.2352 +}
 11.2353 +
 11.2354 +static SCSI_ADAPTER_CONTROL_STATUS
 11.2355 +XenVbd_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
 11.2356 +{
 11.2357 +  SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
 11.2358 +  PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
 11.2359 +
 11.2360 +  KdPrint((__DRIVER_NAME " --> HwScsiAdapterControl\n"));
 11.2361 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 11.2362 +
 11.2363 +  switch (ControlType)
 11.2364 +  {
 11.2365 +  case ScsiQuerySupportedControlTypes:
 11.2366 +    SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
 11.2367 +    KdPrint((__DRIVER_NAME "     ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
 11.2368 +    SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
 11.2369 +    SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
 11.2370 +    break;
 11.2371 +  case ScsiStopAdapter:
 11.2372 +    KdPrint((__DRIVER_NAME "     ScsiStopAdapter\n"));
 11.2373 +    break;
 11.2374 +  case ScsiRestartAdapter:
 11.2375 +    KdPrint((__DRIVER_NAME "     ScsiRestartAdapter\n"));
 11.2376 +    break;
 11.2377 +  case ScsiSetBootConfig:
 11.2378 +    KdPrint((__DRIVER_NAME "     ScsiSetBootConfig\n"));
 11.2379 +    break;
 11.2380 +  case ScsiSetRunningConfig:
 11.2381 +    KdPrint((__DRIVER_NAME "     ScsiSetRunningConfig\n"));
 11.2382 +    break;
 11.2383 +  default:
 11.2384 +    KdPrint((__DRIVER_NAME "     UNKNOWN\n"));
 11.2385 +    break;
 11.2386 +  }
 11.2387 +
 11.2388 +  KdPrint((__DRIVER_NAME " <-- HwScsiAdapterControl\n"));
 11.2389 +
 11.2390 +  return Status;
 11.2391 +}
    12.1 --- a/xenvbd/xenvbd.h	Mon Dec 10 16:51:00 2007 +1100
    12.2 +++ b/xenvbd/xenvbd.h	Sat Dec 15 15:42:55 2007 +1100
    12.3 @@ -1,11 +1,13 @@
    12.4 -#if !defined(_XENBUS_H_)
    12.5 -#define _XENBUS_H_
    12.6 +#if !defined(_XENVBD_H_)
    12.7 +#define _XENVBD_H_
    12.8  
    12.9 +#include <ntifs.h>
   12.10  #include <ntddk.h>
   12.11  #include <wdm.h>
   12.12  #include <wdf.h>
   12.13  #include <initguid.h>
   12.14  #include <ntdddisk.h>
   12.15 +#include <srb.h>
   12.16  
   12.17  #define NTSTRSAFE_LIB
   12.18  #include <ntstrsafe.h>
   12.19 @@ -16,100 +18,78 @@
   12.20  #include <event_channel.h>
   12.21  #include <hvm/params.h>
   12.22  #include <hvm/hvm_op.h>
   12.23 +#include <xen_public.h>
   12.24  #include <evtchn_public.h>
   12.25  #include <xenbus_public.h>
   12.26 +#include <gnttbl_public.h>
   12.27  #include <io/ring.h>
   12.28  #include <io/blkif.h>
   12.29  #define __DRIVER_NAME "XenVbd"
   12.30 -#define XENVBD_POOL_TAG (ULONG) 'XenP'
   12.31 +#define XENVBD_POOL_TAG (ULONG) 'XVBD'
   12.32  
   12.33  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
   12.34  #define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
   12.35  
   12.36  typedef struct {
   12.37    blkif_request_t req;
   12.38 -  //int Id;
   12.39 -  PIRP Irp;
   12.40 +  PSCSI_REQUEST_BLOCK Srb;
   12.41    PMDL Mdl;
   12.42    VOID *Buf;
   12.43 -  //int nr_segments;
   12.44 -  //unsigned long gref[BLKIF_MAX_SEGMENTS_PER_REQUEST];
   12.45  } blkif_shadow_t;
   12.46  
   12.47 -typedef struct {
   12.48 -  LIST_ENTRY Entry;
   12.49 -  PIRP Irp;
   12.50 -} XenVbd_ListEntry;
   12.51 +//#include "scsidata.h"
   12.52  
   12.53 -/*
   12.54 -typedef struct _XENVBD_QUEUE_DATA {
   12.55 -    XENVBD_CHILD_DEVICE_DATA DeviceData;
   12.56 -} XENVBD_QUEUE_DATA, *PXENVBD_QUEUE_DATA;
   12.57  
   12.58 -WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENVBD_QUEUE_DATA, GetQueueData)
   12.59 -*/
   12.60 -
   12.61 -//typedef unsigned long xenbus_transaction_t;
   12.62 -//typedef uint32_t XENSTORE_RING_IDX;
   12.63 -
   12.64 -extern XEN_IFACE_EVTCHN EvtChnInterface;
   12.65 -extern XEN_IFACE_XENBUS XenBusInterface;
   12.66 +#define SCSI_BUSES 4
   12.67 +#define SCSI_TARGETS_PER_BUS 16
   12.68  
   12.69  typedef enum {
   12.70    XENVBD_DEVICETYPE_UNKNOWN,
   12.71    XENVBD_DEVICETYPE_DISK,
   12.72 -  XENVBD_DEVICETYPE_CDROM
   12.73 +  XENVBD_DEVICETYPE_CDROM,
   12.74 +  XENVBD_DEVICETYPE_CONTROLLER // Not yet used
   12.75  } XENVBD_DEVICETYPE;
   12.76  
   12.77 -struct {
   12.78 -  LIST_ENTRY Entry;
   12.79 -  KSPIN_LOCK Lock;
   12.80 -  WDFQUEUE IoDefaultQueue;
   12.81 -  WDFDEVICE Device;
   12.82 -  char Path[128];
   12.83 -  char BackendPath[128];
   12.84 -  ULONG DeviceIndex;
   12.85 +struct
   12.86 +{
   12.87 +  int Present;
   12.88 +  BOOLEAN PendingInterrupt;
   12.89 +  PVOID DeviceData; // how can we create a forward definition for this???
   12.90    evtchn_port_t EventChannel;
   12.91    //blkif_sring_t *SharedRing;
   12.92 +  blkif_shadow_t *shadow;
   12.93 +  uint64_t shadow_free;
   12.94    ULONG RingBufPFN;
   12.95    int BackendState;
   12.96    int FrontendState;
   12.97 +  char Path[128];
   12.98 +  int DeviceIndex;
   12.99 +  char BackendPath[128];
  12.100    blkif_front_ring_t Ring;
  12.101 -  blkif_shadow_t *shadow;
  12.102 -  uint64_t shadow_free;
  12.103 -
  12.104 -  LIST_ENTRY IrpListHead;
  12.105 -  KSPIN_LOCK IrpListLock;
  12.106 -
  12.107 -  WDFDPC Dpc;
  12.108 -
  12.109 +  XENVBD_DEVICETYPE DeviceType;
  12.110 +  DISK_GEOMETRY Geometry;
  12.111    ULONG BytesPerSector;
  12.112 -  ULONGLONG TotalSectors;
  12.113 -  DISK_GEOMETRY Geometry;
  12.114 -  XENVBD_DEVICETYPE DeviceType;
  12.115 +  ULONGLONG TotalSectors; 
  12.116 +} typedef XENVBD_TARGET_DATA, *PXENVBD_TARGET_DATA;
  12.117  
  12.118 -  int IrpAddedToList;
  12.119 -  int IrpRemovedFromList;
  12.120 -  int IrpAddedToRing;
  12.121 -  int IrpAddedToRingAtLastNotify;
  12.122 -  int IrpAddedToRingAtLastInterrupt;
  12.123 -  int IrpAddedToRingAtLastDpc;
  12.124 -  int IrpRemovedFromRing;
  12.125 -  int IrpCompleted;
  12.126 +struct
  12.127 +{
  12.128 +  XENVBD_TARGET_DATA TargetData[SCSI_TARGETS_PER_BUS];
  12.129 +} typedef XENVBD_BUS_DATA, *PXENVBD_BUS_DATA;
  12.130 +
  12.131 +struct
  12.132 +{
  12.133 +  PXENPCI_XEN_DEVICE_DATA XenDeviceData;
  12.134 +  XENVBD_BUS_DATA BusData[SCSI_BUSES];
  12.135  
  12.136    int FastPathUsed;
  12.137    int SlowPathUsed;
  12.138  
  12.139 -} typedef XENVBD_CHILD_DEVICE_DATA, *PXENVBD_CHILD_DEVICE_DATA, **PPXENVBD_CHILD_DEVICE_DATA;
  12.140 -
  12.141 -WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(PXENVBD_CHILD_DEVICE_DATA, GetChildDeviceData);
  12.142 +  int BusChangePending;
  12.143  
  12.144 -typedef struct _XENVBD_DEVICE_IDENTIFICATION_DESCRIPTION
  12.145 -{
  12.146 -  WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Header;
  12.147 -  PXENVBD_CHILD_DEVICE_DATA DeviceData;
  12.148 -  //ULONG DeviceIndex;
  12.149 -  //char Path[128];
  12.150 -} XENVBD_DEVICE_IDENTIFICATION_DESCRIPTION, *PXENVBD_DEVICE_IDENTIFICATION_DESCRIPTION;
  12.151 +  int EnumeratedDevices;
  12.152 +  KEVENT WaitDevicesEvent;
  12.153 +
  12.154 +} typedef XENVBD_DEVICE_DATA, *PXENVBD_DEVICE_DATA;
  12.155  
  12.156  #endif