repository: c:/kernel.org/kvm-guest-drivers-windows
branch: master
commit cbb86a13caafd329d5617efafbdc1964f3280d1f
Author: Vadim Rozenfeld <[email protected]>
Date:   Mon Sep 27 14:34:25 2010 +0200

    [balloon] add memory statistics support for kernel-mode part

diff --git a/Balloon/sys/Device.c b/Balloon/sys/Device.c
index 50d3eda..be05832 100644
--- a/Balloon/sys/Device.c
+++ b/Balloon/sys/Device.c
@@ -18,14 +18,32 @@
 #include "device.tmh"
 #endif
 
-#pragma alloc_text(PAGE, BalloonPrepareHardware)
-#pragma alloc_text(PAGE, BalloonReleaseHardware)
+EVT_WDF_DEVICE_PREPARE_HARDWARE     BalloonEvtDevicePrepareHardware;
+EVT_WDF_DEVICE_RELEASE_HARDWARE     BalloonEvtDeviceReleaseHardware;
+EVT_WDF_DEVICE_D0_ENTRY             BalloonEvtDeviceD0Entry;
+EVT_WDF_DEVICE_D0_EXIT              BalloonEvtDeviceD0Exit;
+EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED
BalloonEvtDeviceD0ExitPreInterruptsDisabled;
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, BalloonEvtDevicePrepareHardware)
+#pragma alloc_text(PAGE, BalloonEvtDeviceReleaseHardware)
+#pragma alloc_text(PAGE, BalloonEvtDeviceD0ExitPreInterruptsDisabled)
+#pragma alloc_text(PAGE, BalloonEvtDeviceD0Exit)
 #pragma alloc_text(PAGE, BalloonDeviceAdd)
+#pragma alloc_text(PAGE, BalloonEvtDeviceFileCreate)
+#pragma alloc_text(PAGE, BalloonEvtFileClose)
+#endif
+
+#if (WINVER >= 0x0501)
+#define LOMEMEVENTNAME L"\\KernelObjects\\LowMemoryCondition"
+DECLARE_CONST_UNICODE_STRING(evLowMemString, LOMEMEVENTNAME);
+#endif // (WINVER >= 0x0501)
 
-NTSTATUS BalloonDeviceAdd(
-                      IN WDFDRIVER  Driver,
-                      IN PWDFDEVICE_INIT  DeviceInit
-                      )
+
+NTSTATUS 
+BalloonDeviceAdd(
+    IN WDFDRIVER  Driver,
+    IN PWDFDEVICE_INIT  DeviceInit)
 {
     NTSTATUS                    status = STATUS_SUCCESS;
     WDFDEVICE                   device;
@@ -33,16 +51,32 @@ NTSTATUS BalloonDeviceAdd(
     WDF_OBJECT_ATTRIBUTES       attributes;
     WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
     WDF_INTERRUPT_CONFIG        interruptConfig;
+    WDF_FILEOBJECT_CONFIG       fileConfig;
 
     UNREFERENCED_PARAMETER(Driver);
 
     TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s\n",
__FUNCTION__);
 
     WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
-    pnpPowerCallbacks.EvtDevicePrepareHardware =
BalloonPrepareHardware;
-    pnpPowerCallbacks.EvtDeviceReleaseHardware =
BalloonReleaseHardware;
+    pnpPowerCallbacks.EvtDevicePrepareHardware =
BalloonEvtDevicePrepareHardware;
+    pnpPowerCallbacks.EvtDeviceReleaseHardware =
BalloonEvtDeviceReleaseHardware;
+    pnpPowerCallbacks.EvtDeviceD0Entry         =
BalloonEvtDeviceD0Entry;
+    pnpPowerCallbacks.EvtDeviceD0Exit          =
BalloonEvtDeviceD0Exit;
+    pnpPowerCallbacks.EvtDeviceD0ExitPreInterruptsDisabled =
BalloonEvtDeviceD0ExitPreInterruptsDisabled;
     WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit,
&pnpPowerCallbacks);
 
+
+    WDF_FILEOBJECT_CONFIG_INIT(
+                            &fileConfig,
+                            BalloonEvtDeviceFileCreate,
+                            BalloonEvtFileClose,
+                            WDF_NO_EVENT_CALLBACK
+                            );
+
+    WdfDeviceInitSetFileObjectConfig(DeviceInit,
+                            &fileConfig,
+                            WDF_NO_OBJECT_ATTRIBUTES);
+
     WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);
 
     WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes,
