win-pvdrivers

changeset 8:d25a6f733a8e

Finally got swapfile working!
author James Harper <james.harper@bendigoit.com.au>
date Mon Nov 19 17:42:06 2007 +1100 (2007-11-19)
parents 078654ce6a13
children b55f3c61e509
files INSTALLING.txt TODO.txt target/xenpci.inf target/xenvbd.inf xenpci/xenpci.c xenvbd/xenvbd.c xenvbd/xenvbd.h
line diff
     1.1 --- a/INSTALLING.txt	Mon Nov 12 23:04:56 2007 +1100
     1.2 +++ b/INSTALLING.txt	Mon Nov 19 17:42:06 2007 +1100
     1.3 @@ -39,11 +39,7 @@ 14. Click 'Have Disk' and go to the loca
     1.4  
     1.5  15. Select the 'Xen PCI Device Hider Driver' (I know, it's a stupid name) and install it, again accepting the unsigned driver warning.
     1.6  
     1.7 -16. *** Shouldn't need to do this step anymore *** Open the registry editor (Start -> Run, then type 'regedit')
     1.8 -
     1.9 -17. *** Shouldn't need to do this step anymore *** In the registry editor, open the key 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\ServiceGroupOrder' and modify the List value so that WdfLoadGroup is before Boot Bus Extender.
    1.10 -
    1.11 -18. edit your boot.ini to look something like this:
    1.12 +16. edit your boot.ini to look something like this:
    1.13  
    1.14  "
    1.15  [boot loader]
    1.16 @@ -54,11 +50,9 @@ multi(0)disk(0)rdisk(0)partition(1)\WIND
    1.17  multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows Server 2003, Enterprise, PV" /noexecute=optout /fastdetect /gplpv
    1.18  "
    1.19  
    1.20 -19. The main thing in the above step is that you have a line with /gplpv on the end. This tells the PV drivers to activate, otherwise they will pretty much sit silent.
    1.21 +17. The main thing in the above step is that you have a line with /gplpv on the end. This tells the PV drivers to activate, otherwise they will pretty much sit silent.
    1.22  
    1.23 -20. Reboot and select the /gplpv entry. If it doesn't work then email me with some details and i'll see what I can do.
    1.24 -
    1.25 -
    1.26 +18. Reboot and select the /gplpv entry. If it doesn't work then email me with some details and i'll see what I can do. 
    1.27  
    1.28  Without the /gplpv option specified, the xenvbd driver will only pick up on devices you have added since boot, so you can still test it without specifying /gplpv and doing something like the following in Dom0:
    1.29  
     2.1 --- a/TODO.txt	Mon Nov 12 23:04:56 2007 +1100
     2.2 +++ b/TODO.txt	Mon Nov 19 17:42:06 2007 +1100
     2.3 @@ -8,8 +8,6 @@ Known problems or things that need doing
     2.4  . Almost certainly won't support migration or suspend/resume.
     2.5  . Probably really poor performance - no optimisation done at all yet.
     2.6  . Probably lots of other things too.
     2.7 -. Put up a binary release so it can get some further testing
     2.8 -. Write an installer for the above binaries to automate everything
     2.9  
    2.10  TODO:
    2.11  . Do some performance testing
    2.12 @@ -17,3 +15,5 @@ TODO:
    2.13  . network adapters (vif) (Andy Grover is looking at this)
    2.14  . virtual scsi (eg a front end for the scsi passthrough stuff)
    2.15  . balloon drivers (this should actually be pretty easy)
    2.16 +. Write an installer for the above binaries to automate everything
    2.17 +. Put up a binary release so it can get some further testing
     3.1 --- a/target/xenpci.inf	Mon Nov 12 23:04:56 2007 +1100
     3.2 +++ b/target/xenpci.inf	Mon Nov 19 17:42:06 2007 +1100
     3.3 @@ -3,7 +3,7 @@ Signature="$WINDOWS NT$"
     3.4  Class=Xen
     3.5  ClassGuid={C828ABE9-14CA-4445-BAA6-82C2376C6518}
     3.6  Provider=%JAMESHARPER%
     3.7 -DriverVer=11/12/2007,1.0.1.5
     3.8 +DriverVer=11/19/2007,1.0.1.8
     3.9  
    3.10  [DestinationDirs]
    3.11  DefaultDestDir = 12
     4.1 --- a/target/xenvbd.inf	Mon Nov 12 23:04:56 2007 +1100
     4.2 +++ b/target/xenvbd.inf	Mon Nov 19 17:42:06 2007 +1100
     4.3 @@ -3,7 +3,7 @@ Signature="$WINDOWS NT$"
     4.4  Class=SCSIAdapter
     4.5  ClassGuid={B968331F-9539-47d0-855E-66CB6AA613E2}
     4.6  Provider=%JAMESHARPER%
     4.7 -DriverVer=11/11/2007,1.0.1.290
     4.8 +DriverVer=11/19/2007,1.0.1.332
     4.9  
    4.10  [DestinationDirs]
    4.11  DefaultDestDir = 12
     5.1 --- a/xenpci/xenpci.c	Mon Nov 12 23:04:56 2007 +1100
     5.2 +++ b/xenpci/xenpci.c	Mon Nov 19 17:42:06 2007 +1100
     5.3 @@ -362,6 +362,10 @@ XenPCI_AddDevice(
     5.4      return status;
     5.5    }
     5.6  
     5.7 +  WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFilePaging, TRUE);
     5.8 +  WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFileHibernation, TRUE);
     5.9 +  WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFileDump, TRUE);
    5.10 +
    5.11    status = WdfFdoQueryForInterface(Device, &GUID_BUS_INTERFACE_STANDARD, (PINTERFACE) &BusInterface, sizeof(BUS_INTERFACE_STANDARD), 1, NULL);
    5.12    if(!NT_SUCCESS(status))
    5.13    {
    5.14 @@ -702,6 +706,10 @@ XenPCI_ChildListCreateDevice(WDFCHILDLIS
    5.15      KdPrint((__DRIVER_NAME "     WdfDeviceCreate status = %08X\n", status));
    5.16    }
    5.17  
    5.18 +  WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFilePaging, TRUE);
    5.19 +  WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileHibernation, TRUE);
    5.20 +  WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileDump, TRUE);
    5.21 +
    5.22    ChildDeviceData = GetXenDeviceData(ChildDevice);
    5.23    strncpy(ChildDeviceData->BasePath, XenIdentificationDesc->Path, 128);
    5.24    
     6.1 --- a/xenvbd/xenvbd.c	Mon Nov 12 23:04:56 2007 +1100
     6.2 +++ b/xenvbd/xenvbd.c	Mon Nov 19 17:42:06 2007 +1100
     6.3 @@ -17,21 +17,18 @@ DRIVER_INITIALIZE DriverEntry;
     6.4  
     6.5  static NTSTATUS
     6.6  XenVbd_AddDevice(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit);
     6.7 -
     6.8  static NTSTATUS
     6.9  XenVbd_PrepareHardware(WDFDEVICE hDevice, WDFCMRESLIST Resources, WDFCMRESLIST ResourcesTranslated);
    6.10 -
    6.11  static NTSTATUS
    6.12  XenVbd_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated);
    6.13 -
    6.14  static NTSTATUS
    6.15  XenVbd_D0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
    6.16 -
    6.17  static NTSTATUS
    6.18  XenVbd_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
    6.19 -
    6.20  static NTSTATUS
    6.21  XenVbd_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState);
    6.22 +static NTSTATUS
    6.23 +XenVbd_DeviceUsageNotification(WDFDEVICE Device, WDF_SPECIAL_FILE_TYPE NotificationType, BOOLEAN IsInNotificationPath);
    6.24  
    6.25  static VOID
    6.26  XenVbd_IoDefault(WDFQUEUE Queue, WDFREQUEST Request);
    6.27 @@ -217,11 +214,14 @@ XenVbd_AddDevice(
    6.28    pnpPowerCallbacks.EvtDeviceD0Entry = XenVbd_D0Entry;
    6.29    pnpPowerCallbacks.EvtDeviceD0EntryPostInterruptsEnabled = XenVbd_D0EntryPostInterruptsEnabled;
    6.30    pnpPowerCallbacks.EvtDeviceD0Exit = XenVbd_D0Exit;
    6.31 +  pnpPowerCallbacks.EvtDeviceUsageNotification = XenVbd_DeviceUsageNotification;
    6.32    WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
    6.33  
    6.34    /*initialize storage for the device context*/
    6.35    //WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, XENVBD_DEVICE_DATA);
    6.36  
    6.37 +  //WdfDeviceInitSetPowerNotPageable(DeviceInit);
    6.38 +
    6.39    /*create a device instance.*/
    6.40    status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &GlobalDevice);  
    6.41    if(!NT_SUCCESS(status))
    6.42 @@ -229,6 +229,10 @@ XenVbd_AddDevice(
    6.43      KdPrint((__DRIVER_NAME "WdfDeviceCreate failed with status 0x%08x\n", status));
    6.44      return status;
    6.45    }
    6.46 +
    6.47 +  WdfDeviceSetSpecialFileSupport(GlobalDevice, WdfSpecialFilePaging, TRUE);
    6.48 +  WdfDeviceSetSpecialFileSupport(GlobalDevice, WdfSpecialFileHibernation, TRUE);
    6.49 +  WdfDeviceSetSpecialFileSupport(GlobalDevice, WdfSpecialFileDump, TRUE);
    6.50    
    6.51    status = STATUS_SUCCESS;
    6.52  
    6.53 @@ -306,7 +310,6 @@ XenVbd_D0Entry(
    6.54  
    6.55    //KdPrint((__DRIVER_NAME " --> EvtDeviceD0Entry\n"));
    6.56  
    6.57 -  
    6.58    //KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Entry\n"));
    6.59  
    6.60    return status;
    6.61 @@ -356,7 +359,6 @@ XenVbd_D0EntryPostInterruptsEnabled(WDFD
    6.62        KdPrint((__DRIVER_NAME "     Waiting for devices to be enumerated\n"));
    6.63        while (EnumeratedDevices != i)
    6.64        {
    6.65 -// TODO: need to not wait forever here...
    6.66          WaitTimeout.QuadPart = -600000000;
    6.67          if (KeWaitForSingleObject(&WaitDevicesEvent, Executive, KernelMode, FALSE, &WaitTimeout) == STATUS_TIMEOUT)
    6.68          {
    6.69 @@ -394,6 +396,31 @@ XenVbd_D0Exit(
    6.70    return status;
    6.71  }
    6.72  
    6.73 +static NTSTATUS
    6.74 +XenVbd_DeviceUsageNotification(WDFDEVICE Device, WDF_SPECIAL_FILE_TYPE NotificationType, BOOLEAN IsInNotificationPath)
    6.75 +{
    6.76 +  KdPrint((__DRIVER_NAME " --> DeviceUsageNotification\n"));
    6.77 +
    6.78 +  switch (NotificationType)
    6.79 +  {
    6.80 +  case WdfSpecialFilePaging:
    6.81 +    KdPrint((__DRIVER_NAME "     NotificationType = WdfSpecialFilePaging, Using = %d\n", IsInNotificationPath));
    6.82 +    break;
    6.83 +  case WdfSpecialFileHibernation:
    6.84 +    KdPrint((__DRIVER_NAME "     NotificationType = WdfSpecialFileHibernation, Using = %d\n", IsInNotificationPath));
    6.85 +    break;
    6.86 +  case WdfSpecialFileDump:
    6.87 +    KdPrint((__DRIVER_NAME "     NotificationType = WdfSpecialFileDump, Using = %d\n", IsInNotificationPath));
    6.88 +    break;
    6.89 +  default:
    6.90 +    KdPrint((__DRIVER_NAME "     NotificationType = %d, Using = %d\n", NotificationType, IsInNotificationPath));
    6.91 +    break;
    6.92 +  }
    6.93 +  KdPrint((__DRIVER_NAME " <-- DeviceUsageNotification\n"));
    6.94 +
    6.95 +  return TRUE;
    6.96 +}
    6.97 +
    6.98  static VOID 
    6.99  XenVbd_IoDefault(
   6.100      IN WDFQUEUE  Queue,
   6.101 @@ -492,6 +519,7 @@ XenVbd_DpcThreadProc(WDFDPC Dpc)
   6.102    KIRQL KIrql;
   6.103    WDFDEVICE ChildDevice;
   6.104    XenVbd_ListEntry *ListEntry;
   6.105 +  int notify;
   6.106  
   6.107    //!!!IRQL_DISPATCH!!!
   6.108  
   6.109 @@ -505,7 +533,7 @@ XenVbd_DpcThreadProc(WDFDPC Dpc)
   6.110    more_to_do = TRUE;
   6.111    KeAcquireSpinLock(&ChildDeviceData->Lock, &KIrql);
   6.112  
   6.113 -  //ChildDeviceData->IrpAddedToRingAtLastDpc = ChildDeviceData->IrpAddedToRing;
   6.114 +  ChildDeviceData->IrpAddedToRingAtLastDpc = ChildDeviceData->IrpAddedToRing;
   6.115  
   6.116    while (more_to_do)
   6.117    {
   6.118 @@ -514,7 +542,7 @@ XenVbd_DpcThreadProc(WDFDPC Dpc)
   6.119      for (i = ChildDeviceData->Ring.rsp_cons; i != rp; i++)
   6.120      {
   6.121        rep = RING_GET_RESPONSE(&ChildDeviceData->Ring, i);
   6.122 -      //ChildDeviceData->IrpRemovedFromRing++;
   6.123 +      ChildDeviceData->IrpRemovedFromRing++;
   6.124        Irp = ChildDeviceData->shadow[rep->id].Irp;
   6.125        IrpSp = IoGetCurrentIrpStackLocation(Irp);
   6.126        Srb = IrpSp->Parameters.Scsi.Srb;
   6.127 @@ -564,25 +592,28 @@ XenVbd_DpcThreadProc(WDFDPC Dpc)
   6.128      }
   6.129    }
   6.130  
   6.131 +  notify = 0;
   6.132 +  while (!RING_FULL(&ChildDeviceData->Ring) && (ListEntry = (XenVbd_ListEntry *)RemoveHeadList(&ChildDeviceData->IrpListHead)) != (XenVbd_ListEntry *)&ChildDeviceData->IrpListHead)
   6.133 +  {
   6.134 +    ChildDeviceData->IrpRemovedFromList++;
   6.135 +    XenVbd_PutIrpOnRing(ChildDevice, ListEntry->Irp);
   6.136 +    ExFreePoolWithTag(ListEntry, XENVBD_POOL_TAG);
   6.137 +    notify = 1;
   6.138 +  }
   6.139 +  if (notify)
   6.140 +  {
   6.141 +    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&ChildDeviceData->Ring, notify);
   6.142 +    if (notify)
   6.143 +      EvtChnInterface.Notify(ChildDeviceData->EventChannel);
   6.144 +  }
   6.145    KeReleaseSpinLock(&ChildDeviceData->Lock, KIrql);
   6.146  
   6.147    for (j = 0; j < IrpCount; j++)
   6.148    {
   6.149      IoCompleteRequest(Irps[j], IO_NO_INCREMENT);
   6.150 -    //ChildDeviceData->IrpCompleted++;
   6.151 +    ChildDeviceData->IrpCompleted++;
   6.152    }
   6.153  
   6.154 -  KeAcquireSpinLock(&ChildDeviceData->Lock, &KIrql);
   6.155 -
   6.156 -  while (!RING_FULL(&ChildDeviceData->Ring) && (ListEntry = (XenVbd_ListEntry *)/*ExInterlocked*/RemoveHeadList(&ChildDeviceData->IrpListHead)) != (XenVbd_ListEntry *)&ChildDeviceData->IrpListHead)
   6.157 -  {
   6.158 -    //ChildDeviceData->IrpRemovedFromList++;
   6.159 -    XenVbd_PutIrpOnRing(ChildDevice, ListEntry->Irp);
   6.160 -    ExFreePoolWithTag(ListEntry, XENVBD_POOL_TAG);
   6.161 -  }
   6.162 -
   6.163 -  KeReleaseSpinLock(&ChildDeviceData->Lock, KIrql);
   6.164 -
   6.165    //KdPrint((__DRIVER_NAME " <-- XenVbd_DpcThreadProc\n"));
   6.166    //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));
   6.167  }
   6.168 @@ -599,7 +630,7 @@ XenVbd_Interrupt(PKINTERRUPT Interrupt, 
   6.169    //KdPrint((__DRIVER_NAME " --> XenVbd_Interrupt\n"));
   6.170  
   6.171    ChildDeviceData = (PXENVBD_CHILD_DEVICE_DATA)ServiceContext;
   6.172 -  //ChildDeviceData->IrpAddedToRingAtLastInterrupt = ChildDeviceData->IrpAddedToRing;
   6.173 +  ChildDeviceData->IrpAddedToRingAtLastInterrupt = ChildDeviceData->IrpAddedToRing;
   6.174    RetVal = WdfDpcEnqueue(ChildDeviceData->Dpc);
   6.175  
   6.176    //KdPrint((__DRIVER_NAME " <-- XenVbd_Interrupt (RetVal = %d)\n", RetVal));  
   6.177 @@ -829,6 +860,7 @@ XenVbd_ChildListCreateDevice(WDFCHILDLIS
   6.178    unsigned int i;
   6.179    WDF_DPC_CONFIG DpcConfig;
   6.180    WDF_OBJECT_ATTRIBUTES DpcObjectAttributes;
   6.181 +  WDF_DEVICE_STATE DeviceState;
   6.182  
   6.183    UNREFERENCED_PARAMETER(ChildList);
   6.184  
   6.185 @@ -868,12 +900,17 @@ XenVbd_ChildListCreateDevice(WDFCHILDLIS
   6.186  
   6.187    WdfDeviceInitSetIoType(ChildInit, WdfDeviceIoDirect);
   6.188  
   6.189 +  //WdfDeviceInitSetPowerNotPageable(ChildInit);
   6.190 +
   6.191    status = WdfDeviceCreate(&ChildInit, &PdoAttributes, &ChildDevice);
   6.192    if (!NT_SUCCESS(status))
   6.193    {
   6.194      KdPrint((__DRIVER_NAME "     WdfDeviceCreate status = %08X\n", status));
   6.195    }
   6.196  
   6.197 +  WDF_DEVICE_STATE_INIT(&DeviceState);
   6.198 +  DeviceState.NotDisableable = WdfTrue;
   6.199 +  WdfDeviceSetDeviceState(ChildDevice, &DeviceState);
   6.200    WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFilePaging, TRUE);
   6.201    WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileHibernation, TRUE);
   6.202    WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileDump, TRUE);
   6.203 @@ -884,14 +921,16 @@ XenVbd_ChildListCreateDevice(WDFCHILDLIS
   6.204  
   6.205    *GetChildDeviceData(ChildDevice) = ChildDeviceData;
   6.206  
   6.207 -  //ChildDeviceData->IrpAddedToList = 0;
   6.208 -  //ChildDeviceData->IrpRemovedFromList = 0;
   6.209 -  //ChildDeviceData->IrpAddedToRing = 0;
   6.210 -  //ChildDeviceData->IrpAddedToRingAtLastNotify = 0;
   6.211 -  //ChildDeviceData->IrpAddedToRingAtLastInterrupt = 0;
   6.212 -  //ChildDeviceData->IrpAddedToRingAtLastDpc = 0;
   6.213 -  //ChildDeviceData->IrpRemovedFromRing = 0;
   6.214 -  //ChildDeviceData->IrpCompleted = 0;
   6.215 +  ChildDeviceData->FastPathUsed = 0;
   6.216 +  ChildDeviceData->SlowPathUsed = 0;
   6.217 +  ChildDeviceData->IrpAddedToList = 0;
   6.218 +  ChildDeviceData->IrpRemovedFromList = 0;
   6.219 +  ChildDeviceData->IrpAddedToRing = 0;
   6.220 +  ChildDeviceData->IrpAddedToRingAtLastNotify = 0;
   6.221 +  ChildDeviceData->IrpAddedToRingAtLastInterrupt = 0;
   6.222 +  ChildDeviceData->IrpAddedToRingAtLastDpc = 0;
   6.223 +  ChildDeviceData->IrpRemovedFromRing = 0;
   6.224 +  ChildDeviceData->IrpCompleted = 0;
   6.225  
   6.226    status = WdfIoQueueCreate(ChildDevice, &IoQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &ChildDeviceData->IoDefaultQueue);
   6.227    if(!NT_SUCCESS(status))
   6.228 @@ -925,6 +964,8 @@ XenVbd_ChildListCreateDevice(WDFCHILDLIS
   6.229  }
   6.230  
   6.231  
   6.232 +// 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
   6.233 +
   6.234  // Call with device lock held
   6.235  static VOID
   6.236  XenVbd_PutIrpOnRing(WDFDEVICE Device, PIRP Irp)
   6.237 @@ -934,7 +975,6 @@ XenVbd_PutIrpOnRing(WDFDEVICE Device, PI
   6.238    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
   6.239    PXENVBD_CHILD_DEVICE_DATA ChildDeviceData;
   6.240    blkif_request_t *req;
   6.241 -  int notify;
   6.242    int i;
   6.243    int j;
   6.244    int BlockCount;
   6.245 @@ -976,6 +1016,7 @@ XenVbd_PutIrpOnRing(WDFDEVICE Device, PI
   6.246      // fast path - zero copy
   6.247      ChildDeviceData->shadow[req->id].Mdl = Irp->MdlAddress;
   6.248      ChildDeviceData->shadow[req->id].Buf = NULL; // we don't need the virtual address
   6.249 +    ChildDeviceData->FastPathUsed++;
   6.250    }
   6.251    else
   6.252    {
   6.253 @@ -986,6 +1027,13 @@ XenVbd_PutIrpOnRing(WDFDEVICE Device, PI
   6.254      {
   6.255        KdPrint((__DRIVER_NAME "     MmGetMdlVirtualAddress returned NULL in PutIrpOnRing\n"));
   6.256      }
   6.257 +    ChildDeviceData->SlowPathUsed++;
   6.258 +  }
   6.259 +
   6.260 +  if (((ChildDeviceData->FastPathUsed + ChildDeviceData->SlowPathUsed) & 0x2FF) == 0)
   6.261 +  {
   6.262 +    KdPrint((__DRIVER_NAME "     Fast Path = %d, Slow Path = %d\n", ChildDeviceData->FastPathUsed, ChildDeviceData->SlowPathUsed));
   6.263 +    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));
   6.264    }
   6.265  
   6.266    sect_offset = MmGetMdlByteOffset(ChildDeviceData->shadow[req->id].Mdl) >> 9;
   6.267 @@ -1007,19 +1055,42 @@ XenVbd_PutIrpOnRing(WDFDEVICE Device, PI
   6.268    ChildDeviceData->shadow[req->id].req = *req;
   6.269  
   6.270    ChildDeviceData->Ring.req_prod_pvt++;
   6.271 -  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&ChildDeviceData->Ring, notify);
   6.272 -  if (notify)
   6.273 +
   6.274 +  ChildDeviceData->IrpAddedToRing++;
   6.275 +  //KdPrint((__DRIVER_NAME " <-- PutIrpOnRing\n"));
   6.276 +}
   6.277 +
   6.278 +static ULONG
   6.279 +XenVBD_FillModePage(PXENVBD_CHILD_DEVICE_DATA ChildDeviceData, UCHAR PageCode, PUCHAR DataBuffer, ULONG BufferLength, PULONG Offset)
   6.280 +{
   6.281 +  PMODE_RIGID_GEOMETRY_PAGE ModeRigidGeometry;
   6.282 +
   6.283 +  switch (PageCode)
   6.284    {
   6.285 -    EvtChnInterface.Notify(ChildDeviceData->EventChannel);
   6.286 -    //KdPrint((__DRIVER_NAME "       Notified\n"));
   6.287 -    //ChildDeviceData->IrpAddedToRing++;
   6.288 -    //ChildDeviceData->IrpAddedToRingAtLastNotify = ChildDeviceData->IrpAddedToRing;
   6.289 +  case MODE_PAGE_RIGID_GEOMETRY:
   6.290 +    KdPrint((__DRIVER_NAME "     MODE_PAGE_RIGID_GEOMETRY\n"));
   6.291 +    if (*Offset + sizeof(MODE_RIGID_GEOMETRY_PAGE) > BufferLength)
   6.292 +      return 1;
   6.293 +    ModeRigidGeometry = (PMODE_RIGID_GEOMETRY_PAGE)(DataBuffer + *Offset);
   6.294 +    memset(ModeRigidGeometry, 0, sizeof(MODE_RIGID_GEOMETRY_PAGE));
   6.295 +    ModeRigidGeometry->PageCode = PageCode;
   6.296 +    ModeRigidGeometry->PageSavable = 0;
   6.297 +    ModeRigidGeometry->PageLength = sizeof(MODE_RIGID_GEOMETRY_PAGE);
   6.298 +    ModeRigidGeometry->NumberOfCylinders[0] = (ChildDeviceData->Geometry.Cylinders.LowPart >> 16) & 0xFF;
   6.299 +    ModeRigidGeometry->NumberOfCylinders[1] = (ChildDeviceData->Geometry.Cylinders.LowPart >> 8) & 0xFF;
   6.300 +    ModeRigidGeometry->NumberOfCylinders[2] = (ChildDeviceData->Geometry.Cylinders.LowPart >> 0) & 0xFF;
   6.301 +    ModeRigidGeometry->NumberOfHeads = ChildDeviceData->Geometry.TracksPerCylinder;
   6.302 +    //ModeRigidGeometry->LandZoneCyclinder = 0;
   6.303 +    ModeRigidGeometry->RoataionRate[0] = 0x05;
   6.304 +    ModeRigidGeometry->RoataionRate[0] = 0x39;
   6.305 +    *Offset += sizeof(MODE_RIGID_GEOMETRY_PAGE);
   6.306 +    break;
   6.307 +  case MODE_PAGE_FAULT_REPORTING:
   6.308 +    break;
   6.309 +  default:
   6.310 +    break;
   6.311    }
   6.312 -  else
   6.313 -  {
   6.314 -    //ChildDeviceData->IrpAddedToRing++;
   6.315 -  }
   6.316 -  //KdPrint((__DRIVER_NAME " <-- PutIrpOnRing\n"));
   6.317 +  return 0;
   6.318  }
   6.319  
   6.320  static NTSTATUS
   6.321 @@ -1032,6 +1103,10 @@ XenVbd_Child_PreprocessWdmIrpSCSI(WDFDEV
   6.322    PXENVBD_CHILD_DEVICE_DATA ChildDeviceData;
   6.323    KIRQL KIrql;
   6.324    XenVbd_ListEntry *ListEntry;
   6.325 +  int notify;
   6.326 +  PCDB cdb;
   6.327 +  //PUCHAR Ptr;
   6.328 +  ULONG i;
   6.329  
   6.330    //KdPrint((__DRIVER_NAME " --> WdmIrpPreprocessSCSI\n"));
   6.331  
   6.332 @@ -1042,8 +1117,9 @@ XenVbd_Child_PreprocessWdmIrpSCSI(WDFDEV
   6.333    switch (Srb->Function)
   6.334    {
   6.335    case SRB_FUNCTION_EXECUTE_SCSI:
   6.336 +    cdb = (PCDB)Srb->Cdb;
   6.337      //KdPrint((__DRIVER_NAME "     SRB_FUNCTION_EXECUTE_SCSI\n"));
   6.338 -    switch(Srb->Cdb[0]) {
   6.339 +    switch(cdb->CDB6GENERIC.OperationCode) { //Srb->Cdb[0]) {
   6.340      case SCSIOP_TEST_UNIT_READY:
   6.341        //KdPrint((__DRIVER_NAME "     Command = TEST_UNIT_READY\n"));
   6.342        Srb->SrbStatus = SRB_STATUS_SUCCESS;
   6.343 @@ -1054,19 +1130,22 @@ XenVbd_Child_PreprocessWdmIrpSCSI(WDFDEV
   6.344        IoCompleteRequest(Irp, IO_NO_INCREMENT);
   6.345        break;
   6.346      case SCSIOP_INQUIRY:
   6.347 -      //KdPrint((__DRIVER_NAME "     Command = INQUIRY (LUN = %d, EVPD = %d, Page Code = %02X)\n", Srb->Cdb[1] >> 5, Srb->Cdb[1] & 1, Srb->Cdb[2]));
   6.348 +      KdPrint((__DRIVER_NAME "     Command = INQUIRY\n"));
   6.349 +      KdPrint((__DRIVER_NAME "     (LUN = %d, EVPD = %d, Page Code = %02X)\n", Srb->Cdb[1] >> 5, Srb->Cdb[1] & 1, Srb->Cdb[2]));
   6.350        if ((Srb->Cdb[1] & 1) == 0)
   6.351        {
   6.352          memset(Srb->DataBuffer, 0, Srb->DataTransferLength);
   6.353          DataBuffer = Srb->DataBuffer;
   6.354          DataBuffer[0] = 0x00; // disk
   6.355          DataBuffer[1] = 0x00; // not removable
   6.356 -        memcpy(DataBuffer + 8, "James", 5); // vendor id
   6.357 -        memcpy(DataBuffer + 16, "XenVBD", 6); // product id
   6.358 +        memcpy(DataBuffer + 8, "James   ", 8); // vendor id
   6.359 +        memcpy(DataBuffer + 16, "XenVBD          ", 8); // product id
   6.360 +        memcpy(DataBuffer + 32, "000", 8); // product revision level
   6.361          Srb->SrbStatus = SRB_STATUS_SUCCESS;
   6.362        }
   6.363        else
   6.364        {
   6.365 +        //KdPrint((__DRIVER_NAME "     Command = INQUIRY (LUN = %d, EVPD = %d, Page Code = %02X)\n", Srb->Cdb[1] >> 5, Srb->Cdb[1] & 1, Srb->Cdb[2]));
   6.366          Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
   6.367        }
   6.368        Srb->ScsiStatus = 0;
   6.369 @@ -1093,18 +1172,32 @@ XenVbd_Child_PreprocessWdmIrpSCSI(WDFDEV
   6.370        IoCompleteRequest(Irp, IO_NO_INCREMENT);
   6.371        break;
   6.372      case SCSIOP_MODE_SENSE:
   6.373 -      //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));
   6.374 -      switch(Srb->Cdb[2] & 0x3F)
   6.375 +      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));
   6.376 +      KdPrint((__DRIVER_NAME "     Length = %d\n", Srb->DataTransferLength));
   6.377 +
   6.378 +      Srb->ScsiStatus = 0;
   6.379 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
   6.380 +      status = STATUS_SUCCESS; 
   6.381 +      switch(cdb->MODE_SENSE.PageCode) //Srb->Cdb[2] & 0x3F)
   6.382        {
   6.383 +      case MODE_SENSE_RETURN_ALL:
   6.384 +        Irp->IoStatus.Information = 0;
   6.385 +        //Ptr = (UCHAR *)Srb->DataBuffer;
   6.386 +        for (i = 0; i < MODE_SENSE_RETURN_ALL; i++)
   6.387 +        {
   6.388 +          if (XenVBD_FillModePage(ChildDeviceData, cdb->MODE_SENSE.PageCode, Srb->DataBuffer, cdb->MODE_SENSE.AllocationLength, &Irp->IoStatus.Information))
   6.389 +          {
   6.390 +            break;
   6.391 +          }
   6.392 +        }
   6.393 +        break;
   6.394        default:
   6.395 -        memset(Srb->DataBuffer, 0, Srb->DataTransferLength);
   6.396 -        Srb->ScsiStatus = 0;
   6.397 -        Srb->SrbStatus = SRB_STATUS_SUCCESS;
   6.398 -        status = STATUS_SUCCESS;
   6.399 -        Irp->IoStatus.Status = status;
   6.400 -        Irp->IoStatus.Information = Srb->DataTransferLength;
   6.401 -        IoCompleteRequest(Irp, IO_NO_INCREMENT);
   6.402 +        XenVBD_FillModePage(ChildDeviceData, cdb->MODE_SENSE.PageCode, Srb->DataBuffer, cdb->MODE_SENSE.AllocationLength, &Irp->IoStatus.Information);
   6.403 +        break;
   6.404        }
   6.405 +      Srb->DataTransferLength = Irp->IoStatus.Information;
   6.406 +      Irp->IoStatus.Status = status;
   6.407 +      IoCompleteRequest(Irp, IO_NO_INCREMENT);
   6.408        break;
   6.409      case SCSIOP_READ:
   6.410      case SCSIOP_WRITE:
   6.411 @@ -1125,11 +1218,14 @@ XenVbd_Child_PreprocessWdmIrpSCSI(WDFDEV
   6.412          }
   6.413          ListEntry->Irp = Irp;
   6.414          InsertTailList(&ChildDeviceData->IrpListHead, &ListEntry->Entry);
   6.415 -        //ChildDeviceData->IrpAddedToList++;
   6.416 +        ChildDeviceData->IrpAddedToList++;
   6.417        }
   6.418        else
   6.419        {
   6.420          XenVbd_PutIrpOnRing(Device, Irp);
   6.421 +        RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&ChildDeviceData->Ring, notify);
   6.422 +        if (notify)
   6.423 +          EvtChnInterface.Notify(ChildDeviceData->EventChannel);
   6.424          //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));
   6.425        }
   6.426        KeReleaseSpinLock(&ChildDeviceData->Lock, KIrql);
   6.427 @@ -1207,6 +1303,9 @@ XenVbd_Child_IoDeviceControl(WDFQUEUE Qu
   6.428    PSTORAGE_DEVICE_ID_DESCRIPTOR Sdid;
   6.429    PSTORAGE_IDENTIFIER Si;
   6.430    PSCSI_ADDRESS Sa;
   6.431 +  ULONG Information;
   6.432 +  //NTSTATUS Status;
   6.433 +  int StructEndOffset;
   6.434  
   6.435    UNREFERENCED_PARAMETER(Queue);
   6.436    //UNREFERENCED_PARAMETER(Request);
   6.437 @@ -1230,14 +1329,17 @@ XenVbd_Child_IoDeviceControl(WDFQUEUE Qu
   6.438      Spq = (PSTORAGE_PROPERTY_QUERY)Irp->AssociatedIrp.SystemBuffer;
   6.439      if (Spq->PropertyId == StorageAdapterProperty && Spq->QueryType == PropertyStandardQuery)
   6.440      {
   6.441 -      //KdPrint((__DRIVER_NAME "     PropertyId = StorageAdapterProperty, QueryType = PropertyStandardQuery\n"));
   6.442 +      KdPrint((__DRIVER_NAME "     PropertyId = StorageAdapterProperty, QueryType = PropertyStandardQuery\n"));
   6.443 +      Information = 0;
   6.444        if (OutputBufferLength >= 8)
   6.445        {
   6.446 +        Information = 8;
   6.447          Sad = (PSTORAGE_ADAPTER_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
   6.448          Sad->Version = 1;
   6.449          Sad->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
   6.450 -        if (OutputBufferLength >= sizeof(STORAGE_ADAPTER_DESCRIPTOR))
   6.451 +        if (OutputBufferLength >= Sad->Size)
   6.452          {
   6.453 +          Information = Sad->Size;
   6.454            Sad->MaximumTransferLength = 45056;
   6.455            Sad->MaximumPhysicalPages = 11;
   6.456            Sad->AlignmentMask = 0;
   6.457 @@ -1250,60 +1352,77 @@ XenVbd_Child_IoDeviceControl(WDFQUEUE Qu
   6.458            Sad->BusMinorVersion = 0;
   6.459          }
   6.460        }
   6.461 -      WdfRequestComplete(Request, STATUS_SUCCESS);
   6.462 +      WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, Information);
   6.463      }
   6.464      else if (Spq->PropertyId == StorageDeviceProperty && Spq->QueryType == PropertyStandardQuery)
   6.465      {
   6.466 -      //KdPrint((__DRIVER_NAME "     PropertyId = StorageDeviceProperty, QueryType = PropertyStandardQuery\n"));
   6.467 +      KdPrint((__DRIVER_NAME "     PropertyId = StorageDeviceProperty, QueryType = PropertyStandardQuery\n"));
   6.468 +      Information = 0;
   6.469        if (OutputBufferLength >= 8)
   6.470        {
   6.471 +        Information = 8;
   6.472          Sdd = (PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
   6.473          Sdd->Version = 1;
   6.474 -        Sdd->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 31 - 1;
   6.475 +        Sdd->Size = &Sdd->RawDeviceProperties[36] - (PUCHAR)Sdd + 1;
   6.476          // 0       0        1         2       3
   6.477          // 0       7        5         4       1
   6.478          //"VENDOR\0PRODUCT\0Revision\0Serial\0"
   6.479 -        if (OutputBufferLength >= sizeof(STORAGE_DEVICE_DESCRIPTOR) - 1 + 31)
   6.480 +        if (OutputBufferLength >= Sdd->Size)
   6.481          {
   6.482 +          Information = Sdd->Size;
   6.483            Sdd->DeviceType = 0x00;
   6.484            Sdd->DeviceTypeModifier = 0x00;
   6.485            Sdd->RemovableMedia = FALSE;
   6.486            Sdd->CommandQueueing = FALSE;
   6.487 -          Sdd->VendorIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) - 1 + 0;
   6.488 -          Sdd->ProductIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) - 1 + 7;
   6.489 -          Sdd->ProductRevisionOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) - 1 + 15;
   6.490 -          Sdd->SerialNumberOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) - 1 + 24;
   6.491 +          StructEndOffset = Sdd->RawDeviceProperties - (PUCHAR)Sdd;
   6.492 +          Sdd->VendorIdOffset = StructEndOffset + 0;
   6.493 +          Sdd->ProductIdOffset = StructEndOffset + 7;
   6.494 +          Sdd->ProductRevisionOffset = StructEndOffset + 15;
   6.495 +          Sdd->SerialNumberOffset = StructEndOffset + 24;
   6.496            Sdd->BusType = BusTypeScsi;
   6.497 -          Sdd->RawPropertiesLength = 31;
   6.498 -          memcpy(Sdd->RawDeviceProperties, "VENDOR\0PRODUCT\0Revision\0Serial\0", 31);
   6.499 +          Sdd->RawPropertiesLength = 36;
   6.500 +          memcpy(Sdd->RawDeviceProperties, "VENDOR\0PRODUCT\0Revision\0Serial99999\0", 36);
   6.501          }
   6.502        }
   6.503 -      WdfRequestComplete(Request, STATUS_SUCCESS);
   6.504 +      WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, Information);
   6.505      }
   6.506      else if (Spq->PropertyId == StorageDeviceIdProperty && Spq->QueryType == PropertyStandardQuery)
   6.507      {
   6.508 +      KdPrint((__DRIVER_NAME "     PropertyId = StorageDeviceIdProperty, QueryType = PropertyStandardQuery\n"));
   6.509 +      Information = 0;
   6.510        if (OutputBufferLength >= 8)
   6.511        {
   6.512 +        Information = 8;
   6.513          Sdid = (PSTORAGE_DEVICE_ID_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
   6.514          Sdid->Version = 1;
   6.515 -        Sdid->Size = sizeof(STORAGE_DEVICE_ID_DESCRIPTOR) - 1 + sizeof(STORAGE_IDENTIFIER) - 1 + 5;
   6.516 +        Si = (PSTORAGE_IDENTIFIER)Sdid->Identifiers;
   6.517 +        Sdid->Size = &Si->Identifier[8] - (PUCHAR)Sdid + 1;
   6.518          if (OutputBufferLength >= Sdid->Size)
   6.519          {
   6.520 +          Information = Sdid->Size;
   6.521            Sdid->NumberOfIdentifiers = 1;
   6.522 -          Si = (PSTORAGE_IDENTIFIER)Sdid->Identifiers;
   6.523 -          Si->CodeSet = 0;
   6.524 +          Si->CodeSet = StorageIdCodeSetAscii;
   6.525            Si->Type = StorageIdTypeScsiNameString;
   6.526 -          Si->IdentifierSize = 5;
   6.527 +          //Si->CodeSet = StorageIdCodeSetBinary;
   6.528 +          //Si->Type = StorageIdTypeEUI64;
   6.529 +          Si->IdentifierSize = 9;
   6.530            Si->NextOffset = 0;
   6.531 -          Si->Association = StorageIdAssocDevice;
   6.532 -          Si->Identifier[0] = 'J';
   6.533 -          Si->Identifier[0] = 'a';
   6.534 -          Si->Identifier[0] = 'm';
   6.535 -          Si->Identifier[0] = 'e';
   6.536 -          Si->Identifier[0] = 's';
   6.537 +          Si->Association = StorageIdAssocPort;
   6.538 +          Si->Identifier[0] = 'S';
   6.539 +          Si->Identifier[1] = 'e';
   6.540 +          Si->Identifier[2] = 'r';
   6.541 +          Si->Identifier[3] = 'i';
   6.542 +          Si->Identifier[4] = 'a';
   6.543 +          Si->Identifier[5] = 'l';
   6.544 +          Si->Identifier[6] = '9';
   6.545 +          Si->Identifier[7] = '9';
   6.546 +          Si->Identifier[6] = '9';
   6.547 +          Si->Identifier[7] = '9';
   6.548 +          Si->Identifier[8] = '9';
   6.549 +          //Si->Identifier[8] = 0;
   6.550          }
   6.551        }
   6.552 -      WdfRequestComplete(Request, STATUS_SUCCESS);
   6.553 +      WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, Information);
   6.554      }
   6.555      else
   6.556      {
   6.557 @@ -1336,11 +1455,6 @@ XenVbd_Child_IoDeviceControl(WDFQUEUE Qu
   6.558        case PropertyStandardQuery:
   6.559          KdPrint((__DRIVER_NAME "     PropertyStandardQuery\n"));
   6.560          break;        
   6.561 -      /*
   6.562 -      case PropertyIncludeSwIds:
   6.563 -        KdPrint((__DRIVER_NAME "     PropertyIncludeSwIds\n"));
   6.564 -        break;        
   6.565 -      */
   6.566        case PropertyExistsQuery:
   6.567          KdPrint((__DRIVER_NAME "     PropertyExistsQuery\n"));
   6.568          break;        
     7.1 --- a/xenvbd/xenvbd.h	Mon Nov 12 23:04:56 2007 +1100
     7.2 +++ b/xenvbd/xenvbd.h	Mon Nov 19 17:42:06 2007 +1100
     7.3 @@ -81,14 +81,17 @@ struct {
     7.4    ULONGLONG TotalSectors;
     7.5    DISK_GEOMETRY Geometry;
     7.6  
     7.7 -  //int IrpAddedToList;
     7.8 -  //int IrpRemovedFromList;
     7.9 -  //int IrpAddedToRing;
    7.10 -  //int IrpAddedToRingAtLastNotify;
    7.11 -  //int IrpAddedToRingAtLastInterrupt;
    7.12 -  //int IrpAddedToRingAtLastDpc;
    7.13 -  //int IrpRemovedFromRing;
    7.14 -  //int IrpCompleted;
    7.15 +  int IrpAddedToList;
    7.16 +  int IrpRemovedFromList;
    7.17 +  int IrpAddedToRing;
    7.18 +  int IrpAddedToRingAtLastNotify;
    7.19 +  int IrpAddedToRingAtLastInterrupt;
    7.20 +  int IrpAddedToRingAtLastDpc;
    7.21 +  int IrpRemovedFromRing;
    7.22 +  int IrpCompleted;
    7.23 +
    7.24 +  int FastPathUsed;
    7.25 +  int SlowPathUsed;
    7.26  
    7.27  } typedef XENVBD_CHILD_DEVICE_DATA, *PXENVBD_CHILD_DEVICE_DATA, **PPXENVBD_CHILD_DEVICE_DATA;
    7.28