DEVICE_CONTEXT);
@@ -67,9 +101,9 @@ NTSTATUS BalloonDeviceAdd(
     interruptConfig.EvtInterruptDisable = BalloonInterruptDisable;
 
     status = WdfInterruptCreate(device,
-                              &interruptConfig,
-                              WDF_NO_OBJECT_ATTRIBUTES,
-                              &devCtx->WdfInterrupt);
+                            &interruptConfig,
+                            WDF_NO_OBJECT_ATTRIBUTES,
+                            &devCtx->WdfInterrupt);
     if (!NT_SUCCESS (status))
     {
         TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
@@ -98,7 +132,7 @@ NTSTATUS BalloonDeviceAdd(
 }
 
 NTSTATUS
-BalloonPrepareHardware(
+BalloonEvtDevicePrepareHardware(
     IN WDFDEVICE    Device,
     IN WDFCMRESLIST ResourceList,
     IN WDFCMRESLIST ResourceListTranslated
@@ -135,7 +169,6 @@ BalloonPrepareHardware(
         switch (desc->Type) {
 
             case CmResourceTypePort:
-
                 if (!foundPort && 
                      desc->u.Port.Length >= 0x20) {
 
@@ -180,21 +213,18 @@ BalloonPrepareHardware(
         TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, " Missing resources
\n");
         return STATUS_DEVICE_CONFIGURATION_ERROR;
     }
-
-    status = BalloonInit(Device);
-    if (status != STATUS_SUCCESS)
-    {
-        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, 
-           "BalloonInit failed with status 0x%08x\n", status);
-        return status;
-    }
+#if (WINVER >= 0x0501)
+    devCtx->evLowMem = IoCreateNotificationEvent(
+                               (PUNICODE_STRING )&evLowMemString,
+                               &devCtx->hLowMem);
+#endif // (WINVER >= 0x0501)
 
     TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s\n",
__FUNCTION__);
     return status;
 }
 
 NTSTATUS
-BalloonReleaseHardware (
+BalloonEvtDeviceReleaseHardware (
     WDFDEVICE      Device,
     WDFCMRESLIST   ResourcesTranslated
     )
@@ -207,9 +237,16 @@ BalloonReleaseHardware (
 
     PAGED_CODE();
 
-    BalloonTerm(Device);
     devCtx = GetDeviceContext(Device);
 
+#if (WINVER >= 0x0501)
+    if(devCtx->evLowMem)
+    {
+        ZwClose(devCtx->hLowMem);
+        devCtx->evLowMem = NULL;
+    }
+#endif // (WINVER >= 0x0501)
+
     if (devCtx->PortBase) {
         if (devCtx->PortMapped) {
             MmUnmapIoSpace( devCtx->PortBase,  devCtx->PortCount );
@@ -221,6 +258,80 @@ BalloonReleaseHardware (
     return STATUS_SUCCESS;
 }
 
+NTSTATUS
+BalloonEvtDeviceD0Entry(
+    IN  WDFDEVICE Device,
+    IN  WDF_POWER_DEVICE_STATE PreviousState
+    )
+{
+    PDEVICE_CONTEXT     devCtx = NULL;
+    NTSTATUS            status = STATUS_SUCCESS;
+    PDRIVER_CONTEXT     drvCtx = GetDriverContext(WdfGetDriver());
+
+    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "--> %s\n",
__FUNCTION__);
+    devCtx = GetDeviceContext(Device);
+    devCtx->bShutDown = FALSE;
+    status = BalloonInit(Device);
+    if(!NT_SUCCESS(status))
+    {
+        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
+           "BalloonInit failed with status 0x%08x\n", status);
+        return status;
+    }
+
+    if (devCtx->bServiceConnected &&
+       VirtIODeviceGetHostFeature(&devCtx->VDevice,
VIRTIO_BALLOON_F_STATS_VQ))
+    {
+        VirtIODeviceEnableGuestFeature(&devCtx->VDevice,
VIRTIO_BALLOON_F_STATS_VQ);
+    }
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+BalloonEvtDeviceD0Exit(
+    IN  WDFDEVICE Device,
+    IN  WDF_POWER_DEVICE_STATE TargetState
+    )
+{
+    PDEVICE_CONTEXT       devCtx = GetDeviceContext(Device);
+    PDRIVER_CONTEXT       drvCtx = GetDriverContext(WdfGetDriver());
+
+    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "<--> %s\n",
__FUNCTION__);
+
+    PAGED_CODE();
+
+    BalloonTerm(Device);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+BalloonEvtDeviceD0ExitPreInterruptsDisabled(
+    IN  WDFDEVICE Device,
+    IN  WDF_POWER_DEVICE_STATE TargetState
+    )
+{
+    PDEVICE_CONTEXT       devCtx = GetDeviceContext(Device);
+    PDRIVER_CONTEXT       drvCtx = GetDriverContext(WdfGetDriver());
+
+    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "<--> %s\n",
__FUNCTION__);
+
+    PAGED_CODE();
+
+    if (TargetState == WdfPowerDeviceD3Final)
+    {
+        devCtx->bShutDown = TRUE;
+
+        while(drvCtx->num_pages)
+        {
+           BalloonLeak(Device, drvCtx->num_pages);
+        }
+        SetBalloonSize(Device, drvCtx->num_pages);
+    }
+
+    return STATUS_SUCCESS;
+}
+
 
 BOOLEAN
 BalloonInterruptIsr(
@@ -230,8 +341,6 @@ BalloonInterruptIsr(
 {
     PDEVICE_CONTEXT     devCtx = NULL;
     WDFDEVICE           Device;
-    int hsr;
-    int hcr;
 
     UNREFERENCED_PARAMETER( MessageID );
 
@@ -262,18 +371,14 @@ FillLeakWorkItem(
     devCtx = GetDeviceContext(pItemContext->Device);
 
     if (pItemContext->Diff > 0) {
-        BalloonFill(pItemContext->Device, pItemContext->Diff);
+        BalloonFill(pItemContext->Device,
(size_t)(pItemContext->Diff));
     } else if (pItemContext->Diff < 0) {  
-        BalloonLeak(pItemContext->Device, -pItemContext->Diff);
+        BalloonLeak(pItemContext->Device,
(size_t)(-pItemContext->Diff));
     }
     SetBalloonSize(pItemContext->Device, drvCtx->num_pages); 
     if (pItemContext->bStatUpdate) {
         BalloonMemStats(pItemContext->Device);
     }
-    WdfInterruptSynchronize(
-        devCtx->WdfInterrupt,
-        RestartInterrupt,
-        devCtx);
 
     WdfObjectDelete(WorkItem);
 
@@ -296,21 +401,28 @@ BalloonInterruptDpc(
     WDF_WORKITEM_CONFIG   workitemConfig;
     WDFWORKITEM           hWorkItem;
     NTSTATUS              status = STATUS_SUCCESS;
-    size_t                num_pages;
     BOOLEAN               bStatUpdate = FALSE;
 
     UNREFERENCED_PARAMETER( WdfInterrupt );
 
     TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC, "--> %s\n",
__FUNCTION__);
   
-    devCtx->InfVirtQueue->vq_ops->get_buf(devCtx->InfVirtQueue, &len);
-    devCtx->DefVirtQueue->vq_ops->get_buf(devCtx->DefVirtQueue, &len);
-    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC, "-->
BalloonInterruptDpc 1\n");
+    if (devCtx->InfVirtQueue->vq_ops->get_buf(devCtx->InfVirtQueue,
&len))
+    {
+        KeSetEvent (&drvCtx->InfEvent, IO_NO_INCREMENT, FALSE);
+    }
+    if (devCtx->DefVirtQueue->vq_ops->get_buf(devCtx->DefVirtQueue,
&len))
+    {
+        KeSetEvent (&drvCtx->DefEvent, IO_NO_INCREMENT, FALSE);
+    }
     if(devCtx->StatVirtQueue &&
        devCtx->StatVirtQueue->vq_ops->get_buf(devCtx->StatVirtQueue,
&len)) {
        bStatUpdate = TRUE;
     }
-    num_pages = GetBalloonSize(WdfDevice);
+    if (devCtx->bShutDown == TRUE)
+    {
+        return;
+    }
 
     WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
     WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attributes,
WORKITEM_CONTEXT);
@@ -330,12 +442,12 @@ BalloonInterruptDpc(
     context = GetWorkItemContext(hWorkItem);
 
     context->Device = WdfDevice;
-    context->Diff = num_pages - drvCtx->num_pages;
+    context->Diff = GetBalloonSize(WdfDevice);
+
     context->bStatUpdate = bStatUpdate;
 
     WdfWorkItemEnqueue(hWorkItem);
 
-    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC, "<-- %s\n",
__FUNCTION__);
     return;
 }
 
@@ -373,3 +485,81 @@ BalloonInterruptDisable(
     TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- %s\n",
__FUNCTION__);
     return STATUS_SUCCESS;
 }
+
+VOID
+BalloonEvtDeviceFileCreate (
+    IN WDFDEVICE WdfDevice,
+    IN WDFREQUEST Request,
+    IN WDFFILEOBJECT FileObject
+    )
+{
+    PDEVICE_CONTEXT     devCtx = NULL;
+
+    UNREFERENCED_PARAMETER(FileObject);
+
+    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"%s\n", __FUNCTION__);
+
+    PAGED_CODE ();
+
+    devCtx = GetDeviceContext(WdfDevice);
+
+    if(VirtIODeviceGetHostFeature(&devCtx->VDevice,
VIRTIO_BALLOON_F_STATS_VQ))
+    {
+        VirtIODeviceEnableGuestFeature(&devCtx->VDevice,
VIRTIO_BALLOON_F_STATS_VQ);
+        devCtx->bServiceConnected = TRUE;
+    }
+    WdfRequestComplete(Request, STATUS_SUCCESS);
+
+    return;
+}
+
+
+VOID
+BalloonEvtFileClose (
+    IN WDFFILEOBJECT    FileObject
+    )
+{
+    PDEVICE_CONTEXT     devCtx = NULL;
+
+    PAGED_CODE ();
+
+    devCtx = GetDeviceContext(WdfFileObjectGetDevice(FileObject));
+
+    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "%s\n",
__FUNCTION__);
+
+    if(VirtIODeviceGetHostFeature(&devCtx->VDevice,
VIRTIO_BALLOON_F_STATS_VQ))
+    {
+       ULONG ulValue = 0;
+
+       ulValue = ReadVirtIODeviceRegister(devCtx->VDevice.addr +
VIRTIO_PCI_GUEST_FEATURES);
+       ulValue &= ~(1 << VIRTIO_BALLOON_F_STATS_VQ);
+       WriteVirtIODeviceRegister(devCtx->VDevice.addr +
VIRTIO_PCI_GUEST_FEATURES, ulValue);
+        devCtx->bServiceConnected = FALSE;
+    }
+    return;
+}
+
+VOID
+SetBalloonSize(
+    IN WDFOBJECT WdfDevice,
+    IN size_t    num
+    )
+{
+    PDEVICE_CONTEXT       devCtx = GetDeviceContext(WdfDevice);
+    u32 actual = (u32)num;
+    VirtIODeviceSet(&devCtx->VDevice,
FIELD_OFFSET(VIRTIO_BALLOON_CONFIG, actual), &actual, sizeof(actual));
+}
+
+LONGLONG
+GetBalloonSize(
+    IN WDFOBJECT WdfDevice
+    )
+{
+    PDEVICE_CONTEXT       devCtx = GetDeviceContext(WdfDevice);
+    PDRIVER_CONTEXT       drvCtx = GetDriverContext(WdfGetDriver());
+
+    u32 v;
+    VirtIODeviceGet(&devCtx->VDevice,
FIELD_OFFSET(VIRTIO_BALLOON_CONFIG, num_pages), &v, sizeof(v));
+    return (LONGLONG)v - drvCtx->num_pages;
+}
+
diff --git a/Balloon/sys/Driver.c b/Balloon/sys/Driver.c
index d23b555..e4bfb41 100644
--- a/Balloon/sys/Driver.c
+++ b/Balloon/sys/Driver.c
@@ -19,8 +19,8 @@
 #endif
 
 #if !defined(EVENT_TRACING)
-ULONG DebugLevel = TRACE_LEVEL_INFORMATION;
-ULONG DebugFlag = 0x2f;
+ULONG DebugLevel = TRACE_LEVEL_WARNING;
+ULONG DebugFlag = 0x0000ffff;
 #else
 ULONG DebugLevel;
 ULONG DebugFlag;
@@ -43,7 +43,8 @@ NTSTATUS DriverEntry(
 
     WPP_INIT_TRACING( DriverObject, RegistryPath );
 
-    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"--> %s\n",
__FUNCTION__);
+    TraceEvents(TRACE_LEVEL_WARNING, DBG_HW_ACCESS, "Balloon driver,
built on %s %s\n",
+            __DATE__, __TIME__);
 
     WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attrib, DRIVER_CONTEXT);
     attrib.EvtCleanupCallback = EvtDriverContextCleanup;
@@ -60,6 +61,7 @@ NTSTATUS DriverEntry(
     {
         TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,"WdfDriverCreate failed
with status 0x%08x\n", status);
         WPP_CLEANUP(DriverObject);
+        return status;
     }
 
     drvCxt = GetDriverContext(driver);
@@ -105,6 +107,7 @@ NTSTATUS DriverEntry(
         WPP_CLEANUP(DriverObject);
         return status;
     }
+    RtlFillMemory (drvCxt->MemStats, sizeof (BALLOON_STAT) *
VIRTIO_BALLOON_S_NR, -1);
     WDF_OBJECT_ATTRIBUTES_INIT(&attrib);
     attrib.ParentObject = driver;
 
@@ -115,6 +118,16 @@ NTSTATUS DriverEntry(
         return status;
     }
 
+    KeInitializeEvent(&drvCxt->InfEvent,
+                      SynchronizationEvent,
+                      FALSE
+                      );
+
+    KeInitializeEvent(&drvCxt->DefEvent,
+                      SynchronizationEvent,
+                      FALSE
+                      );
+
     TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"<-- %s\n",
__FUNCTION__);
 
     LogError( DriverObject, BALLOON_STARTED);
@@ -218,8 +231,7 @@ TraceEvents    (
                       status));
             return;
         }
-        if (TraceEventsLevel <= TRACE_LEVEL_INFORMATION ||
-            (TraceEventsLevel <= DebugLevel &&
+        if ((TraceEventsLevel <= DebugLevel &&
              ((TraceEventsFlag & DebugFlag) == TraceEventsFlag))) {
             BalloonDbgPrint((debugMessageBuffer));
         }
diff --git a/Balloon/sys/ProtoTypes.h b/Balloon/sys/ProtoTypes.h
index e300960..85c5f05 100644
--- a/Balloon/sys/ProtoTypes.h
+++ b/Balloon/sys/ProtoTypes.h
@@ -17,7 +17,7 @@
 
 #include "virtio.h"
 #include "public.h"
-
+#include "trace.h"
 
 /* The ID for virtio_balloon */
 #define VIRTIO_ID_BALLOON      5
@@ -60,26 +60,29 @@ typedef struct _DEVICE_CONTEXT {
     PVIOQUEUE           DefVirtQueue;
     PVIOQUEUE           StatVirtQueue;
     BOOLEAN             bTellHostFirst;
-    WDFQUEUE            StatusQueue;
+    BOOLEAN             bServiceConnected;
+    BOOLEAN             bShutDown;
 } DEVICE_CONTEXT, *PDEVICE_CONTEXT;
 
 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext);
 
 typedef struct _DRIVER_CONTEXT {
-    volatile ULONG          num_pages;   
+    volatile ULONG          num_pages;
     ULONG                   num_pfns;
     PPFN_NUMBER             pfns_table;
     NPAGED_LOOKASIDE_LIST   LookAsideList;
     SINGLE_LIST_ENTRY       PageListHead;
     WDFSPINLOCK             SpinLock;
     PBALLOON_STAT           MemStats;
+    KEVENT                  InfEvent;
+    KEVENT                  DefEvent;
 } DRIVER_CONTEXT, * PDRIVER_CONTEXT;
 
 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DRIVER_CONTEXT, GetDriverContext)
 
 typedef struct _WORKITEM_CONTEXT {
     WDFDEVICE           Device;
-    LONG                Diff;
+    LONGLONG            Diff;
     BOOLEAN             bStatUpdate;
 } WORKITEM_CONTEXT, *PWORKITEM_CONTEXT;
 
@@ -93,19 +96,8 @@ WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WORKITEM_CONTEXT,
GetWorkItemContext)
 DRIVER_INITIALIZE DriverEntry; 
 EVT_WDF_OBJECT_CONTEXT_CLEANUP EvtDriverContextCleanup;
 EVT_WDF_DRIVER_DEVICE_ADD BalloonDeviceAdd;
-
-NTSTATUS
-BalloonPrepareHardware(
-    IN WDFDEVICE    Device,
-    IN WDFCMRESLIST ResourceList,
-    IN WDFCMRESLIST ResourceListTranslated
-    );
-
-NTSTATUS
-BalloonReleaseHardware(
-    IN WDFDEVICE    Device,
-    IN WDFCMRESLIST ResourceList
-    );
+EVT_WDF_DEVICE_FILE_CREATE BalloonEvtDeviceFileCreate;
+EVT_WDF_FILE_CLOSE BalloonEvtFileClose;
 
 VOID
 BalloonInterruptDpc(
@@ -141,14 +133,6 @@ BalloonTerm(
     IN WDFOBJECT    WdfDevice
     );
 
-__inline VOID
-DisableInterrupt(
-    IN PDEVICE_CONTEXT devCtx
-    )
-{
-    UNREFERENCED_PARAMETER(devCtx);
-}
-
 VOID 
 BalloonFill(
     IN WDFOBJECT WdfDevice, 
@@ -169,10 +153,13 @@ BalloonMemStats(
 VOID 
 BalloonTellHost(
     IN WDFOBJECT WdfDevice, 
-    IN PVIOQUEUE vq
+    IN PVIOQUEUE vq,
+    IN PVOID     ev
     );
 
-__inline BOOLEAN EnableInterrupt(
+__inline
+BOOLEAN
+EnableInterrupt(
     IN WDFINTERRUPT WdfInterrupt,
     IN WDFCONTEXT Context
     )
@@ -180,39 +167,52 @@ __inline BOOLEAN EnableInterrupt(
     PDEVICE_CONTEXT devCtx = (PDEVICE_CONTEXT)Context;
     UNREFERENCED_PARAMETER(WdfInterrupt);
 
+
devCtx->InfVirtQueue->vq_ops->enable_interrupt(devCtx->InfVirtQueue,
TRUE);
     devCtx->InfVirtQueue->vq_ops->kick(devCtx->InfVirtQueue);
+
devCtx->DefVirtQueue->vq_ops->enable_interrupt(devCtx->DefVirtQueue,
TRUE);
+    devCtx->DefVirtQueue->vq_ops->kick(devCtx->DefVirtQueue);
+
+    if (devCtx->StatVirtQueue)
+    {
+
devCtx->StatVirtQueue->vq_ops->enable_interrupt(devCtx->StatVirtQueue,
TRUE);
+       devCtx->StatVirtQueue->vq_ops->kick(devCtx->StatVirtQueue);
+    }
     return TRUE;
 }
 
-__inline VOID 
-SetBalloonSize(
-    IN WDFOBJECT WdfDevice, 
-    IN size_t    num
+__inline
+VOID
+DisableInterrupt(
+    IN PDEVICE_CONTEXT devCtx
     )
 {
-    PDEVICE_CONTEXT       devCtx = GetDeviceContext(WdfDevice);
-    VIRTIO_BALLOON_CONFIG v;
-    v.actual = num;
-    VirtIODeviceSet(&devCtx->VDevice,
FIELD_OFFSET(VIRTIO_BALLOON_CONFIG, actual), &v.actual,
sizeof(v.actual));
+
devCtx->InfVirtQueue->vq_ops->enable_interrupt(devCtx->InfVirtQueue,
FALSE);
+
devCtx->DefVirtQueue->vq_ops->enable_interrupt(devCtx->DefVirtQueue,
FALSE);
+    if (devCtx->StatVirtQueue)
+    {
+
devCtx->StatVirtQueue->vq_ops->enable_interrupt(devCtx->StatVirtQueue,
FALSE);
+    }
 }
 
-__inline size_t 
+
+VOID
+SetBalloonSize(
+    IN WDFOBJECT WdfDevice,
+    IN size_t    num
+    );
+
+LONGLONG
 GetBalloonSize(
     IN WDFOBJECT WdfDevice
-    )
-{
-    PDEVICE_CONTEXT       devCtx = GetDeviceContext(WdfDevice);
-    VIRTIO_BALLOON_CONFIG v;
-    VirtIODeviceGet(&devCtx->VDevice,
FIELD_OFFSET(VIRTIO_BALLOON_CONFIG, num_pages), &v.num_pages,
sizeof(v.num_pages));
-    return v.num_pages;
-}
+    );
 
 NTSTATUS
 BalloonQueueInitialize(
     WDFDEVICE hDevice
     );
 
-__inline BOOLEAN
+__inline
+BOOLEAN
 RestartInterrupt(
     IN WDFINTERRUPT WdfInterrupt,
     IN WDFCONTEXT Context
diff --git a/Balloon/sys/balloon.c b/Balloon/sys/balloon.c
index f63b802..177d74b 100644
--- a/Balloon/sys/balloon.c
+++ b/Balloon/sys/balloon.c
@@ -19,14 +19,9 @@
 #endif
 
 
-#if (WINVER >= 0x0501)
-#define LOMEMEVENTNAME L"\\KernelObjects\\LowMemoryCondition"
-DECLARE_CONST_UNICODE_STRING(evLowMemString, LOMEMEVENTNAME);
-#endif // (WINVER >= 0x0501)
-
 NTSTATUS
 BalloonInit(
-            IN WDFOBJECT    WdfDevice
+    IN WDFOBJECT    WdfDevice
             )
 {
 
@@ -71,22 +66,15 @@ BalloonInit(
 

if(devCtx->StatVirtQueue->vq_ops->add_buf(devCtx->StatVirtQueue, &sg, 1,
0, devCtx) != 0)
         {
-            TraceEvents(TRACE_LEVEL_ERROR, DBG_HW_ACCESS, "<-> Cannot
add buffer\n");
+            TraceEvents(TRACE_LEVEL_ERROR, DBG_HW_ACCESS, "<-> %s ::
Cannot add buffer\n", __FUNCTION__);
         }
 
         devCtx->StatVirtQueue->vq_ops->kick(devCtx->StatVirtQueue);
 
-        VirtIODeviceEnableGuestFeature(&devCtx->VDevice,
VIRTIO_BALLOON_F_STATS_VQ);
     }
     devCtx->bTellHostFirst
         = (BOOLEAN)VirtIODeviceGetHostFeature(&devCtx->VDevice,
VIRTIO_BALLOON_F_MUST_TELL_HOST); 
 
-#if (WINVER >= 0x0501)
-    devCtx->evLowMem = IoCreateNotificationEvent(
-                               (PUNICODE_STRING )&evLowMemString,
-                               &devCtx->hLowMem);
-#endif // (WINVER >= 0x0501)
-
 free_mem:
     KeMemoryBarrier();
 
@@ -113,12 +101,6 @@ BalloonTerm(
 
     TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> BalloonTerm\n");
 
-    while(drvCtx->num_pages)
-    {
-        BalloonLeak(WdfDevice, drvCtx->num_pages);
-    }
-
-    SetBalloonSize(WdfDevice, drvCtx->num_pages); 
     VirtIODeviceRemoveStatus(&devCtx->VDevice ,
VIRTIO_CONFIG_S_DRIVER_OK);
 
     if(devCtx->DefVirtQueue) 
@@ -144,11 +126,6 @@ BalloonTerm(
 
     VirtIODeviceReset(&devCtx->VDevice);
 
-
-#if (WINVER >= 0x0501)
-    ZwClose(&devCtx->hLowMem);
-#endif // (WINVER >= 0x0501)
-
     TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- BalloonTerm\n");
 }
 
@@ -165,17 +142,19 @@ BalloonFill(
     PDEVICE_CONTEXT     devCtx = GetDeviceContext(WdfDevice);
     ULONG               pages_per_request =
PAGE_SIZE/sizeof(PFN_NUMBER); 
 
-    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "-->
BalloonFill\n");
+    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "--> %s\n",
__FUNCTION__);
 
     LowAddress.QuadPart = 0;
     HighAddress.QuadPart = (ULONGLONG)-1;
 
     num = min(num, pages_per_request);
+    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "-->
BalloonFill num = %d\n", num);
+
     for (drvCtx->num_pfns = 0; drvCtx->num_pfns < num; drvCtx->num_pfns
++) 
     {
         if(IsLowMemory(WdfDevice))
         {
-           TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, 
+           TraceEvents(TRACE_LEVEL_WARNING, DBG_HW_ACCESS,
                 "LowMemoryCondition event was set to
signaled,allocations stops, BalPageCount=%d\n", drvCtx->num_pages);
            break;
         }
@@ -187,14 +166,14 @@ BalloonFill(
                                         );
         if (pPageMdl == NULL)
         {
-            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, 
+            TraceEvents(TRACE_LEVEL_WARNING, DBG_HW_ACCESS,
                  "Balloon MDL Page Allocation Failed!!!, BalPageCount=%
d\n", drvCtx->num_pages);
             break;
         }
 
         if (MmGetMdlByteCount(pPageMdl) != PAGE_SIZE)
         {
-            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, 
+            TraceEvents(TRACE_LEVEL_WARNING, DBG_HW_ACCESS,
                  "Balloon MDL Page Allocation < PAGE_SIZE =%d,
Failed!!!, BalPageCount=%d\n",MmGetMdlByteCount(pPageMdl),
drvCtx->num_pages);
             MmFreePagesFromMdl(pPageMdl);
             ExFreePool(pPageMdl);
@@ -221,9 +200,8 @@ BalloonFill(
 
     if (drvCtx->num_pfns > 0)
     {
-        BalloonTellHost(WdfDevice , devCtx->InfVirtQueue);
+        BalloonTellHost(WdfDevice , devCtx->InfVirtQueue,
&drvCtx->InfEvent);
     }
-    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "<--
BalloonFill\n");
 }
 
 VOID 
@@ -238,7 +216,7 @@ BalloonLeak(
     PDEVICE_CONTEXT     devCtx = GetDeviceContext(WdfDevice);
     PDRIVER_CONTEXT     drvCtx = GetDriverContext(WdfGetDriver());
 
-    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "-->
BalloonLeak\n");
+    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "--> %s\n",
__FUNCTION__);
     
     num = min(num, PAGE_SIZE/sizeof(PFN_NUMBER));
 
@@ -249,7 +227,7 @@ BalloonLeak(
     {
         if (pPageListEntry == NULL)
         {
-            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS,
"PopEntryList=NULL\n");
+            TraceEvents(TRACE_LEVEL_WARNING, DBG_HW_ACCESS,
"PopEntryList=NULL\n");
             break;
         }
         drvCtx->pfns_table[drvCtx->num_pfns] = pPageListEntry->PagePfn;
@@ -259,7 +237,7 @@ BalloonLeak(
  
     if (devCtx->bTellHostFirst) 
     {
-        BalloonTellHost(WdfDevice, devCtx->DefVirtQueue);
+        BalloonTellHost(WdfDevice, devCtx->DefVirtQueue,
&drvCtx->DefEvent);
     }
 
     for (i = 0; i < drvCtx->num_pfns; i++) 
@@ -267,14 +245,15 @@ BalloonLeak(
 
         WdfSpinLockAcquire(drvCtx->SpinLock);
         pPageListEntry =
(PPAGE_LIST_ENTRY)PopEntryList(&drvCtx->PageListHead);
-        drvCtx->num_pages--;
-        WdfSpinLockRelease(drvCtx->SpinLock);
 
         if (pPageListEntry == NULL)
         {
-           TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS,
"PopEntryList=NULL\n");
+           TraceEvents(TRACE_LEVEL_WARNING, DBG_HW_ACCESS,
"PopEntryList=NULL\n");
+           WdfSpinLockRelease(drvCtx->SpinLock);
            break;
         }
+        drvCtx->num_pages--;
+        WdfSpinLockRelease(drvCtx->SpinLock);
 
         pPageMdl = pPageListEntry->PageMdl;
         MmFreePagesFromMdl(pPageMdl);
@@ -288,36 +267,48 @@ BalloonLeak(
 
     if (!devCtx->bTellHostFirst) 
     {
-        BalloonTellHost(WdfDevice, devCtx->DefVirtQueue);
+        BalloonTellHost(WdfDevice, devCtx->DefVirtQueue,
&drvCtx->DefEvent);
     }
-
-    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "<--
BalloonLeak\n");
 }
 
 VOID 
 BalloonTellHost(
     IN WDFOBJECT WdfDevice, 
-    IN PVIOQUEUE vq
+    IN PVIOQUEUE vq,
+    IN PVOID     ev
     )
 {
     VIO_SG              sg;
     PDEVICE_CONTEXT     devCtx = GetDeviceContext(WdfDevice);
     PDRIVER_CONTEXT     drvCtx = GetDriverContext(WdfGetDriver());
+    NTSTATUS            status;
+    LARGE_INTEGER       timeout = {0};
 
-    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "-->
BalloonTellHost\n");
+    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "--> %s\n",
__FUNCTION__);
 
     sg.physAddr = GetPhysicalAddress(drvCtx->pfns_table);
     sg.ulSize = sizeof(drvCtx->pfns_table[0]) * drvCtx->num_pfns;
 
     if(vq->vq_ops->add_buf(vq, &sg, 1, 0, devCtx) != 0)
     {
-        TraceEvents(TRACE_LEVEL_ERROR, DBG_HW_ACCESS, "<-> Cannot add
buffer\n");
+        TraceEvents(TRACE_LEVEL_ERROR, DBG_HW_ACCESS, "<-> %s :: Cannot
add buffer\n", __FUNCTION__);
+        return;
     }
-
     vq->vq_ops->kick(vq);
-    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "<--
BalloonTellHost\n");
-}
 
+    timeout.QuadPart = Int32x32To64(1000, -10000);
+    status = KeWaitForSingleObject (
+                ev,
+                Executive,
+                KernelMode,
+                FALSE,
+                &timeout);
+    ASSERT(NT_SUCCESS(status));
+    if(STATUS_TIMEOUT == status)
+    {
+        TraceEvents(TRACE_LEVEL_WARNING, DBG_HW_ACCESS, "<--> TimeOut
\n");
+    }
+}
 
 VOID 
 BalloonMemStats(
@@ -329,23 +320,18 @@ BalloonMemStats(
     PDRIVER_CONTEXT     drvCtx = GetDriverContext(WdfGetDriver());
     WDFREQUEST request;
     NTSTATUS  status;
-    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "--> %s\n",
__FUNCTION__);
-    status = WdfIoQueueRetrieveNextRequest(devCtx->StatusQueue,
&request);
 
-    if (NT_SUCCESS(status)) {
-        TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS,"got
available request\n");
-        WdfRequestComplete(request, STATUS_SUCCESS);
-    } else {
-        sg.physAddr = GetPhysicalAddress(drvCtx->MemStats);
-        sg.ulSize = 0;
+    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "--> %s\n",
__FUNCTION__);
 
-
if(devCtx->StatVirtQueue->vq_ops->add_buf(devCtx->StatVirtQueue, &sg, 1,
0, devCtx) != 0)
-        {
-            TraceEvents(TRACE_LEVEL_ERROR, DBG_HW_ACCESS, "<-> Cannot
add buffer\n");
-        }
+    sg.physAddr = GetPhysicalAddress(drvCtx->MemStats);
+    sg.ulSize = sizeof(BALLOON_STAT) * VIRTIO_BALLOON_S_NR;
 
-        devCtx->StatVirtQueue->vq_ops->kick(devCtx->StatVirtQueue);
+    if(devCtx->StatVirtQueue->vq_ops->add_buf(devCtx->StatVirtQueue,
&sg, 1, 0, devCtx) != 0)
+    {
+        TraceEvents(TRACE_LEVEL_ERROR, DBG_HW_ACCESS, "<-> %s :: Cannot
add buffer\n", __FUNCTION__);
     }
+
+    devCtx->StatVirtQueue->vq_ops->kick(devCtx->StatVirtQueue);
     TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "<-- %s\n",
__FUNCTION__);
 }
 
diff --git a/Balloon/sys/balloon.inx b/Balloon/sys/balloon.inx
index 3da2ad3..538abdf 100644
--- a/Balloon/sys/balloon.inx
+++ b/Balloon/sys/balloon.inx
@@ -1,6 +1,6 @@
 ;/*++
 ;
-;Copyright (c) 2005-2009 Red Hat Inc.
+;Copyright (c) 2005-2010 Red Hat Inc.
 ;
 ;Module Name:
 ;    BALLOON.INF
@@ -16,22 +16,13 @@
 Signature="$WINDOWS NT$"
 Class=System
 ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}
-Provider=%QMRNT%
+Provider=%RHEL%
 DriverVer=05/19/2008,6.0.6000.16386
 CatalogFile=Balloon.cat
 
 [DestinationDirs]
 DefaultDestDir = 12
 
-; ================= Class section =====================
-
-[ClassInstall32]
-Addreg=BalloonClassReg     
-
-[BalloonClassReg]
-HKR,,,0,%ClassName%
-HKR,,Icon,,-5
-
 [SourceDisksNames]
 1 = %DiskId1%,,,""
 
@@ -80,7 +71,7 @@ LoadOrderGroup = Extended Base
 
 ; -------------- BALLOON driver eventlog install sections
 [BALLOON_Logging_Inst]
-AddReg = BALOON_Logging_Inst_AddReg
+AddReg = BALLOON_Logging_Inst_AddReg
 
 [BALLOON_Logging_Inst_AddReg]
 HKR,,EventMessageFile,0x00020000,"%%SystemRoot%%\System32\IoLogMsg.dll;
%%SystemRoot%%\System32\drivers\BALLOON.sys"
@@ -113,7 +104,7 @@ KmdfLibraryVersion = $KMDFVERSION$
 
 [Strings]
 SPSVCINST_ASSOCSERVICE= 0x00000002
-QMRNT = "Red Hat Inc."
+RHEL = "Red Hat Inc."
 StdMfg = "VirtIO ballooning devices"
 DiskId1 = "VirtIO Balloon Installation Disk #1"
 BALLOON.DeviceDesc = "VirtIO Balloon Driver"
diff --git a/Balloon/sys/makefile.inc b/Balloon/sys/makefile.inc
index 81ffd40..3016f96 100644
--- a/Balloon/sys/makefile.inc
+++ b/Balloon/sys/makefile.inc
@@ -1,6 +1,6 @@
 _LNG=$(LANGUAGE)
 _INX=.
-STAMP=stampinf -f $@ -a $(_BUILDARCH) -k
$(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR)
+STAMP=stampinf -f $@ -d * -a $(_BUILDARCH) -k
$(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR)
 
 $(OBJ_PATH)\$(O)\$(INF_NAME).inf: $(_INX)\$(INF_NAME).inx 
     copy $(_INX)\$(@B).inx $@
diff --git a/Balloon/sys/packOne.bat b/Balloon/sys/packOne.bat
index 6aa134c..f7545d9 100644
--- a/Balloon/sys/packOne.bat
+++ b/Balloon/sys/packOne.bat
@@ -50,6 +50,34 @@ copy /Y %PDB_PATH_AND_NAME% ..\Install\%INST_OS%\%
INST_ARC%
 copy /Y %INF_PATH_AND_NAME% ..\Install\%INST_OS%\%INST_ARC%
 copy /Y %WDF_PATH_AND_NAME% ..\Install\%INST_OS%\%INST_ARC%
 
+:create_cat
+echo "Setting OS mask for:" %1 %2
+
+if /i "%1"=="wlh" goto create_vista
+if /i "%1"=="win7" goto create_vista
+if /i "%1"=="wnet" goto create_xp
+if /i "%1"=="wxp" goto create_xp
+goto error_cat2inf
+
+:create_xp
+if /i "%2"=="x86" set _OSMASK_=XP_X86,Server2003_X86
+if /i "%2"=="x64" set _OSMASK_=XP_X64,Server2003_X64
+goto run_cat2inf
+
+:create_vista
+if /i "%2"=="x86" set _OSMASK_=Vista_X86,Server2008_X86,7_X86
+if /i "%2"=="x64" set
_OSMASK_=Vista_X64,Server2008_X64,7_X64,Server2008R2_X64
+goto run_cat2inf
+
+:error_cat2inf
+echo "Error setting OS mask for inf2cat"
+goto after_cat2inf
+
+:run_cat2inf
+inf2cat /driver:..\Install\%INST_OS%\%INST_ARC% /os:%_OSMASK_%
+rem pause
+:after_cat2inf
+
 set INST_OS=
 set INST_ARC=
 set FILE_NAME=
diff --git a/Balloon/sys/queue.c b/Balloon/sys/queue.c
index 226e211..923a4c8 100644
--- a/Balloon/sys/queue.c
+++ b/Balloon/sys/queue.c
@@ -34,22 +34,6 @@ BalloonQueueInitialize(
         TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfIoQueueCreate
failed 0x%08x\n", status);
         return status;
     }
-
-    devCtx = GetDeviceContext(Device);
-
-    WDF_IO_QUEUE_CONFIG_INIT(
-                 &queueConfig,
-                 WdfIoQueueDispatchManual);
-    status = WdfIoQueueCreate(
-                 Device,
-                 &queueConfig,
-                 WDF_NO_OBJECT_ATTRIBUTES,
-                 &devCtx->StatusQueue);
-
-    if( !NT_SUCCESS(status) ) {
-        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfIoQueueCreate
failed 0x%08x\n", status);
-        return status;
-    }
     return status;
 }
 
@@ -60,56 +44,45 @@ BalloonIoWrite(
     IN size_t     Length
     )
 {
-    WDFMEMORY              memory;
-    VIO_SG                 sg;
-    PVIOQUEUE              vq;
-    PDEVICE_CONTEXT        devCtx =
GetDeviceContext(WdfIoQueueGetDevice( Queue ));
-    PDRIVER_CONTEXT        drvCtx = GetDriverContext(WdfGetDriver());
+    PVOID                  buffer = NULL;
+    size_t                 buffSize;
     NTSTATUS               status = STATUS_SUCCESS;
+    WDFDRIVER              drv;
 
-    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "BalloonIoWrite
Called! Queue 0x%p, Request 0x%p Length %d\n",
+    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "BalloonIoWrite
Called! Queue 0x%p, Request 0x%p Length %d\n",
              Queue,Request,Length);
 
     if( Length < sizeof(BALLOON_STAT)) {
-        TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "BalloonIoWrite
Buffer Length to small %d, expected is %d\n",
+        TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS,
"BalloonIoWrite Buffer Length too small %d, expected is %d\n",
                  Length, sizeof(BALLOON_STAT));
-        WdfRequestCompleteWithInformation(Request,
STATUS_BUFFER_OVERFLOW, 0L);
+        WdfRequestComplete(Request, STATUS_BUFFER_TOO_SMALL);
         return;
     }
 
-    status = WdfRequestRetrieveInputMemory(Request, &memory);
-    if( !NT_SUCCESS(status) ) {
-        TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "BalloonIoWrite
Could not get request memory buffer 0x%08x\n",
+    status = WdfRequestRetrieveInputBuffer(Request,
sizeof(BALLOON_STAT), &buffer, &buffSize);
+    if( !NT_SUCCESS(status) || (buffer == NULL)) {
+        TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS,
"BalloonIoWrite Could not get request memory buffer 0x%08x\n",
                  status);
-        WdfVerifierDbgBreakPoint();
-        WdfRequestComplete(Request, status);
+        WdfRequestCompleteWithInformation(Request, status, 0L);
         return;
     }
 
-    status = WdfMemoryCopyToBuffer( 
-                             memory,
-                             0,
-                             drvCtx->MemStats,
-                             Length );
-    if( !NT_SUCCESS(status) ) {
-        TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS,
"WdfMemoryCopyFromBuffer failed 0x%08x\n", status);
-        WdfRequestComplete(Request, status);
-        return;
+    drv = WdfGetDriver();
+    drvCtx = GetDriverContext( drv );
+    Length = min(buffSize, sizeof(BALLOON_STAT) * VIRTIO_BALLOON_S_NR);
+#if 0
+    {
+        size_t i;
+        PBALLOON_STAT stat = (PBALLOON_STAT)buffer;
+        for (i = 0; i < Length / sizeof(BALLOON_STAT); ++i)
+        {
+           TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "tag = %
d, val = %08I64X\n\n", stat[i].tag, stat[i].val);
+        }
     }
-
-    sg.physAddr = GetPhysicalAddress(drvCtx->MemStats);
-    sg.ulSize = Length ;
-
-    vq = devCtx->StatVirtQueue; 
-    if(vq->vq_ops->add_buf(vq, &sg, 1, 0, devCtx)) {
-        TraceEvents(TRACE_LEVEL_ERROR, DBG_HW_ACCESS, "Cannot add
buffer\n");
-    }
-
-    vq->vq_ops->kick(vq);
-
-    status = WdfRequestForwardToIoQueue(Request, devCtx->StatusQueue);
-    if ( !NT_SUCCESS(status) ) {
-        TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS,
"WdfRequestForwardToIoQueue failed: 0x%08x\n", status);
-    }
-    return;
+#endif
+    RtlCopyMemory(drvCtx->MemStats, buffer, Length);
+    WdfRequestCompleteWithInformation(Request, status, Length);
+    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS,
"WdfRequestCompleteWithInformation Called! Queue 0x%p, Request 0x%p
Length %d Status 0x%08x\n",
+             Queue,Request,Length, status);
 }
diff --git a/Balloon/sys/sources b/Balloon/sys/sources
index f0564c9..4641c24 100644
--- a/Balloon/sys/sources
+++ b/Balloon/sys/sources
@@ -14,7 +14,7 @@ TARGETLIBS=$(TARGETLIBS) \
 
 MISCFILES=$(OBJ_PATH)\$(O)\$(INF_NAME).inf
 
-INCLUDES = $(INCLUDES);..\..\VirtIO;..\app
+INCLUDES = $(INCLUDES);..\..\VirtIO
 
 NTTARGETFILES=
 
diff --git a/Balloon/sys/trace.h b/Balloon/sys/trace.h
index dbc4e2c..0a0be4d 100644
--- a/Balloon/sys/trace.h
+++ b/Balloon/sys/trace.h
@@ -17,7 +17,6 @@
 
 #if !defined(TRACE_LEVEL_NONE)
   #define TRACE_LEVEL_NONE        0
-  #define TRACE_LEVEL_CRITICAL    1
   #define TRACE_LEVEL_FATAL       1
   #define TRACE_LEVEL_ERROR       2
   #define TRACE_LEVEL_WARNING     3

--
To unsubscribe from this list: send the line "unsubscribe kvm-commits" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to