[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH 04/26] Refactor Adapter.c



From: Owen Smith <owen.smith@xxxxxxxxxx>

Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
 src/xenvbd/adapter.c    | 2301 ++++++++++++++++++++++-------------------------
 src/xenvbd/adapter.h    |  123 +--
 src/xenvbd/blockring.c  |   22 +-
 src/xenvbd/driver.c     |  185 +---
 src/xenvbd/driver.h     |    5 +
 src/xenvbd/frontend.c   |  133 +--
 src/xenvbd/frontend.h   |    4 +
 src/xenvbd/granter.c    |   26 +-
 src/xenvbd/notifier.c   |   51 +-
 src/xenvbd/pdoinquiry.c |   44 +-
 src/xenvbd/pdoinquiry.h |    3 +-
 src/xenvbd/target.c     |  133 ++-
 src/xenvbd/target.h     |   27 +-
 13 files changed, 1292 insertions(+), 1765 deletions(-)

diff --git a/src/xenvbd/adapter.c b/src/xenvbd/adapter.c
index 1e0340b..7fb786f 100644
--- a/src/xenvbd/adapter.c
+++ b/src/xenvbd/adapter.c
@@ -44,6 +44,7 @@
 #include <debug_interface.h>
 #include <suspend_interface.h>
 #include <emulated_interface.h>
+#include <unplug_interface.h>
 
 #include "adapter.h"
 #include "driver.h"
@@ -58,553 +59,59 @@
 #include "assert.h"
 
 #define MAXNAMELEN  128
-
-#define ADAPTER_SIGNATURE   'odfX'
+#define ADAPTER_POOL_TAG        'adAX'
 
 struct _XENVBD_ADAPTER {
-    ULONG                       Signature;
     PDEVICE_OBJECT              DeviceObject;
     PDEVICE_OBJECT              LowerDeviceObject;
     PDEVICE_OBJECT              PhysicalDeviceObject;
     KSPIN_LOCK                  Lock;
     DEVICE_POWER_STATE          DevicePower;
-    ANSI_STRING                 Enumerator;
-
-    // Power
     PXENVBD_THREAD              DevicePowerThread;
     PIRP                        DevicePowerIrp;
 
-    // Interfaces to XenBus
-    XENBUS_EVTCHN_INTERFACE     Evtchn;
-    XENBUS_STORE_INTERFACE      Store;
-    XENBUS_GNTTAB_INTERFACE     Gnttab;
-    XENBUS_DEBUG_INTERFACE      Debug;
-    XENBUS_SUSPEND_INTERFACE    Suspend;
-    XENBUS_UNPLUG_INTERFACE     Unplug;
-    XENFILT_EMULATED_INTERFACE  Emulated;
+    XENBUS_EVTCHN_INTERFACE     EvtchnInterface;
+    XENBUS_STORE_INTERFACE      StoreInterface;
+    XENBUS_GNTTAB_INTERFACE     GnttabInterface;
+    XENBUS_DEBUG_INTERFACE      DebugInterface;
+    XENBUS_SUSPEND_INTERFACE    SuspendInterface;
+    XENBUS_UNPLUG_INTERFACE     UnplugInterface;
+    XENFILT_EMULATED_INTERFACE  EmulatedInterface;
     
-    // Debug Callback
     PXENBUS_DEBUG_CALLBACK      DebugCallback;
     PXENBUS_SUSPEND_CALLBACK    SuspendCallback;
 
-    // Targets
     KSPIN_LOCK                  TargetLock;
-    PXENVBD_TARGET                 Targets[XENVBD_MAX_TARGETS];
-
-    // Target Enumeration
+    PXENVBD_TARGET              TargetList[XENVBD_MAX_TARGETS];
     PXENVBD_THREAD              ScanThread;
     KEVENT                      ScanEvent;
     PXENBUS_STORE_WATCH         ScanWatch;
 
-    // Statistics
-    LONG                        CurrentSrbs;
-    LONG                        MaximumSrbs;
-    LONG                        TotalSrbs;
+    ULONG                       BuildIo;
+    ULONG                       StartIo;
+    ULONG                       Completed;
 };
 
-//=============================================================================
-static FORCEINLINE BOOLEAN
-__AdapterSetDevicePowerState(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in DEVICE_POWER_STATE          State
-    )
-{
-    KIRQL       Irql;
-    BOOLEAN     Changed = FALSE;
-
-    KeAcquireSpinLock(&Adapter->Lock, &Irql);
-
-    if (Adapter->DevicePower != State) {
-        Verbose("POWER %s to %s\n", 
PowerDeviceStateName(Adapter->DevicePower), PowerDeviceStateName(State));
-        Changed = TRUE;
-        Adapter->DevicePower = State;
-    }
-
-    KeReleaseSpinLock(&Adapter->Lock, Irql);
-
-    return Changed;
-}
-
-static FORCEINLINE DEVICE_POWER_STATE
-__AdapterGetDevicePowerState(
-    __in PXENVBD_ADAPTER                Adapter
-    )
-{
-    KIRQL               Irql;
-    DEVICE_POWER_STATE  State;
-
-    KeAcquireSpinLock(&Adapter->Lock, &Irql);
-    State = Adapter->DevicePower;
-    KeReleaseSpinLock(&Adapter->Lock, Irql);
-
-    return State;
-}
-
-__checkReturn
-static FORCEINLINE PXENVBD_TARGET
-__AdapterGetTargetAlways(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in ULONG                       TargetId,
-    __in PCHAR                       Caller
-    )
-{
-    PXENVBD_TARGET Target;
-    KIRQL       Irql;
-
-    ASSERT3U(TargetId, <, XENVBD_MAX_TARGETS);
-
-    KeAcquireSpinLock(&Adapter->TargetLock, &Irql);
-    Target = Adapter->Targets[TargetId];
-    if (Target) {
-        __TargetReference(Target, Caller);
-    }
-    KeReleaseSpinLock(&Adapter->TargetLock, Irql);
-    
-    return Target;
-}
-
-__checkReturn
-static FORCEINLINE PXENVBD_TARGET
-___AdapterGetTarget(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in ULONG                       TargetId,
-    __in PCHAR                       Caller
-    )
-{
-    PXENVBD_TARGET Target = NULL;
-    KIRQL       Irql;
-
-    ASSERT3U(TargetId, <, XENVBD_MAX_TARGETS);
-
-    KeAcquireSpinLock(&Adapter->TargetLock, &Irql);
-    if (Adapter->Targets[TargetId] && 
-        __TargetReference(Adapter->Targets[TargetId], Caller) > 0) {
-        Target = Adapter->Targets[TargetId];
-    }
-    KeReleaseSpinLock(&Adapter->TargetLock, Irql);
-    
-    return Target;
-}
-#define __AdapterGetTarget(f, t) ___AdapterGetTarget(f, t, __FUNCTION__)
-
-BOOLEAN
-AdapterLinkTarget(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PXENVBD_TARGET                 Target
-    )
-{
-    KIRQL       Irql;
-    PXENVBD_TARGET Current;
-    BOOLEAN     Result = FALSE;
-    ULONG       TargetId = TargetGetTargetId(Target);
-
-    KeAcquireSpinLock(&Adapter->TargetLock, &Irql);
-    Current = Adapter->Targets[TargetId];
-    if (Adapter->Targets[TargetId] == NULL) {
-        Adapter->Targets[TargetId] = Target;
-        Result = TRUE;
-    }
-    KeReleaseSpinLock(&Adapter->TargetLock, Irql);
-
-    if (!Result) {
-        Warning("Target[%d] : Current 0x%p, New 0x%p\n", TargetId, Current, 
Target);
-    }
-    return Result;
-}
-BOOLEAN
-AdapterUnlinkTarget(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PXENVBD_TARGET                 Target
-    )
-{
-    KIRQL       Irql;
-    PXENVBD_TARGET Current;
-    BOOLEAN     Result = FALSE;
-    ULONG       TargetId = TargetGetTargetId(Target);
-
-    KeAcquireSpinLock(&Adapter->TargetLock, &Irql);
-    Current = Adapter->Targets[TargetId];
-    if (Adapter->Targets[TargetId] == Target) {
-        Adapter->Targets[TargetId] = NULL;
-        Result = TRUE;
-    }
-    KeReleaseSpinLock(&Adapter->TargetLock, Irql);
-
-    if (!Result) {
-        Warning("Target[%d] : Current 0x%p, Expected 0x%p\n", TargetId, 
Current, Target);
-    }
-    return Result;
-}
-
-//=============================================================================
-// QueryInterface
-
-__drv_requiresIRQL(PASSIVE_LEVEL)
-static NTSTATUS
-AdapterQueryInterface(
-    IN  PXENVBD_ADAPTER     Adapter,
-    IN  const GUID      *Guid,
-    IN  ULONG           Version,
-    OUT PINTERFACE      Interface,
-    IN  ULONG           Size,
-    IN  BOOLEAN         Optional
-    )
-{
-    KEVENT              Event;
-    IO_STATUS_BLOCK     StatusBlock;
-    PIRP                Irp;
-    PIO_STACK_LOCATION  StackLocation;
-    NTSTATUS            status;
-
-    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
-
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-    RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
-
-    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
-                                       Adapter->LowerDeviceObject,
-                                       NULL,
-                                       0,
-                                       NULL,
-                                       &Event,
-                                       &StatusBlock);
-
-    status = STATUS_UNSUCCESSFUL;
-    if (Irp == NULL)
-        goto fail1;
-
-    StackLocation = IoGetNextIrpStackLocation(Irp);
-    StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
-
-    StackLocation->Parameters.QueryInterface.InterfaceType = Guid;
-    StackLocation->Parameters.QueryInterface.Size = (USHORT)Size;
-    StackLocation->Parameters.QueryInterface.Version = (USHORT)Version;
-    StackLocation->Parameters.QueryInterface.Interface = Interface;
-    
-    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
-
-    status = IoCallDriver(Adapter->LowerDeviceObject, Irp);
-    if (status == STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event,
-                                     Executive,
-                                     KernelMode,
-                                     FALSE,
-                                     NULL);
-        status = StatusBlock.Status;
-    }
-
-    if (!NT_SUCCESS(status)) {
-        if (status == STATUS_NOT_SUPPORTED && Optional)
-            goto done;
-
-        goto fail2;
-    }
-
-done:
-    return STATUS_SUCCESS;
-
-fail2:
-    Error("fail2\n");
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-#define QUERY_INTERFACE(                                                       
     \
-    _Adapter,                                                                  
             \
-    _ProviderName,                                                             
         \
-    _InterfaceName,                                                            
         \
-    _Interface,                                                                
         \
-    _Size,                                                                     
         \
-    _Optional)                                                                 
         \
-    AdapterQueryInterface((_Adapter),                                          
                 \
-                      &GUID_ ## _ProviderName ## _ ## _InterfaceName ## 
_INTERFACE,     \
-                      _ProviderName ## _ ## _InterfaceName ## 
_INTERFACE_VERSION_MAX,   \
-                      (_Interface),                                            
         \
-                      (_Size),                                                 
         \
-                      (_Optional))
-
-//=============================================================================
-// Debug
-
-static DECLSPEC_NOINLINE VOID
-AdapterDebugCallback(
-    __in PVOID                       Context,
-    __in BOOLEAN                     Crashing
-    )
-{
-    PXENVBD_ADAPTER     Adapter = Context;
-    ULONG           TargetId;
-
-    if (Adapter == NULL || Adapter->DebugCallback == NULL)
-        return;
-
-    XENBUS_DEBUG(Printf, &Adapter->Debug,
-                 "ADAPTER: Version: %d.%d.%d.%d (%d/%d/%d)\n",
-                 MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION, BUILD_NUMBER,
-                 DAY, MONTH, YEAR); 
-    XENBUS_DEBUG(Printf, &Adapter->Debug,
-                 "ADAPTER: Adapter: 0x%p %s\n",
-                 Context,
-                 Crashing ? "CRASHING" : "");
-    XENBUS_DEBUG(Printf, &Adapter->Debug,
-                 "ADAPTER: DevObj 0x%p LowerDevObj 0x%p PhysDevObj 0x%p\n",
-                 Adapter->DeviceObject,
-                 Adapter->LowerDeviceObject,
-                 Adapter->PhysicalDeviceObject);
-    XENBUS_DEBUG(Printf, &Adapter->Debug,
-                 "ADAPTER: DevicePowerState: %s\n",
-                 PowerDeviceStateName(Adapter->DevicePower));
-    XENBUS_DEBUG(Printf, &Adapter->Debug,
-                 "ADAPTER: Enumerator      : %s (0x%p)\n",
-                 AdapterEnum(Adapter), Adapter->Enumerator.Buffer);
-    XENBUS_DEBUG(Printf, &Adapter->Debug,
-                 "ADAPTER: Srbs            : %d / %d (%d Total)\n",
-                 Adapter->CurrentSrbs, Adapter->MaximumSrbs, 
Adapter->TotalSrbs);
-
-    BufferDebugCallback(&Adapter->Debug);
-    
-    for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
-        // no need to use __AdapterGetTarget (which is locked at DISPATCH) as 
called at HIGH_LEVEL
-        PXENVBD_TARGET Target = Adapter->Targets[TargetId];
-        if (Target == NULL)
-            continue;
-
-        XENBUS_DEBUG(Printf, &Adapter->Debug,
-                     "ADAPTER: ====> Target[%-3d]    : 0x%p\n",                
  
-                     TargetId, Target);
-
-        // call Target's debug callback directly
-        TargetDebugCallback(Target, &Adapter->Debug);
-
-        XENBUS_DEBUG(Printf, &Adapter->Debug,
-                     "ADAPTER: <==== Target[%-3d]    : 0x%p\n",                
  
-                     TargetId, Target);
-    }
-
-    Adapter->MaximumSrbs = Adapter->CurrentSrbs;
-    Adapter->TotalSrbs = 0;
-}
-
-//=============================================================================
-// Enumeration
-static FORCEINLINE ULONG
-__ParseVbd(
-    __in PCHAR                       DeviceIdStr
-    )
-{
-    ULONG   DeviceId = strtoul(DeviceIdStr, NULL, 10);
-    
-    ASSERT3U((DeviceId & ~((1 << 29) - 1)), ==, 0);
-
-    if (DeviceId & (1 << 28)) { 
-        return (DeviceId & ((1 << 20) - 1)) >> 8;           /* xvd    */
-    } else {
-        switch (DeviceId >> 8) {
-        case 202:   return (DeviceId & 0xF0) >> 4;          /* xvd    */
-        case 8:     return (DeviceId & 0xF0) >> 4;          /* sd     */
-        case 3:     return (DeviceId & 0xC0) >> 6;          /* hda..b */
-        case 22:    return ((DeviceId & 0xC0) >> 6) + 2;    /* hdc..d */
-        case 33:    return ((DeviceId & 0xC0) >> 6) + 4;    /* hde..f */
-        case 34:    return ((DeviceId & 0xC0) >> 6) + 6;    /* hdg..h */
-        case 56:    return ((DeviceId & 0xC0) >> 6) + 8;    /* hdi..j */
-        case 57:    return ((DeviceId & 0xC0) >> 6) + 10;   /* hdk..l */
-        case 88:    return ((DeviceId & 0xC0) >> 6) + 12;   /* hdm..n */
-        case 89:    return ((DeviceId & 0xC0) >> 6) + 14;   /* hdo..p */
-        default:    break;
-        }
-    }
-    Error("Invalid DeviceId %s (%08x)\n", DeviceIdStr, DeviceId);
-    return 0xFFFFFFFF; // OBVIOUS ERROR VALUE
-}
-static FORCEINLINE XENVBD_DEVICE_TYPE
-__DeviceType(
-    __in PCHAR                      Type
-    )
-{
-    if (strcmp(Type, "disk") == 0)
-        return XENVBD_DEVICE_TYPE_DISK;
-    if (strcmp(Type, "cdrom") == 0)
-        return XENVBD_DEVICE_TYPE_CDROM;
-    return XENVBD_DEVICE_TYPE_UNKNOWN;
-}
-
-static FORCEINLINE BOOLEAN
-__AdapterHiddenTarget(
-    IN  PXENVBD_ADAPTER     Adapter,
-    IN  PCHAR               DeviceId,
-    OUT PXENVBD_DEVICE_TYPE DeviceType
-    )
-{
-    NTSTATUS    status;
-    PCHAR       Buffer;
-    CHAR        Path[sizeof("device/vbd/XXXXXXXX")];
-    ULONG       Value;
-    
-    *DeviceType = XENVBD_DEVICE_TYPE_UNKNOWN;
-    status = RtlStringCbPrintfA(Path,
-                                sizeof(Path),
-                                "device/vbd/%s",
-                                DeviceId);
-    if (!NT_SUCCESS(status))
-        goto fail;
-
-    // Ejected?
-    status = XENBUS_STORE(Read, &Adapter->Store, NULL, Path, "ejected", 
&Buffer);
-    if (NT_SUCCESS(status)) {
-        Value = strtoul(Buffer, NULL, 10);
-        XENBUS_STORE(Free, &Adapter->Store, Buffer);
-
-        if (Value)
-            goto ignore;
-    }
-
-    // Not Disk?
-    status = XENBUS_STORE(Read, &Adapter->Store, NULL, Path, "device-type", 
&Buffer);
-    if (!NT_SUCCESS(status))
-        goto ignore;
-    *DeviceType = __DeviceType(Buffer);
-    XENBUS_STORE(Free, &Adapter->Store, Buffer);
-    
-    switch (*DeviceType) {
-    case XENVBD_DEVICE_TYPE_DISK:   
-        break;
-    default:                        
-        goto ignore;
-    }
-
-    // Try to Create
-    return FALSE;
-
-fail:
-    Error("Fail\n");
-    return TRUE;
-
-ignore:
-    return TRUE;
-}
-__checkReturn
-static FORCEINLINE BOOLEAN
-__AdapterIsTargetUnplugged(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PCHAR                       Enumerator,
-    __in PCHAR                       Device,
-    __in ULONG                       Target
+static FORCEINLINE PVOID
+__AdapterAllocate(
+    IN  ULONG   Size
     )
 {
-    // Only check targets that could be emulated
-    if (Target > 3) {
-        Verbose("Target[%d] : (%s/%s) Emulated NOT_APPLICABLE (non-IDE 
device)\n", 
-                            Target, Enumerator, Device);
-        return TRUE;
-    }
-     
-    // Check presense of Emulated interface. Absence indicates emulated cannot 
be unplugged
-    if (Adapter->Emulated.Interface.Context == NULL) {
-        Warning("Target[%d] : (%s/%s) Emulated NOT_KNOWN (assumed PRESENT)\n", 
-                            Target, Enumerator, Device);
-        return FALSE;
-    }
-
-    // Ask XenFilt if Ctrlr(0), Target(Target), Lun(0) is present
-    if (XENFILT_EMULATED(IsDiskPresent, &Adapter->Emulated, 0, Target, 0)) {
-        Verbose("Target[%d] : (%s/%s) Emulated PRESENT\n", 
-                            Target, Enumerator, Device);
-        return FALSE;
-    } else {
-        Verbose("Target[%d] : (%s/%s) Emulated NOT_PRESENT\n", 
-                            Target, Enumerator, Device);
-        return TRUE;
-    }
+    PVOID       Buffer;
+    Buffer = ExAllocatePoolWithTag(NonPagedPool,
+                                   Size,
+                                   ADAPTER_POOL_TAG);
+    if (Buffer)
+        RtlZeroMemory(Buffer, Size);
+    return Buffer;
 }
 
 static FORCEINLINE VOID
-__AdapterEnumerate(
-    __in    PXENVBD_ADAPTER     Adapter,
-    __in    PANSI_STRING    Devices,
-    __out   PBOOLEAN        NeedInvalidate,
-    __out   PBOOLEAN        NeedReboot
+__AdapterFree(
+    IN  PVOID   Buffer
     )
 {
-    ULONG               TargetId;
-    PANSI_STRING        Device;
-    ULONG               Index;
-    PXENVBD_TARGET         Target;
-
-    *NeedInvalidate = FALSE;
-    *NeedReboot = FALSE;
-
-    for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
-        BOOLEAN     Missing = TRUE;
-
-        Target = __AdapterGetTarget(Adapter, TargetId);
-        if (Target == NULL)
-            continue;
-
-        for (Index = 0; Devices[Index].Buffer != NULL; ++Index) {
-            ULONG DeviceTargetId;
-            Device = &Devices[Index];
-            DeviceTargetId = __ParseVbd(Device->Buffer);
-            if (TargetId == DeviceTargetId) {
-                Missing = FALSE;
-                break;
-            }
-        }
-
-        if (Missing && !TargetIsMissing(Target)) {
-            TargetSetMissing(Target, "Device Disappeared");
-            if (TargetGetDevicePnpState(Target) == Present)
-                TargetSetDevicePnpState(Target, Deleted);
-            else
-                *NeedInvalidate = TRUE;
-        }
-
-        if (TargetGetDevicePnpState(Target) == Deleted) {
-            TargetDereference(Target);
-            TargetDestroy(Target);
-        } else {
-            TargetDereference(Target);
-        }
-    }
-
-    // add new targets
-    for (Index = 0; Devices[Index].Buffer != NULL; ++Index) {
-        XENVBD_DEVICE_TYPE  DeviceType;
-
-        Device = &Devices[Index];
-
-        TargetId = __ParseVbd(Device->Buffer);
-        if (TargetId == 0xFFFFFFFF) {
-            continue;
-        }
-
-        Target = __AdapterGetTarget(Adapter, TargetId);
-        if (Target) {
-            TargetDereference(Target);
-            continue;
-        }
-
-        if (__AdapterHiddenTarget(Adapter, Device->Buffer, &DeviceType)) {
-            continue;
-        }
-
-        if (!__AdapterIsTargetUnplugged(Adapter,
-                                AdapterEnum(Adapter),
-                                Device->Buffer,
-                                TargetId)) {
-            *NeedReboot = TRUE;
-            continue;
-        }
-
-        if (TargetCreate(Adapter,
-                      Device->Buffer,
-                      TargetId,
-                      DeviceType)) {
-            *NeedInvalidate = TRUE;
-        }
-    }
+    ExFreePoolWithTag(Buffer, ADAPTER_POOL_TAG);
 }
 
 static FORCEINLINE PANSI_STRING
@@ -632,10 +139,7 @@ __AdapterMultiSzToAnsi(
         }
     }
 
-    Ansi = __AllocatePoolWithTag(NonPagedPool,
-                                 sizeof (ANSI_STRING) * (Count + 1),
-                                 ADAPTER_SIGNATURE);
-
+    Ansi = __AdapterAllocate(sizeof (ANSI_STRING) * (Count + 1));
     status = STATUS_NO_MEMORY;
     if (Ansi == NULL)
         goto fail1;
@@ -645,9 +149,7 @@ __AdapterMultiSzToAnsi(
 
         Length = (ULONG)strlen(Buffer);
         Ansi[Index].MaximumLength = (USHORT)(Length + 1);
-        Ansi[Index].Buffer = __AllocatePoolWithTag(NonPagedPool,
-                                                   Ansi[Index].MaximumLength,
-                                                   ADAPTER_SIGNATURE);
+        Ansi[Index].Buffer = __AdapterAllocate(Ansi[Index].MaximumLength);
 
         status = STATUS_NO_MEMORY;
         if (Ansi[Index].Buffer == NULL)
@@ -665,9 +167,9 @@ fail2:
     Error("fail2\n");
 
     while (--Index >= 0)
-            __FreePoolWithTag(Ansi[Index].Buffer, ADAPTER_SIGNATURE);
+            __AdapterFree(Ansi[Index].Buffer);
 
-    __FreePoolWithTag(Ansi, ADAPTER_SIGNATURE);
+    __AdapterFree(Ansi);
 
 fail1:
     Error("fail1 (%08x)\n", status);
@@ -701,105 +203,322 @@ __AdapterMultiSzToUpcaseAnsi(
         }
     }
 
-    Ansi = __AllocatePoolWithTag(NonPagedPool,
-                                 sizeof (ANSI_STRING) * (Count + 1),
-                                 ADAPTER_SIGNATURE);
-
+    Ansi = __AdapterAllocate(sizeof (ANSI_STRING) * (Count + 1));
     status = STATUS_NO_MEMORY;
     if (Ansi == NULL)
         goto fail1;
 
-    for (Index = 0; Index < Count; Index++) {
-        ULONG   Length;
+    for (Index = 0; Index < Count; Index++) {
+        ULONG   Length;
+
+        Length = (ULONG)strlen(Buffer);
+        Ansi[Index].MaximumLength = (USHORT)(Length + 1);
+        Ansi[Index].Buffer = __AdapterAllocate(Ansi[Index].MaximumLength);
+
+        status = STATUS_NO_MEMORY;
+        if (Ansi[Index].Buffer == NULL)
+            goto fail2;
+
+        RtlCopyMemory(Ansi[Index].Buffer, Buffer, Length);
+        Ansi[Index].Length = (USHORT)Length;
+
+        Buffer += Length + 1;
+    }
+
+    return Ansi;
+
+fail2:
+    Error("fail2\n");
+
+    while (--Index >= 0)
+            __AdapterFree(Ansi[Index].Buffer);
+
+    __AdapterFree(Ansi);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return NULL;
+}
+
+static FORCEINLINE VOID
+__AdapterFreeAnsi(
+    IN  PANSI_STRING    Ansi
+    )
+{
+    ULONG               Index;
+
+    for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
+            __AdapterFree(Ansi[Index].Buffer);
+
+    __AdapterFree(Ansi);
+}
+
+static FORCEINLINE BOOLEAN
+__AdapterSetDevicePowerState(
+    IN  PXENVBD_ADAPTER     Adapter,
+    IN  DEVICE_POWER_STATE  State
+    )
+{
+    KIRQL                   Irql;
+    BOOLEAN                 Changed = FALSE;
+
+    KeAcquireSpinLock(&Adapter->Lock, &Irql);
+
+    if (Adapter->DevicePower != State) {
+        Verbose("POWER %s to %s\n", 
PowerDeviceStateName(Adapter->DevicePower), PowerDeviceStateName(State));
+        Changed = TRUE;
+        Adapter->DevicePower = State;
+    }
+
+    KeReleaseSpinLock(&Adapter->Lock, Irql);
+
+    return Changed;
+}
+
+static FORCEINLINE DEVICE_POWER_STATE
+__AdapterGetDevicePowerState(
+    IN  PXENVBD_ADAPTER Adapter
+    )
+{
+    KIRQL               Irql;
+    DEVICE_POWER_STATE  State;
+
+    KeAcquireSpinLock(&Adapter->Lock, &Irql);
+    State = Adapter->DevicePower;
+    KeReleaseSpinLock(&Adapter->Lock, Irql);
+
+    return State;
+}
+
+static FORCEINLINE PXENVBD_TARGET
+AdapterGetTarget(
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  ULONG           TargetId
+    )
+{
+    PXENVBD_TARGET      Target;
+    KIRQL               Irql;
+
+    ASSERT3U(TargetId, <, XENVBD_MAX_TARGETS);
+
+    KeAcquireSpinLock(&Adapter->TargetLock, &Irql);
+    Target = Adapter->TargetList[TargetId];
+    KeReleaseSpinLock(&Adapter->TargetLock, Irql);
+    
+    return Target;
+}
+
+static FORCEINLINE BOOLEAN
+__AdapterHiddenTarget(
+    IN  PXENVBD_ADAPTER     Adapter,
+    IN  PCHAR               DeviceId
+    )
+{
+    NTSTATUS                status;
+    PCHAR                   Buffer;
+    CHAR                    Path[sizeof("device/vbd/XXXXXXXX")];
+    BOOLEAN                 Ejected;
+    BOOLEAN                 IsDisk;
+    
+    status = RtlStringCbPrintfA(Path,
+                                sizeof(Path),
+                                "device/vbd/%s",
+                                DeviceId);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    // Ejected?
+    status = XENBUS_STORE(Read,
+                          &Adapter->StoreInterface,
+                          NULL,
+                          Path,
+                          "ejected",
+                          &Buffer);
+    if (NT_SUCCESS(status)) {
+        Ejected = (BOOLEAN)strtoul(Buffer, NULL, 2);
+
+        XENBUS_STORE(Free,
+                     &Adapter->StoreInterface,
+                     Buffer);
+
+        if (Ejected)
+            goto ignore;
+    }
+
+    // Not Disk?
+    status = XENBUS_STORE(Read,
+                          &Adapter->StoreInterface,
+                          NULL,
+                          Path,
+                          "device-type",
+                          &Buffer);
+    if (!NT_SUCCESS(status))
+        goto ignore;
+
+    IsDisk = (strcmp(Buffer, "disk") == 0);
+   
+    XENBUS_STORE(Free,
+                 &Adapter->StoreInterface,
+                 Buffer);
+    
+    if (!IsDisk)
+        goto ignore;
 
-        Length = (ULONG)strlen(Buffer);
-        Ansi[Index].MaximumLength = (USHORT)(Length + 1);
-        Ansi[Index].Buffer = __AllocatePoolWithTag(NonPagedPool,
-                                                   Ansi[Index].MaximumLength,
-                                                   ADAPTER_SIGNATURE);
+    // Try to Create
+    return FALSE;
 
-        status = STATUS_NO_MEMORY;
-        if (Ansi[Index].Buffer == NULL)
-            goto fail2;
+fail1:
+    Error("fail1\n");
+    return TRUE;
 
-        RtlCopyMemory(Ansi[Index].Buffer, Buffer, Length);
-        Ansi[Index].Length = (USHORT)Length;
+ignore:
+    return TRUE;
+}
 
-        Buffer += Length + 1;
-    }
+BOOLEAN
+AdapterIsTargetEmulated(
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  ULONG           TargetId
+    )
+{
+    BOOLEAN             Emulated;
+    NTSTATUS            status;
 
-    return Ansi;
+    // Only check targets that could be emulated
+    if (TargetId > 3)
+        return FALSE;
 
-fail2:
-    Error("fail2\n");
+    // Check presense of Emulated interface. Absence indicates emulated cannot 
be unplugged
+    if (Adapter->EmulatedInterface.Interface.Context == NULL)
+        return TRUE;
 
-    while (--Index >= 0)
-            __FreePoolWithTag(Ansi[Index].Buffer, ADAPTER_SIGNATURE);
+    // Acquire failed, assume emulated
+    status = XENFILT_EMULATED(Acquire, &Adapter->EmulatedInterface);
+    if (!NT_SUCCESS(status))
+        return TRUE;
 
-    __FreePoolWithTag(Ansi, ADAPTER_SIGNATURE);
+    // Ask XenFilt if Ctrlr(0), Target(Target), Lun(0) is present
+    Emulated = XENFILT_EMULATED(IsDiskPresent,
+                                &Adapter->EmulatedInterface,
+                                0,
+                                TargetId,
+                                0);
 
-fail1:
-    Error("fail1 (%08x)\n", status);
+    XENFILT_EMULATED(Release, &Adapter->EmulatedInterface);
 
-    return NULL;
+    return Emulated;
 }
 
 static FORCEINLINE VOID
-__AdapterFreeAnsi(
-    IN  PANSI_STRING    Ansi
+__AdapterEnumerate(
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  PANSI_STRING    Devices
     )
 {
+    KIRQL               Irql;
+    ULONG               TargetId;
+    ULONG               DeviceId;
+    PANSI_STRING        Device;
     ULONG               Index;
+    PXENVBD_TARGET      Target;
+    BOOLEAN             NeedInvalidate;
+    BOOLEAN             NeedReboot;
 
-    for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
-            __FreePoolWithTag(Ansi[Index].Buffer, ADAPTER_SIGNATURE);
+    NeedInvalidate = FALSE;
+    NeedReboot = FALSE;
 
-    __FreePoolWithTag(Ansi, ADAPTER_SIGNATURE);
-}
+    for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
+        BOOLEAN     Missing = TRUE;
 
-static DECLSPEC_NOINLINE VOID
-AdapterScanTargets(
-    __in    PXENVBD_ADAPTER Adapter
-    )
-{
-    NTSTATUS        Status;
-    PCHAR           Buffer;
-    PANSI_STRING    Devices;
-    BOOLEAN         NeedInvalidate;
-    BOOLEAN         NeedReboot;
+        Target = AdapterGetTarget(Adapter, TargetId);
+        if (Target == NULL)
+            continue;
 
-    Status = XENBUS_STORE(Directory, &Adapter->Store, NULL, "device", 
AdapterEnum(Adapter), &Buffer);
-    if (!NT_SUCCESS(Status))
-        return;
+        for (Index = 0; Devices[Index].Buffer != NULL; ++Index) {
+            Device = &Devices[Index];
 
-    Devices = __AdapterMultiSzToAnsi(Buffer);
-    XENBUS_STORE(Free, &Adapter->Store, Buffer);
+            if (Device->Length == 0)
+                continue;
 
-    if (Devices == NULL)
-        return;
+            DeviceId = strtoul(Device->Buffer, NULL, 10);
+            if (TargetGetDeviceId(Target) == DeviceId) {
+                Device->Length = 0;
+                Missing = FALSE;
+                break;
+            }
+        }
+
+        if (Missing && !TargetIsMissing(Target)) {
+            TargetSetMissing(Target, "Device Disappeared");
+            if (TargetGetDevicePnpState(Target) == Present)
+                TargetSetDevicePnpState(Target, Deleted);
+            else
+                NeedInvalidate = TRUE;
+        }
 
-    __AdapterEnumerate(Adapter, Devices, &NeedInvalidate, &NeedReboot);
-    __AdapterFreeAnsi(Devices);
+        if (TargetGetDevicePnpState(Target) == Deleted) {
+            KeAcquireSpinLock(&Adapter->TargetLock, &Irql);
+            ASSERT3P(Adapter->TargetList[TargetId], ==, Target);
+            Adapter->TargetList[TargetId] = NULL;
+            KeReleaseSpinLock(&Adapter->TargetLock, Irql);
 
-    if (NeedInvalidate) {
-        StorPortNotification(BusChangeDetected, Adapter, 0);
+            TargetDestroy(Target);
+        }
     }
-    if (NeedReboot) {
-        DriverRequestReboot();
+
+    // add new targets
+    for (Index = 0; Devices[Index].Buffer != NULL; ++Index) {
+        NTSTATUS        status;
+
+        Device = &Devices[Index];
+
+        if (Device->Length == 0)
+            continue;
+
+        if (__AdapterHiddenTarget(Adapter, Device->Buffer))
+            continue;
+
+        status = TargetCreate(Adapter,
+                              Device->Buffer,
+                              &Target);
+        if (status == STATUS_RETRY)
+            NeedReboot = TRUE;
+        if (!NT_SUCCESS(status))
+            continue;
+
+        TargetId = TargetGetTargetId(Target);
+
+        KeAcquireSpinLock(&Adapter->TargetLock, &Irql);
+        ASSERT3P(Adapter->TargetList[TargetId], ==, NULL);
+        Adapter->TargetList[TargetId] = Target;
+        KeReleaseSpinLock(&Adapter->TargetLock, Irql);
+
+        NeedInvalidate = TRUE;
     }
+
+    if (NeedInvalidate)
+        StorPortNotification(BusChangeDetected,
+                             Adapter,
+                             NULL);
+    if (NeedReboot)
+        DriverRequestReboot();
 }
 
-__checkReturn
 static DECLSPEC_NOINLINE NTSTATUS
-AdapterScan(
-    __in PXENVBD_THREAD              Thread,
-    __in PVOID                       Context
+AdapterScanThread(
+    IN  PXENVBD_THREAD  Thread,
+    IN  PVOID           Context
     )
 {
     PXENVBD_ADAPTER     Adapter = Context;
-    PKEVENT         Event = ThreadGetEvent(Thread);
+    PKEVENT             Event = ThreadGetEvent(Thread);
 
     for (;;) {
+        NTSTATUS        status;
+        PCHAR           Buffer;
+        PANSI_STRING    Devices;
+
         Trace("waiting...\n");
 
         (VOID) KeWaitForSingleObject(Event,
@@ -811,204 +530,39 @@ AdapterScan(
 
         if (ThreadIsAlerted(Thread))
             break;
+        if (__AdapterGetDevicePowerState(Adapter) != PowerDeviceD0)
+            goto done;
+            
+        status = XENBUS_STORE(Directory,
+                              &Adapter->StoreInterface,
+                              NULL,
+                              "device",
+                              "vbd",
+                              &Buffer);
+        if (NT_SUCCESS(status)) {
+            Devices = __AdapterMultiSzToAnsi(Buffer);
 
-        if (__AdapterGetDevicePowerState(Adapter) == PowerDeviceD0)
-            AdapterScanTargets(Adapter);
-
-        KeSetEvent(&Adapter->ScanEvent, IO_NO_INCREMENT, FALSE);
-    }
-    KeSetEvent(&Adapter->ScanEvent, IO_NO_INCREMENT, FALSE);
-
-    return STATUS_SUCCESS;
-}
-
-//=============================================================================
-// Initialize, Start, Stop
-
-__drv_requiresIRQL(PASSIVE_LEVEL)
-static FORCEINLINE NTSTATUS
-__AdapterQueryInterfaces(
-    __in PXENVBD_ADAPTER             Adapter
-    )
-{
-    NTSTATUS        Status;
-
-    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
-
-    // Get STORE Interface
-    Status = QUERY_INTERFACE(Adapter,
-                             XENBUS,
-                             STORE,
-                             (PINTERFACE)&Adapter->Store,
-                             sizeof (Adapter->Store),
-                             FALSE);
-    if (!NT_SUCCESS(Status))
-        goto fail1;
-
-    // Get EVTCHN Interface
-    Status = QUERY_INTERFACE(Adapter,
-                             XENBUS,
-                             EVTCHN,
-                             (PINTERFACE)&Adapter->Evtchn,
-                             sizeof (Adapter->Evtchn),
-                             FALSE);
-    if (!NT_SUCCESS(Status))
-        goto fail2;
-
-    // Get GNTTAB Interface
-    Status = QUERY_INTERFACE(Adapter,
-                             XENBUS,
-                             GNTTAB,
-                             (PINTERFACE)&Adapter->Gnttab,
-                             sizeof (Adapter->Gnttab),
-                             FALSE);
-    if (!NT_SUCCESS(Status))
-        goto fail3;
-
-    // Get SUSPEND Interface
-    Status = QUERY_INTERFACE(Adapter,
-                             XENBUS,
-                             SUSPEND,
-                             (PINTERFACE)&Adapter->Suspend,
-                             sizeof (Adapter->Suspend),
-                             FALSE);
-    if (!NT_SUCCESS(Status))
-        goto fail4;
-
-    // Get DEBUG Interface
-    Status = QUERY_INTERFACE(Adapter,
-                             XENBUS,
-                             DEBUG,
-                             (PINTERFACE)&Adapter->Debug,
-                             sizeof (Adapter->Debug),
-                             FALSE);
-    if (!NT_SUCCESS(Status))
-        goto fail5;
-
-    // Get UNPLUG Interface
-    Status = QUERY_INTERFACE(Adapter,
-                             XENBUS,
-                             UNPLUG,
-                             (PINTERFACE)&Adapter->Unplug,
-                             sizeof (Adapter->Unplug),
-                             FALSE);
-    if (!NT_SUCCESS(Status))
-        goto fail6;
+            XENBUS_STORE(Free,
+                         &Adapter->StoreInterface,
+                         Buffer);
+        } else {
+            Devices = NULL;
+        }
 
-    // Get EMULATED Interface (optional)
-    Status = QUERY_INTERFACE(Adapter,
-                             XENFILT,
-                             EMULATED,
-                             (PINTERFACE)&Adapter->Emulated,
-                             sizeof (Adapter->Emulated),
-                             TRUE);
-    if (!NT_SUCCESS(Status))
-        goto fail7;
+        if (Devices == NULL)
+            goto done;
 
-    return STATUS_SUCCESS;
+        __AdapterEnumerate(Adapter,
+                           Devices);
 
-fail7:
-    RtlZeroMemory(&Adapter->Unplug,
-                  sizeof (XENBUS_UNPLUG_INTERFACE));
-fail6:
-    RtlZeroMemory(&Adapter->Debug,
-                  sizeof (XENBUS_DEBUG_INTERFACE));
-fail5:
-    RtlZeroMemory(&Adapter->Suspend,
-                  sizeof (XENBUS_SUSPEND_INTERFACE));
-fail4:
-    RtlZeroMemory(&Adapter->Gnttab,
-                  sizeof (XENBUS_GNTTAB_INTERFACE));
-fail3:
-    RtlZeroMemory(&Adapter->Evtchn,
-                  sizeof (XENBUS_EVTCHN_INTERFACE));
-fail2:
-    RtlZeroMemory(&Adapter->Store,
-                  sizeof (XENBUS_STORE_INTERFACE));
-fail1:
-    return Status;
-}
-static FORCEINLINE VOID
-__AdapterZeroInterfaces(
-    __in PXENVBD_ADAPTER             Adapter
-    )
-{
-    RtlZeroMemory(&Adapter->Emulated,
-                  sizeof (XENFILT_EMULATED_INTERFACE));
-    RtlZeroMemory(&Adapter->Unplug,
-                  sizeof (XENBUS_UNPLUG_INTERFACE));
-    RtlZeroMemory(&Adapter->Debug,
-                  sizeof (XENBUS_DEBUG_INTERFACE));
-    RtlZeroMemory(&Adapter->Suspend,
-                  sizeof (XENBUS_SUSPEND_INTERFACE));
-    RtlZeroMemory(&Adapter->Gnttab,
-                  sizeof (XENBUS_GNTTAB_INTERFACE));
-    RtlZeroMemory(&Adapter->Evtchn,
-                  sizeof (XENBUS_EVTCHN_INTERFACE));
-    RtlZeroMemory(&Adapter->Store,
-                  sizeof (XENBUS_STORE_INTERFACE));
-}
-static FORCEINLINE NTSTATUS
-__AdapterAcquire(
-    __in PXENVBD_ADAPTER    Adapter
-    )
-{
-    NTSTATUS            status;
+        __AdapterFreeAnsi(Devices);
 
-    if (Adapter->Emulated.Interface.Context) {
-        status = XENFILT_EMULATED(Acquire, &Adapter->Emulated);
-        if (!NT_SUCCESS(status))
-            goto fail1;
+done:
+        KeSetEvent(&Adapter->ScanEvent, IO_NO_INCREMENT, FALSE);
     }
-
-    status = XENBUS_SUSPEND(Acquire, &Adapter->Suspend);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status = XENBUS_DEBUG(Acquire, &Adapter->Debug);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    status = XENBUS_GNTTAB(Acquire, &Adapter->Gnttab);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    status = XENBUS_EVTCHN(Acquire, &Adapter->Evtchn);
-    if (!NT_SUCCESS(status))
-        goto fail5;
-
-    status = XENBUS_STORE(Acquire, &Adapter->Store);
-    if (!NT_SUCCESS(status))
-        goto fail6;
+    KeSetEvent(&Adapter->ScanEvent, IO_NO_INCREMENT, FALSE);
 
     return STATUS_SUCCESS;
-
-fail6:
-    XENBUS_EVTCHN(Release, &Adapter->Evtchn);
-fail5:
-    XENBUS_GNTTAB(Release, &Adapter->Gnttab);
-fail4:
-    XENBUS_DEBUG(Release, &Adapter->Debug);
-fail3:
-    XENBUS_SUSPEND(Release, &Adapter->Suspend);
-fail2:
-    if (Adapter->Emulated.Interface.Context)
-        XENFILT_EMULATED(Release, &Adapter->Emulated);
-fail1:
-    return status;
-}
-static FORCEINLINE VOID
-__AdapterRelease(
-    __in PXENVBD_ADAPTER             Adapter
-    )
-{
-    XENBUS_STORE(Release, &Adapter->Store);
-    XENBUS_EVTCHN(Release, &Adapter->Evtchn);
-    XENBUS_GNTTAB(Release, &Adapter->Gnttab);
-    XENBUS_DEBUG(Release, &Adapter->Debug);
-    XENBUS_SUSPEND(Release, &Adapter->Suspend);
-    if (Adapter->Emulated.Interface.Context)
-        XENFILT_EMULATED(Release, &Adapter->Emulated);
 }
 
 static FORCEINLINE BOOLEAN
@@ -1084,7 +638,7 @@ AdapterClearDistribution(
     Trace("====>\n");
 
     status = XENBUS_STORE(Directory,
-                          &Adapter->Store,
+                          &Adapter->StoreInterface,
                           NULL,
                           NULL,
                           "drivers",
@@ -1093,7 +647,7 @@ AdapterClearDistribution(
         Distributions = __AdapterMultiSzToUpcaseAnsi(Buffer);
 
         XENBUS_STORE(Free,
-                     &Adapter->Store,
+                     &Adapter->StoreInterface,
                      Buffer);
     } else {
         Distributions = NULL;
@@ -1106,7 +660,7 @@ AdapterClearDistribution(
         PANSI_STRING    Distribution = &Distributions[Index];
 
         status = XENBUS_STORE(Read,
-                              &Adapter->Store,
+                              &Adapter->StoreInterface,
                               NULL,
                               "drivers",
                               Distribution->Buffer,
@@ -1116,13 +670,13 @@ AdapterClearDistribution(
 
         if (__AdapterMatchDistribution(Adapter, Buffer))
             (VOID) XENBUS_STORE(Remove,
-                                &Adapter->Store,
+                                &Adapter->StoreInterface,
                                 NULL,
                                 "drivers",
                                 Distribution->Buffer);
 
         XENBUS_STORE(Free,
-                     &Adapter->Store,
+                     &Adapter->StoreInterface,
                      Buffer);
     }
 
@@ -1158,7 +712,7 @@ AdapterSetDistribution(
         ASSERT(NT_SUCCESS(status));
 
         status = XENBUS_STORE(Read,
-                              &Adapter->Store,
+                              &Adapter->StoreInterface,
                               NULL,
                               "drivers",
                               Distribution,
@@ -1171,7 +725,7 @@ AdapterSetDistribution(
         }
 
         XENBUS_STORE(Free,
-                     &Adapter->Store,
+                     &Adapter->StoreInterface,
                      Buffer);
 
         Index++;
@@ -1200,7 +754,7 @@ update:
 #endif
 
     (VOID) XENBUS_STORE(Printf,
-                        &Adapter->Store,
+                        &Adapter->StoreInterface,
                         NULL,
                         "drivers",
                         Distribution,
@@ -1229,27 +783,30 @@ fail1:
 
 static FORCEINLINE NTSTATUS
 __AdapterD3ToD0(
-    __in PXENVBD_ADAPTER    Adapter
+    IN  PXENVBD_ADAPTER Adapter
     )
 {
-    NTSTATUS            Status;
+    NTSTATUS            status;
 
     Trace("=====>\n");
 
+    status = XENBUS_STORE(Acquire, &Adapter->StoreInterface);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+    
     (VOID) AdapterSetDistribution(Adapter);
 
-    ASSERT3P(Adapter->ScanWatch, ==, NULL);
-    Status = XENBUS_STORE(WatchAdd,
-                          &Adapter->Store,
+    status = XENBUS_STORE(WatchAdd,
+                          &Adapter->StoreInterface,
                           "device",
-                          AdapterEnum(Adapter),
+                          "vbd",
                           ThreadGetEvent(Adapter->ScanThread),
                           &Adapter->ScanWatch);
-    if (!NT_SUCCESS(Status))
-        goto fail1;
+    if (!NT_SUCCESS(status))
+        goto fail2;
 
     (VOID) XENBUS_STORE(Printf,
-                        &Adapter->Store,
+                        &Adapter->StoreInterface,
                         NULL,
                         "feature/hotplug",
                         "vbd",
@@ -1259,193 +816,257 @@ __AdapterD3ToD0(
     Trace("<=====\n");
     return STATUS_SUCCESS;
 
+fail2:
+    Error("fail2\n");
+
+    XENBUS_STORE(Release, &Adapter->StoreInterface);
+
 fail1:
-    Error("fail1 (%08x)\n", Status);
+    Error("fail1 (%08x)\n", status);
 
-    return Status;
+    return status;
 }
 
 static FORCEINLINE VOID
 __AdapterD0ToD3(
-    __in PXENVBD_ADAPTER    Adapter
+    IN  PXENVBD_ADAPTER Adapter
     )
 {
     Trace("=====>\n");
 
     (VOID) XENBUS_STORE(Remove,
-                        &Adapter->Store,
+                        &Adapter->StoreInterface,
                         NULL,
                         "feature/hotplug",
                         "vbd");
 
     (VOID) XENBUS_STORE(WatchRemove,
-                        &Adapter->Store,
+                        &Adapter->StoreInterface,
                         Adapter->ScanWatch);
     Adapter->ScanWatch = NULL;
 
     AdapterClearDistribution(Adapter);
 
+    XENBUS_STORE(Release, &Adapter->StoreInterface);
+
     Trace("<=====\n");
 }
 
-__drv_requiresIRQL(DISPATCH_LEVEL)
 static VOID
 AdapterSuspendLateCallback(
-    __in PVOID                   Argument
+    IN  PVOID       Argument
     )
 {
-    PXENVBD_ADAPTER     Adapter = Argument;
-    NTSTATUS        Status;
+    PXENVBD_ADAPTER Adapter = Argument;
+    NTSTATUS        status;
 
-    Verbose("%s (%s)\n",
-         MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." 
BUILD_NUMBER_STR,
-         DAY_STR "/" MONTH_STR "/" YEAR_STR);
+    Verbose("%u.%u.%u.%u (%02u/%02u/%04u)\n",
+         MAJOR_VERSION,
+         MINOR_VERSION,
+         MICRO_VERSION,
+         BUILD_NUMBER,
+         DAY,
+         MONTH,
+         YEAR);
 
     __AdapterD0ToD3(Adapter);
 
-    Status = __AdapterD3ToD0(Adapter);
-    ASSERT(NT_SUCCESS(Status));
+    status = __AdapterD3ToD0(Adapter);
+    ASSERT(NT_SUCCESS(status));
+}
+
+static DECLSPEC_NOINLINE VOID
+AdapterDebugCallback(
+    IN  PVOID       Context,
+    IN  BOOLEAN     Crashing
+    )
+{
+    PXENVBD_ADAPTER Adapter = Context;
+    ULONG           TargetId;
+
+    XENBUS_DEBUG(Printf, 
+                 &Adapter->DebugInterface,
+                 "ADAPTER: Version: %u.%u.%u.%u (%02u/%02u/%04u)\n",
+                 MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION, BUILD_NUMBER,
+                 DAY, MONTH, YEAR); 
+    XENBUS_DEBUG(Printf, 
+                 &Adapter->DebugInterface,
+                 "ADAPTER: Adapter: 0x%p %s\n",
+                 Context,
+                 Crashing ? "CRASHING" : "");
+    XENBUS_DEBUG(Printf, 
+                 &Adapter->DebugInterface,
+                 "ADAPTER: DevObj 0x%p LowerDevObj 0x%p PhysDevObj 0x%p\n",
+                 Adapter->DeviceObject,
+                 Adapter->LowerDeviceObject,
+                 Adapter->PhysicalDeviceObject);
+    XENBUS_DEBUG(Printf, 
+                 &Adapter->DebugInterface,
+                 "ADAPTER: DevicePowerState: %s\n",
+                 PowerDeviceStateName(Adapter->DevicePower));
+    XENBUS_DEBUG(Printf, 
+                 &Adapter->DebugInterface,
+                 "ADAPTER: Srbs            : %u built, %u started, %u 
completed\n",
+                 Adapter->BuildIo,
+                 Adapter->StartIo,
+                 Adapter->Completed);
+
+    BufferDebugCallback(&Adapter->DebugInterface);
+    
+    for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
+        // no need to use AdapterGetTarget (which is locked at DISPATCH) as 
called at HIGH_LEVEL
+        PXENVBD_TARGET Target = Adapter->TargetList[TargetId];
+        if (Target == NULL)
+            continue;
+
+        XENBUS_DEBUG(Printf, &Adapter->DebugInterface,
+                     "ADAPTER: ====> Target[%-3d]    : 0x%p\n",                
  
+                     TargetId, Target);
+
+        // call Target's debug callback directly
+        TargetDebugCallback(Target, &Adapter->DebugInterface);
+
+        XENBUS_DEBUG(Printf, &Adapter->DebugInterface,
+                     "ADAPTER: <==== Target[%-3d]    : 0x%p\n",                
  
+                     TargetId, Target);
+    }
 }
 
 static NTSTATUS
 AdapterD3ToD0(
-    __in PXENVBD_ADAPTER             Adapter
+    IN  PXENVBD_ADAPTER Adapter
     )
 {
-    NTSTATUS    Status;
-    ULONG       TargetId;
+    NTSTATUS            status;
+    ULONG               TargetId;
 
     if (!__AdapterSetDevicePowerState(Adapter, PowerDeviceD0))
         return STATUS_SUCCESS;
 
-    Trace("=====> (%d)\n", KeGetCurrentIrql());
     Verbose("D3->D0\n");
 
-    // Get Interfaces
-    Status = __AdapterAcquire(Adapter);
-    if (!NT_SUCCESS(Status))
+    status = XENBUS_SUSPEND(Acquire, &Adapter->SuspendInterface);
+    if (!NT_SUCCESS(status))
         goto fail1;
-    
-    // register debug callback
-    ASSERT3P(Adapter->DebugCallback, ==, NULL);
-    Status = XENBUS_DEBUG(Register, 
-                          &Adapter->Debug, 
+
+    status = XENBUS_DEBUG(Acquire, &Adapter->DebugInterface);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    status = XENBUS_DEBUG(Register, 
+                          &Adapter->DebugInterface, 
                           __MODULE__, 
                           AdapterDebugCallback, 
                           Adapter, 
                           &Adapter->DebugCallback);
-    if (!NT_SUCCESS(Status))
-        goto fail2;
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    status = __AdapterD3ToD0(Adapter);
+    if (!NT_SUCCESS(status))
+        goto fail4;
 
-    // Power UP any TARGETs
     for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
-        PXENVBD_TARGET Target = __AdapterGetTarget(Adapter, TargetId);
-        if (Target) {
-            Status = TargetD3ToD0(Target);
-            TargetDereference(Target);
+        PXENVBD_TARGET Target = AdapterGetTarget(Adapter, TargetId);
+        if (Target == NULL)
+            continue;
 
-            if (!NT_SUCCESS(Status))
-                goto fail3;
-        }
-    }
+        status = TargetD3ToD0(Target);
 
-    Status = __AdapterD3ToD0(Adapter);
-    if (!NT_SUCCESS(Status))
-        goto fail4;
+        if (!NT_SUCCESS(status))
+            goto fail5;
+    }
 
-    // register suspend callback to re-register the watch
-    ASSERT3P(Adapter->SuspendCallback, ==, NULL);
-    Status = XENBUS_SUSPEND(Register,
-                            &Adapter->Suspend,
+    status = XENBUS_SUSPEND(Register,
+                            &Adapter->SuspendInterface,
                             SUSPEND_CALLBACK_LATE,
                             AdapterSuspendLateCallback,
                             Adapter,
                             &Adapter->SuspendCallback);
-    if (!NT_SUCCESS(Status))
-        goto fail5;
+    if (!NT_SUCCESS(status))
+        goto fail6;
 
-    Trace("<===== (%d)\n", KeGetCurrentIrql());
     return STATUS_SUCCESS;
 
+fail6:
+    Error("fail6\n");
 fail5:
-    Error("Fail5\n");
+    Error("fail5\n");
+
+    for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
+        PXENVBD_TARGET Target = AdapterGetTarget(Adapter, TargetId);
+        if (Target == NULL)
+            continue;
+        TargetD0ToD3(Target);
+    }
 
     __AdapterD0ToD3(Adapter);
 
 fail4:
-    Error("Fail4\n");
+    Error("fail4\n");
 
-fail3:
-    Error("Fail3\n");
+    XENBUS_DEBUG(Deregister,
+                 &Adapter->DebugInterface,
+                 Adapter->DebugCallback);
+    Adapter->DebugCallback = NULL;
 
-    for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
-        PXENVBD_TARGET Target = __AdapterGetTarget(Adapter, TargetId);
-        if (Target) {
-            TargetD0ToD3(Target);
-            TargetDereference(Target);
-        }
-    }
+fail3:
+    Error("fail3\n");
 
-    XENBUS_DEBUG(Deregister, &Adapter->Debug, Adapter->DebugCallback);
-    Adapter->DebugCallback = NULL;
+    XENBUS_DEBUG(Release, &Adapter->DebugInterface);
 
 fail2:
-    Error("Fail2\n");
+    Error("fail2\n");
+
+    XENBUS_SUSPEND(Release, &Adapter->SuspendInterface);
 
-    __AdapterRelease(Adapter);
-   
 fail1:
-    Error("Fail1 (%08x)\n", Status);
+    Error("fail1 (%08x)\n", status);
 
     __AdapterSetDevicePowerState(Adapter, PowerDeviceD3);
-    return Status;
+    return status;
 }
 
 static VOID
 AdapterD0ToD3(
-    __in PXENVBD_ADAPTER             Adapter
+    IN  PXENVBD_ADAPTER Adapter
     )
 {
-    ULONG       TargetId;
+    ULONG               TargetId;
 
     if (!__AdapterSetDevicePowerState(Adapter, PowerDeviceD3))
         return;
 
-    Trace("=====> (%d)\n", KeGetCurrentIrql());
     Verbose("D0->D3\n");
 
-    // remove suspend callback
-    XENBUS_SUSPEND(Deregister, &Adapter->Suspend, Adapter->SuspendCallback);
+    XENBUS_SUSPEND(Deregister,
+                   &Adapter->SuspendInterface,
+                   Adapter->SuspendCallback);
     Adapter->SuspendCallback = NULL;
 
-    __AdapterD0ToD3(Adapter);
-
-    // Power DOWN any TARGETs
     for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
-        PXENVBD_TARGET Target = __AdapterGetTarget(Adapter, TargetId);
-        if (Target) {
-            TargetD0ToD3(Target);
-            TargetDereference(Target);
-        }
+        PXENVBD_TARGET Target = AdapterGetTarget(Adapter, TargetId);
+        if (Target == NULL)
+            continue;
+        TargetD0ToD3(Target);
     }
 
-    // free debug callback
-    if (Adapter->DebugCallback != NULL) {
-        XENBUS_DEBUG(Deregister, &Adapter->Debug, Adapter->DebugCallback);
-        Adapter->DebugCallback = NULL;
-    }
+    __AdapterD0ToD3(Adapter);
 
-    // Release Interfaces
-    __AdapterRelease(Adapter);
+    XENBUS_DEBUG(Deregister,
+                 &Adapter->DebugInterface,
+                 Adapter->DebugCallback);
+    Adapter->DebugCallback = NULL;
 
-    Trace("<===== (%d)\n", KeGetCurrentIrql());
+    XENBUS_DEBUG(Release, &Adapter->DebugInterface);
+
+    XENBUS_SUSPEND(Release, &Adapter->SuspendInterface);
 }
 
-__checkReturn
 static DECLSPEC_NOINLINE NTSTATUS
-AdapterDevicePower(
-    __in PXENVBD_THREAD             Thread,
-    __in PVOID                      Context
+AdapterDevicePowerThread(
+    IN  PXENVBD_THREAD  Thread,
+    IN  PVOID           Context
     )
 {
     PXENVBD_ADAPTER     Adapter = Context;
@@ -1455,7 +1076,6 @@ AdapterDevicePower(
         PIO_STACK_LOCATION  Stack;
         DEVICE_POWER_STATE  DeviceState;
         POWER_ACTION        Action;
-        NTSTATUS            Status;
 
         if (!ThreadWait(Thread))
             break;
@@ -1474,12 +1094,10 @@ AdapterDevicePower(
         case IRP_MN_SET_POWER:
             switch (DeviceState) {
             case PowerDeviceD0:
-                Verbose("ADAPTER:PowerDeviceD0\n");
                 AdapterD3ToD0(Adapter);
                 break;
 
             case PowerDeviceD3:
-                Verbose("ADAPTER:PowerDeviceD3 (%s)\n", 
PowerActionName(Action));
                 AdapterD0ToD3(Adapter);
                 break;
 
@@ -1491,381 +1109,341 @@ AdapterDevicePower(
         default:
             break;
         }
-        Status = DriverDispatchPower(Adapter->DeviceObject, Irp);
-        if (!NT_SUCCESS(Status)) {
-            Warning("StorPort failed PowerIRP with %08x\n", Status);
-        }
+        (VOID) DriverDispatchPower(Adapter->DeviceObject, Irp);
     }
 
     return STATUS_SUCCESS;
 }
 
-__checkReturn
-__drv_requiresIRQL(PASSIVE_LEVEL)
 static NTSTATUS
-__AdapterInitialize(
-    __in PXENVBD_ADAPTER             Adapter
+__AdapterQueryInterface(
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  const GUID      *Guid,
+    IN  ULONG           Version,
+    OUT PINTERFACE      Interface,
+    IN  ULONG           Size,
+    IN  BOOLEAN         Optional
     )
 {
-    ULONG       StorStatus;
-    NTSTATUS    Status;
+    KEVENT              Event;
+    IO_STATUS_BLOCK     StatusBlock;
+    PIRP                Irp;
+    PIO_STACK_LOCATION  StackLocation;
+    NTSTATUS            status;
+
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+    RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
+
+    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
+                                       Adapter->LowerDeviceObject,
+                                       NULL,
+                                       0,
+                                       NULL,
+                                       &Event,
+                                       &StatusBlock);
+
+    status = STATUS_UNSUCCESSFUL;
+    if (Irp == NULL)
+        goto fail1;
+
+    StackLocation = IoGetNextIrpStackLocation(Irp);
+    StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
+
+    StackLocation->Parameters.QueryInterface.InterfaceType = Guid;
+    StackLocation->Parameters.QueryInterface.Size = (USHORT)Size;
+    StackLocation->Parameters.QueryInterface.Version = (USHORT)Version;
+    StackLocation->Parameters.QueryInterface.Interface = Interface;
+    
+    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+
+    status = IoCallDriver(Adapter->LowerDeviceObject, Irp);
+    if (status == STATUS_PENDING) {
+        (VOID) KeWaitForSingleObject(&Event,
+                                     Executive,
+                                     KernelMode,
+                                     FALSE,
+                                     NULL);
+        status = StatusBlock.Status;
+    }
+
+    if (!NT_SUCCESS(status)) {
+        if (status == STATUS_NOT_SUPPORTED && Optional)
+            goto done;
+
+        goto fail2;
+    }
+
+done:
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+fail1:
+    Error("fail1 (%08x)\n", status);
 
-    Trace("=====> (%d)\n", KeGetCurrentIrql());
+    return status;
+}
+
+#define AdapterQueryInterface(_adapter, _name, _itf, _opt)      \
+    __AdapterQueryInterface((_adapter),                         \
+                            &GUID_ ## _name ## _INTERFACE,      \
+                            _name ## _INTERFACE_VERSION_MAX,    \
+                            (PINTERFACE)(_itf),                 \
+                            sizeof( ## _name ## _INTERFACE),    \
+                            (_opt))
+static NTSTATUS
+AdapterInitialize(
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PDEVICE_OBJECT  PhysicalDeviceObject,
+    IN  PDEVICE_OBJECT  LowerDeviceObject
+    )
+{
+    NTSTATUS            status;
     
     ASSERT3U(KeGetCurrentIrql(), <=, DISPATCH_LEVEL);
-    // initialize the memory
-    Adapter->DevicePower = PowerDeviceD3;
+
+    Adapter->DeviceObject           = DeviceObject;
+    Adapter->PhysicalDeviceObject   = PhysicalDeviceObject;
+    Adapter->LowerDeviceObject      = LowerDeviceObject;
+    Adapter->DevicePower            = PowerDeviceD3;
+
     KeInitializeSpinLock(&Adapter->TargetLock);
     KeInitializeSpinLock(&Adapter->Lock);
     KeInitializeEvent(&Adapter->ScanEvent, SynchronizationEvent, FALSE);
 
-    Adapter->Signature = ADAPTER_SIGNATURE;
-
-    StorStatus = StorPortGetDeviceObjects(Adapter,
-                                          &Adapter->DeviceObject,
-                                          &Adapter->PhysicalDeviceObject,
-                                          &Adapter->LowerDeviceObject);
-    Status = STATUS_UNSUCCESSFUL;
-    if (StorStatus != STOR_STATUS_SUCCESS) {
-        Error("StorPortGetDeviceObjects() (%x:%s)\n", StorStatus, 
StorStatusName(StorStatus));
+    status = AdapterQueryInterface(Adapter,
+                                   XENBUS_STORE,
+                                   &Adapter->StoreInterface,
+                                   FALSE);
+    if (!NT_SUCCESS(status))
         goto fail1;
-    }
 
-    // get interfaces
-    Status = __AdapterQueryInterfaces(Adapter);
-    if (!NT_SUCCESS(Status))
+    status = AdapterQueryInterface(Adapter,
+                                   XENBUS_EVTCHN,
+                                   &Adapter->EvtchnInterface,
+                                   FALSE);
+    if (!NT_SUCCESS(status))
         goto fail2;
 
-    // start enum thread
-    Status = ThreadCreate(AdapterScan, Adapter, &Adapter->ScanThread);
-    if (!NT_SUCCESS(Status))
+    status = AdapterQueryInterface(Adapter,
+                                   XENBUS_GNTTAB,
+                                   &Adapter->GnttabInterface,
+                                   FALSE);
+    if (!NT_SUCCESS(status))
         goto fail3;
 
-    Status = ThreadCreate(AdapterDevicePower, Adapter, 
&Adapter->DevicePowerThread);
-    if (!NT_SUCCESS(Status))
+    status = AdapterQueryInterface(Adapter,
+                                   XENBUS_SUSPEND,
+                                   &Adapter->SuspendInterface,
+                                   FALSE);
+    if (!NT_SUCCESS(status))
         goto fail4;
 
-    Trace("<===== (%d)\n", KeGetCurrentIrql());
+    status = AdapterQueryInterface(Adapter,
+                                   XENBUS_DEBUG,
+                                   &Adapter->DebugInterface,
+                                   FALSE);
+    if (!NT_SUCCESS(status))
+        goto fail5;
+
+    status = AdapterQueryInterface(Adapter,
+                                   XENBUS_UNPLUG,
+                                   &Adapter->UnplugInterface,
+                                   FALSE);
+    if (!NT_SUCCESS(status))
+        goto fail6;
+
+    status = AdapterQueryInterface(Adapter,
+                                   XENFILT_EMULATED,
+                                   &Adapter->EmulatedInterface,
+                                   TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail7;
+
+    status = ThreadCreate(AdapterScanThread,
+                          Adapter,
+                          &Adapter->ScanThread);
+    if (!NT_SUCCESS(status))
+        goto fail8;
+
+    status = ThreadCreate(AdapterDevicePowerThread,
+                          Adapter,
+                          &Adapter->DevicePowerThread);
+    if (!NT_SUCCESS(status))
+        goto fail9;
+
     return STATUS_SUCCESS;
 
-fail4:
-    Error("fail4\n");
+fail9:
+    Error("fail9\n");
     ThreadAlert(Adapter->ScanThread);
     ThreadJoin(Adapter->ScanThread);
     Adapter->ScanThread = NULL;
+fail8:
+    Error("fail8\n");
+    RtlZeroMemory(&Adapter->EmulatedInterface,
+                  sizeof (XENFILT_EMULATED_INTERFACE));
+fail7:
+    Error("fail7\n");
+    RtlZeroMemory(&Adapter->UnplugInterface,
+                  sizeof (XENBUS_UNPLUG_INTERFACE));
+fail6:
+    Error("fail6\n");
+    RtlZeroMemory(&Adapter->DebugInterface,
+                  sizeof (XENBUS_DEBUG_INTERFACE));
+fail5:
+    Error("fail5\n");
+    RtlZeroMemory(&Adapter->SuspendInterface,
+                  sizeof (XENBUS_SUSPEND_INTERFACE));
+fail4:
+    Error("fail4\n");
+    RtlZeroMemory(&Adapter->GnttabInterface,
+                  sizeof (XENBUS_GNTTAB_INTERFACE));
 fail3:
     Error("fail3\n");
-    __AdapterZeroInterfaces(Adapter);
+    RtlZeroMemory(&Adapter->EvtchnInterface,
+                  sizeof (XENBUS_EVTCHN_INTERFACE));
 fail2:
     Error("fail2\n");
-    Adapter->DeviceObject = NULL;
-    Adapter->PhysicalDeviceObject = NULL;
-    Adapter->LowerDeviceObject = NULL;
+    RtlZeroMemory(&Adapter->StoreInterface,
+                  sizeof (XENBUS_STORE_INTERFACE));
 fail1:
-    Error("fail1 (%08x)\n", Status);
-    return Status;
+    Error("fail1 (%08x)\n", status);
+
+    RtlZeroMemory(&Adapter->TargetLock, sizeof(KSPIN_LOCK));
+    RtlZeroMemory(&Adapter->Lock, sizeof(KSPIN_LOCK));
+    RtlZeroMemory(&Adapter->ScanEvent, sizeof(KEVENT));
+
+    Adapter->DevicePower            = 0;
+    Adapter->DeviceObject           = NULL;
+    Adapter->PhysicalDeviceObject   = NULL;
+    Adapter->LowerDeviceObject      = NULL;
+
+    return status;
 }
-__drv_maxIRQL(PASSIVE_LEVEL)
+
 static VOID
-__AdapterTerminate(
-    __in PXENVBD_ADAPTER             Adapter
+AdapterTeardown(
+    IN  PXENVBD_ADAPTER Adapter
     )
 {
-    ULONG   TargetId;
-
-    Trace("=====> (%d)\n", KeGetCurrentIrql());
+    ULONG               TargetId;
 
     ASSERT3U(Adapter->DevicePower, ==, PowerDeviceD3);
 
-    // stop device power thread
     ThreadAlert(Adapter->DevicePowerThread);
     ThreadJoin(Adapter->DevicePowerThread);
     Adapter->DevicePowerThread = NULL;
 
-    // stop enum thread
     ThreadAlert(Adapter->ScanThread);
     ThreadJoin(Adapter->ScanThread);
     Adapter->ScanThread = NULL;
 
-    // clear device objects
-    Adapter->DeviceObject = NULL;
-    Adapter->PhysicalDeviceObject = NULL;
-    Adapter->LowerDeviceObject = NULL;
-    
-    // delete targets
-    for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
-        PXENVBD_TARGET Target = __AdapterGetTargetAlways(Adapter, TargetId, 
__FUNCTION__);
-        if (Target) {
-            // Target may not be in Deleted state yet, force it as Adapter is 
terminating
-            if (TargetGetDevicePnpState(Target) != Deleted)
-                TargetSetDevicePnpState(Target, Deleted);
-            // update missing (for debug output more than anything else
-            TargetSetMissing(Target, "AdapterTerminate");
-            // drop ref-count acquired in __AdapterGetTarget *before* 
destroying Target
-            TargetDereference(Target);
-            TargetDestroy(Target);
-        }
-    }
-
-    // cleanup memory
-    ASSERT3U(Adapter->DevicePower, ==, PowerDeviceD3);
-    ASSERT3P(Adapter->DebugCallback, ==, NULL);
-    ASSERT3P(Adapter->SuspendCallback, ==, NULL);
-
-    Adapter->Signature = 0;
-    Adapter->DevicePower = 0;
-    Adapter->CurrentSrbs = Adapter->MaximumSrbs = Adapter->TotalSrbs = 0;
-    RtlZeroMemory(&Adapter->Enumerator, sizeof(ANSI_STRING));
-    RtlZeroMemory(&Adapter->TargetLock, sizeof(KSPIN_LOCK));
-    RtlZeroMemory(&Adapter->Lock, sizeof(KSPIN_LOCK));
-    RtlZeroMemory(&Adapter->ScanEvent, sizeof(KEVENT));
-    __AdapterZeroInterfaces(Adapter);
-
-    ASSERT(IsZeroMemory(Adapter, sizeof(XENVBD_ADAPTER)));
-    Trace("<===== (%d)\n", KeGetCurrentIrql());
-}
-//=============================================================================
-// Query Methods
-__checkReturn
-FORCEINLINE PDEVICE_OBJECT
-AdapterGetDeviceObject(
-    __in PXENVBD_ADAPTER                 Adapter
-    )
-{
-    if (Adapter)
-        return Adapter->DeviceObject;
-    return NULL;
-}
-
-FORCEINLINE ULONG
-AdapterSizeofXenvbdAdapter(
-    )
-{
-    return (ULONG)sizeof(XENVBD_ADAPTER);
-}
-
-FORCEINLINE PCHAR
-AdapterEnum(
-    __in PXENVBD_ADAPTER                 Adapter
-    )
-{
-    if (Adapter->Enumerator.Buffer)
-        return Adapter->Enumerator.Buffer;
-    else
-        return "vbd";
-}
-
-//=============================================================================
-// SRB Methods
-FORCEINLINE VOID
-AdapterStartSrb(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PSCSI_REQUEST_BLOCK         Srb
-    )
-{
-    LONG    Value;
-
-    UNREFERENCED_PARAMETER(Srb);
-
-    Value = InterlockedIncrement(&Adapter->CurrentSrbs);
-    if (Value > Adapter->MaximumSrbs)
-        Adapter->MaximumSrbs = Value;
-    InterlockedIncrement(&Adapter->TotalSrbs);
-}
-
-FORCEINLINE VOID
-AdapterCompleteSrb(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PSCSI_REQUEST_BLOCK         Srb
-    )
-{
-    ASSERT3U(Srb->SrbStatus, !=, SRB_STATUS_PENDING);
-
-    InterlockedDecrement(&Adapter->CurrentSrbs);
-
-    StorPortNotification(RequestComplete, Adapter, Srb);
-}
-
-//=============================================================================
-// StorPort Methods
-BOOLEAN
-AdapterResetBus(
-    __in PXENVBD_ADAPTER                 Adapter
-    )
-{
-    ULONG           TargetId;
-
-    Verbose("====>\n");
     for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
-        PXENVBD_TARGET Target = __AdapterGetTarget(Adapter, TargetId);
-        if (Target) {
-            TargetReset(Target);
-            TargetDereference(Target);
-        }
-    }
-    Verbose("<====\n");
-
-    return TRUE;
-}
-
-static VOID
-AdapterUnplugRequest(
-    IN  PXENVBD_ADAPTER Adapter,
-    IN  BOOLEAN     Make
-    )
-{
-    NTSTATUS        status;
-
-    status = XENBUS_UNPLUG(Acquire, &Adapter->Unplug);
-    if (!NT_SUCCESS(status))
-        return;
+        PXENVBD_TARGET Target = AdapterGetTarget(Adapter, TargetId);
+        if (Target == NULL)
+            continue;
 
-    XENBUS_UNPLUG(Request,
-                  &Adapter->Unplug,
-                  XENBUS_UNPLUG_DEVICE_TYPE_DISKS,
-                  Make);
+        // Target may not be in Deleted state yet, force it as Adapter is 
terminating
+        if (TargetGetDevicePnpState(Target) != Deleted)
+            TargetSetDevicePnpState(Target, Deleted);
+        // update missing (for debug output more than anything else
+        TargetSetMissing(Target, "AdapterTeardown");
+        // drop ref-count acquired in __AdapterGetTarget *before* destroying 
Target
+        TargetDestroy(Target);
+    }
 
-    XENBUS_UNPLUG(Release, &Adapter->Unplug);
-}
+    RtlZeroMemory(&Adapter->EmulatedInterface,
+                  sizeof (XENFILT_EMULATED_INTERFACE));
 
-ULONG
-AdapterFindAdapter(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __inout PPORT_CONFIGURATION_INFORMATION  ConfigInfo
-    )
-{
-    // setup config info
-    ConfigInfo->MaximumTransferLength       = XENVBD_MAX_TRANSFER_LENGTH;
-    ConfigInfo->NumberOfPhysicalBreaks      = XENVBD_MAX_PHYSICAL_BREAKS;
-    ConfigInfo->AlignmentMask               = 0; // Byte-Aligned
-    ConfigInfo->NumberOfBuses               = 1;
-    ConfigInfo->InitiatorBusId[0]           = 1;
-    ConfigInfo->ScatterGather               = TRUE;
-    ConfigInfo->Master                      = TRUE;
-    ConfigInfo->CachesData                  = FALSE;
-    ConfigInfo->MapBuffers                  = STOR_MAP_NON_READ_WRITE_BUFFERS;
-    ConfigInfo->MaximumNumberOfTargets      = XENVBD_MAX_TARGETS;
-    ConfigInfo->MaximumNumberOfLogicalUnits = 1;
-    ConfigInfo->WmiDataProvider             = FALSE; // should be TRUE
-    ConfigInfo->SynchronizationModel        = StorSynchronizeFullDuplex;
+    RtlZeroMemory(&Adapter->UnplugInterface,
+                  sizeof (XENBUS_UNPLUG_INTERFACE));
 
-    if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) {
-        Trace("64bit DMA\n");
-        ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
-    }
+    RtlZeroMemory(&Adapter->DebugInterface,
+                  sizeof (XENBUS_DEBUG_INTERFACE));
 
-    // gets called on resume from hibernate, so only setup if not already done
-    if (Adapter->Signature == ADAPTER_SIGNATURE) {
-        Verbose("ADAPTER already initalized (0x%p)\n", Adapter);
-        return SP_RETURN_FOUND;
-    }
+    RtlZeroMemory(&Adapter->SuspendInterface,
+                  sizeof (XENBUS_SUSPEND_INTERFACE));
 
-    // We need to do this to avoid an assertion in a checked kernel
-    (VOID) StorPortGetUncachedExtension(Adapter, ConfigInfo, PAGE_SIZE);
+    RtlZeroMemory(&Adapter->GnttabInterface,
+                  sizeof (XENBUS_GNTTAB_INTERFACE));
 
-    if (!NT_SUCCESS(__AdapterInitialize(Adapter)))
-        return SP_RETURN_ERROR;
+    RtlZeroMemory(&Adapter->EvtchnInterface,
+                  sizeof (XENBUS_EVTCHN_INTERFACE));
 
-    AdapterUnplugRequest(Adapter, TRUE);
+    RtlZeroMemory(&Adapter->StoreInterface,
+                  sizeof (XENBUS_STORE_INTERFACE));
 
-    if (!NT_SUCCESS(AdapterD3ToD0(Adapter)))
-        return SP_RETURN_ERROR;
+    RtlZeroMemory(&Adapter->TargetLock, sizeof(KSPIN_LOCK));
+    RtlZeroMemory(&Adapter->Lock, sizeof(KSPIN_LOCK));
+    RtlZeroMemory(&Adapter->ScanEvent, sizeof(KEVENT));
 
-    return SP_RETURN_FOUND;
-}
+    Adapter->DevicePower            = 0;
+    Adapter->DeviceObject           = NULL;
+    Adapter->PhysicalDeviceObject   = NULL;
+    Adapter->LowerDeviceObject      = NULL;
 
-static FORCEINLINE VOID
-__AdapterSrbPnp(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PSCSI_PNP_REQUEST_BLOCK     Srb
-    )
-{
-    if (!(Srb->SrbPnPFlags & SRB_PNP_FLAGS_ADAPTER_REQUEST)) {
-        PXENVBD_TARGET     Target;
+    Adapter->BuildIo                = 0;
+    Adapter->StartIo                = 0;
+    Adapter->Completed              = 0;
 
-        Target = __AdapterGetTarget(Adapter, Srb->TargetId);
-        if (Target) {
-            TargetSrbPnp(Target, Srb);
-            TargetDereference(Target);
-        }
-    }
+    ASSERT(IsZeroMemory(Adapter, sizeof(XENVBD_ADAPTER)));
+    Trace("<===== (%d)\n", KeGetCurrentIrql());
 }
 
-BOOLEAN 
-AdapterBuildIo(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PSCSI_REQUEST_BLOCK         Srb
+VOID
+AdapterCompleteSrb(
+    IN  PXENVBD_ADAPTER     Adapter,
+    IN  PSCSI_REQUEST_BLOCK Srb
     )
 {
-    InitSrbExt(Srb);
+    ASSERT3U(Srb->SrbStatus, !=, SRB_STATUS_PENDING);
 
-    switch (Srb->Function) {
-    case SRB_FUNCTION_EXECUTE_SCSI:
-    case SRB_FUNCTION_RESET_DEVICE:
-    case SRB_FUNCTION_FLUSH:
-    case SRB_FUNCTION_SHUTDOWN:
-        AdapterStartSrb(Adapter, Srb);
-        return TRUE;
+    ++Adapter->Completed;
 
-        // dont pass to StartIo
-    case SRB_FUNCTION_PNP:
-        __AdapterSrbPnp(Adapter, (PSCSI_PNP_REQUEST_BLOCK)Srb);
-        Srb->SrbStatus = SRB_STATUS_SUCCESS;
-        break;
-    case SRB_FUNCTION_ABORT_COMMAND:
-        Srb->SrbStatus = SRB_STATUS_ABORT_FAILED;
-        break;
-    case SRB_FUNCTION_RESET_BUS:
-        Srb->SrbStatus = SRB_STATUS_SUCCESS;
-        AdapterResetBus(Adapter);
-        break;
-        
-    default:
-        break;
-    }
-    
     StorPortNotification(RequestComplete, Adapter, Srb);
-    return FALSE;
-}   
+}
 
-BOOLEAN 
-AdapterStartIo(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PSCSI_REQUEST_BLOCK         Srb
+static VOID
+AdapterUnplugRequest(
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  BOOLEAN         Make
     )
 {
-    PXENVBD_TARGET Target;
-    BOOLEAN     CompleteSrb = TRUE;
+    NTSTATUS            status;
 
-    Target = __AdapterGetTarget(Adapter, Srb->TargetId);
-    if (Target) {
-        CompleteSrb = TargetStartIo(Target, Srb);
-        TargetDereference(Target);
-    }
+    status = XENBUS_UNPLUG(Acquire, &Adapter->UnplugInterface);
+    if (!NT_SUCCESS(status))
+        return;
 
-    if (CompleteSrb) {
-        AdapterCompleteSrb(Adapter, Srb);
-    }
-    return TRUE;
+    XENBUS_UNPLUG(Request,
+                  &Adapter->UnplugInterface,
+                  XENBUS_UNPLUG_DEVICE_TYPE_DISKS,
+                  Make);
+
+    XENBUS_UNPLUG(Release, &Adapter->UnplugInterface);
 }
 
 static PXENVBD_TARGET
 AdapterGetTargetFromDeviceObject(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PDEVICE_OBJECT              DeviceObject
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  PDEVICE_OBJECT  DeviceObject
     )
 {
-    ULONG           TargetId;
+    ULONG               TargetId;
 
     ASSERT3P(DeviceObject, !=, NULL);
 
     for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
-        PXENVBD_TARGET Target = __AdapterGetTarget(Adapter, TargetId);
-        if (Target) {
-            if (TargetGetDeviceObject(Target) == DeviceObject)
-                return Target;
-            TargetDereference(Target);
-        }
+        PXENVBD_TARGET Target = AdapterGetTarget(Adapter, TargetId);
+        if (Target == NULL)
+            continue;
+        if (TargetGetDeviceObject(Target) == DeviceObject)
+            return Target;
     }
 
     return NULL;
@@ -1873,18 +1451,18 @@ AdapterGetTargetFromDeviceObject(
 
 static PXENVBD_TARGET
 AdapterMapDeviceObjectToTarget(
-    __in PXENVBD_ADAPTER                Adapter,
-    __in PDEVICE_OBJECT             DeviceObject
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  PDEVICE_OBJECT  DeviceObject
     )
 {
-    PXENVBD_TARGET                 Target;
-    KEVENT                      Complete;
-    PIRP                        Irp;
-    IO_STATUS_BLOCK             StatusBlock;
-    PIO_STACK_LOCATION          Stack;
-    NTSTATUS                    Status;
-    PWCHAR                      String;
-    ULONG                       TargetId;
+    PXENVBD_TARGET      Target;
+    KEVENT              Complete;
+    PIRP                Irp;
+    IO_STATUS_BLOCK     StatusBlock;
+    PIO_STACK_LOCATION  Stack;
+    NTSTATUS            Status;
+    PWCHAR              String;
+    ULONG               TargetId;
     DECLARE_UNICODE_STRING_SIZE(UniStr, 4);
 
     KeInitializeEvent(&Complete, NotificationEvent, FALSE);
@@ -1928,7 +1506,7 @@ AdapterMapDeviceObjectToTarget(
     if (!NT_SUCCESS(Status))
         goto fail4;
 
-    Target = __AdapterGetTarget(Adapter, TargetId);
+    Target = AdapterGetTarget(Adapter, TargetId);
     if (Target == NULL)
         goto fail5;
 
@@ -1946,16 +1524,15 @@ fail1:
     return NULL;
 }
 
-__checkReturn
-NTSTATUS
+static NTSTATUS
 AdapterForwardPnp(
-    __in PXENVBD_ADAPTER                Adapter,
-    __in PDEVICE_OBJECT             DeviceObject,
-    __in PIRP                       Irp
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp
     )
 {
     PIO_STACK_LOCATION  Stack;
-    PXENVBD_TARGET         Target;
+    PXENVBD_TARGET      Target;
 
     ASSERT3P(DeviceObject, !=, Adapter->DeviceObject);
 
@@ -1976,26 +1553,25 @@ AdapterForwardPnp(
     return DriverDispatchPnp(DeviceObject, Irp);
 }
 
-__checkReturn
 NTSTATUS
 AdapterDispatchPnp(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PDEVICE_OBJECT              DeviceObject,
-    __in PIRP                        Irp
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp
     )
 {
     PIO_STACK_LOCATION  Stack;
 
-    ASSERT3P(DeviceObject, ==, Adapter->DeviceObject);
+    if (Adapter->DeviceObject != DeviceObject)
+        return AdapterForwardPnp(Adapter, DeviceObject, Irp);
 
     Stack = IoGetCurrentIrpStackLocation(Irp);
 
     switch (Stack->MinorFunction) {
     case IRP_MN_REMOVE_DEVICE:
-        Verbose("ADAPTER:IRP_MN_REMOVE_DEVICE\n");
         AdapterD0ToD3(Adapter);
         AdapterUnplugRequest(Adapter, FALSE);
-        __AdapterTerminate(Adapter);
+        AdapterTeardown(Adapter);
         break;
 
     case IRP_MN_QUERY_DEVICE_RELATIONS:
@@ -2004,12 +1580,12 @@ AdapterDispatchPnp(
             ThreadWake(Adapter->ScanThread);
 
             Trace("waiting for scan thread\n");
-
             (VOID) KeWaitForSingleObject(&Adapter->ScanEvent,
                                          Executive,
                                          KernelMode,
                                          FALSE,
                                          NULL);
+            Trace("scan thread wait complete\n");
         }
         break;
 
@@ -2020,19 +1596,19 @@ AdapterDispatchPnp(
     return DriverDispatchPnp(DeviceObject, Irp);
 }
 
-__checkReturn
 NTSTATUS
 AdapterDispatchPower(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PDEVICE_OBJECT              DeviceObject,
-    __in PIRP                        Irp
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp
     )
 {
     PIO_STACK_LOCATION  Stack;
     POWER_STATE_TYPE    PowerType;
     NTSTATUS            status;
 
-    ASSERT3P(DeviceObject, ==, Adapter->DeviceObject);
+    if (Adapter->DeviceObject != DeviceObject)
+        return DriverDispatchPower(DeviceObject, Irp);
 
     Stack = IoGetCurrentIrpStackLocation(Irp);
     PowerType = Stack->Parameters.Power.Type;
@@ -2065,72 +1641,299 @@ AdapterDispatchPower(
     return status;
 }
 
-PXENBUS_STORE_INTERFACE
-AdapterAcquireStore(
-    __in PXENVBD_ADAPTER    Adapter
+HW_RESET_BUS        AdapterHwResetBus;
+
+BOOLEAN
+AdapterHwResetBus(
+    IN  PVOID       DevExt,
+    IN  ULONG       PathId
     )
 {
-    NTSTATUS            status;
+    PXENVBD_ADAPTER Adapter = DevExt;
+    ULONG           TargetId;
 
-    status = XENBUS_STORE(Acquire, &Adapter->Store);
-    if (!NT_SUCCESS(status))
-        return NULL;
+    UNREFERENCED_PARAMETER(PathId);
+
+    Verbose("====>\n");
+    for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
+        PXENVBD_TARGET Target = AdapterGetTarget(Adapter, TargetId);
+        if (Target == NULL)
+            continue;
+
+        TargetReset(Target);
+    }
+    Verbose("<====\n");
 
-    return &Adapter->Store;
+    return TRUE;
 }
 
-PXENBUS_EVTCHN_INTERFACE
-AdapterAcquireEvtchn(
-    __in PXENVBD_ADAPTER    Adapter
+
+static FORCEINLINE VOID
+__AdapterSrbPnp(
+    IN  PXENVBD_ADAPTER         Adapter,
+    IN  PSCSI_PNP_REQUEST_BLOCK Srb
     )
 {
-    NTSTATUS            status;
+    if (!(Srb->SrbPnPFlags & SRB_PNP_FLAGS_ADAPTER_REQUEST)) {
+        PXENVBD_TARGET          Target;
 
-    status = XENBUS_EVTCHN(Acquire, &Adapter->Evtchn);
-    if (!NT_SUCCESS(status))
-        return NULL;
+        Target = AdapterGetTarget(Adapter, Srb->TargetId);
+        if (Target) {
+            TargetSrbPnp(Target, Srb);
+        }
+    }
+}
+
+HW_BUILDIO          AdapterHwBuildIo;
+
+BOOLEAN 
+AdapterHwBuildIo(
+    IN  PVOID               DevExt,
+    IN  PSCSI_REQUEST_BLOCK Srb
+    )
+{
+    PXENVBD_ADAPTER         Adapter = DevExt;
+
+    InitSrbExt(Srb);
+
+    switch (Srb->Function) {
+    case SRB_FUNCTION_EXECUTE_SCSI:
+    case SRB_FUNCTION_RESET_DEVICE:
+    case SRB_FUNCTION_FLUSH:
+    case SRB_FUNCTION_SHUTDOWN:
+        ++Adapter->BuildIo;
+        return TRUE;
 
-    return &Adapter->Evtchn;
+        // dont pass to StartIo
+    case SRB_FUNCTION_PNP:
+        __AdapterSrbPnp(Adapter, (PSCSI_PNP_REQUEST_BLOCK)Srb);
+        Srb->SrbStatus = SRB_STATUS_SUCCESS;
+        break;
+    case SRB_FUNCTION_ABORT_COMMAND:
+        Srb->SrbStatus = SRB_STATUS_ABORT_FAILED;
+        break;
+    case SRB_FUNCTION_RESET_BUS:
+        Srb->SrbStatus = SRB_STATUS_SUCCESS;
+        AdapterHwResetBus(Adapter, Srb->PathId);
+        break;
+        
+    default:
+        break;
+    }
+    
+    StorPortNotification(RequestComplete, Adapter, Srb);
+    return FALSE;
 }
 
-PXENBUS_GNTTAB_INTERFACE
-AdapterAcquireGnttab(
-    __in PXENVBD_ADAPTER    Adapter
+HW_STARTIO          AdapterHwStartIo;
+
+BOOLEAN 
+AdapterHwStartIo(
+    IN  PVOID               DevExt,
+    IN  PSCSI_REQUEST_BLOCK Srb
     )
 {
-    NTSTATUS            status;
+    PXENVBD_ADAPTER         Adapter = DevExt;
+    PXENVBD_TARGET          Target;
 
-    status = XENBUS_GNTTAB(Acquire, &Adapter->Gnttab);
-    if (!NT_SUCCESS(status))
-        return NULL;
+    Target = AdapterGetTarget(Adapter, Srb->TargetId);
+    if (Target == NULL)
+        goto fail1;
+
+    ++Adapter->StartIo;
+    if (TargetStartIo(Target, Srb))
+        AdapterCompleteSrb(Adapter, Srb);
 
-    return &Adapter->Gnttab;
+    return TRUE;
+
+fail1:
+    AdapterCompleteSrb(Adapter, Srb);
+    return TRUE;
 }
 
-PXENBUS_DEBUG_INTERFACE
-AdapterAcquireDebug(
-    __in PXENVBD_ADAPTER    Adapter
+HW_ADAPTER_CONTROL  AdapterHwAdapterControl;
+
+SCSI_ADAPTER_CONTROL_STATUS
+AdapterHwAdapterControl(
+    IN  PVOID                       DevExt,
+    IN  SCSI_ADAPTER_CONTROL_TYPE   ControlType,
+    IN  PVOID                       Parameters
     )
 {
-    NTSTATUS            status;
+    PSCSI_SUPPORTED_CONTROL_TYPE_LIST   List;
+
+    UNREFERENCED_PARAMETER(DevExt);
+
+    switch (ControlType) {
+    case ScsiQuerySupportedControlTypes:
+        List = Parameters;
+        List->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
+        break;
+
+    default:
+        break;
+    }
+    return ScsiAdapterControlSuccess;
+}
+
+HW_FIND_ADAPTER     AdapterHwFindAdapter;
+
+ULONG
+AdapterHwFindAdapter(
+    IN  PVOID                               DevExt,
+    IN  PVOID                               Context,
+    IN  PVOID                               BusInformation,
+    IN  PCHAR                               ArgumentString,
+    IN OUT PPORT_CONFIGURATION_INFORMATION  ConfigInfo,
+    OUT PBOOLEAN                            Again
+    )
+{
+    PXENVBD_ADAPTER                         Adapter = DevExt;
+    PDEVICE_OBJECT                          DeviceObject;
+    PDEVICE_OBJECT                          PhysicalDeviceObject;
+    PDEVICE_OBJECT                          LowerDeviceObject;
+    NTSTATUS                                status;
+
+    UNREFERENCED_PARAMETER(Context);
+    UNREFERENCED_PARAMETER(BusInformation);
+    UNREFERENCED_PARAMETER(ArgumentString);
+    UNREFERENCED_PARAMETER(Again);
+
+    // setup config info
+    ConfigInfo->MaximumTransferLength       = XENVBD_MAX_TRANSFER_LENGTH;
+    ConfigInfo->NumberOfPhysicalBreaks      = XENVBD_MAX_PHYSICAL_BREAKS;
+    ConfigInfo->AlignmentMask               = 0; // Byte-Aligned
+    ConfigInfo->NumberOfBuses               = 1;
+    ConfigInfo->InitiatorBusId[0]           = 1;
+    ConfigInfo->ScatterGather               = TRUE;
+    ConfigInfo->Master                      = TRUE;
+    ConfigInfo->CachesData                  = FALSE;
+    ConfigInfo->MapBuffers                  = STOR_MAP_NON_READ_WRITE_BUFFERS;
+    ConfigInfo->MaximumNumberOfTargets      = XENVBD_MAX_TARGETS;
+    ConfigInfo->MaximumNumberOfLogicalUnits = 1;
+    ConfigInfo->WmiDataProvider             = FALSE; // should be TRUE
+    ConfigInfo->SynchronizationModel        = StorSynchronizeFullDuplex;
+
+    if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
+        ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
+
+    // We need to do this to avoid an assertion in a checked kernel
+    (VOID) StorPortGetUncachedExtension(DevExt, ConfigInfo, PAGE_SIZE);
+
+    (VOID) StorPortGetDeviceObjects(DevExt,
+                                    &DeviceObject,
+                                    &PhysicalDeviceObject,
+                                    &LowerDeviceObject);
+    if (Adapter->DeviceObject == DeviceObject)
+        return SP_RETURN_FOUND;
+
+    status = AdapterInitialize(Adapter,
+                               DeviceObject,
+                               PhysicalDeviceObject,
+                               LowerDeviceObject);
+    if (!NT_SUCCESS(status))
+        goto fail1;
 
-    status = XENBUS_DEBUG(Acquire, &Adapter->Debug);
+    AdapterUnplugRequest(Adapter, TRUE);
+
+    status = AdapterD3ToD0(Adapter);
     if (!NT_SUCCESS(status))
-        return NULL;
+        goto fail2;
+
+    DriverSetAdapter(Adapter);
+    return SP_RETURN_FOUND;
 
-    return &Adapter->Debug;
+fail2:
+    Error("fail2\n");
+    AdapterUnplugRequest(Adapter, FALSE);
+    AdapterTeardown(Adapter);
+fail1:
+    Error("fail1\n");
+    return SP_RETURN_ERROR;
 }
 
-PXENBUS_SUSPEND_INTERFACE
-AdapterAcquireSuspend(
-    __in PXENVBD_ADAPTER    Adapter    
+HW_INITIALIZE   AdapterHwInitialize;
+
+BOOLEAN 
+AdapterHwInitialize(
+    IN  PVOID   DevExt
     )
 {
-    NTSTATUS            status;
+    UNREFERENCED_PARAMETER(DevExt);
+    return TRUE;
+}
+
+HW_INTERRUPT    AdapterHwInterrupt;
+
+BOOLEAN 
+AdapterHwInterrupt(
+    IN  PVOID   DevExt
+    )
+{
+    UNREFERENCED_PARAMETER(DevExt);
+    return TRUE;
+}
 
-    status = XENBUS_SUSPEND(Acquire, &Adapter->Suspend);
+NTSTATUS
+AdapterDriverEntry(
+    IN  PUNICODE_STRING     RegistryPath,
+    IN  PDRIVER_OBJECT      DriverObject
+    )
+{
+    HW_INITIALIZATION_DATA  InitData;
+    NTSTATUS                status;
+
+    RtlZeroMemory(&InitData, sizeof(InitData));
+    InitData.HwInitializationDataSize   = sizeof(InitData);
+    InitData.AdapterInterfaceType       = Internal;
+    InitData.HwInitialize               = AdapterHwInitialize;
+    InitData.HwStartIo                  = AdapterHwStartIo;
+    InitData.HwInterrupt                = AdapterHwInterrupt;
+#pragma warning(suppress : 4152)
+    InitData.HwFindAdapter              = AdapterHwFindAdapter;
+    InitData.HwResetBus                 = AdapterHwResetBus;
+    InitData.HwDmaStarted               = NULL;
+    InitData.HwAdapterState             = NULL;
+    InitData.DeviceExtensionSize        = sizeof(XENVBD_ADAPTER);
+    InitData.SpecificLuExtensionSize    = sizeof(ULONG); // not actually used
+    InitData.SrbExtensionSize           = sizeof(XENVBD_SRBEXT);
+    InitData.NumberOfAccessRanges       = 2;
+    InitData.MapBuffers                 = STOR_MAP_NON_READ_WRITE_BUFFERS;
+    InitData.NeedPhysicalAddresses      = TRUE;
+    InitData.TaggedQueuing              = TRUE;
+    InitData.AutoRequestSense           = TRUE;
+    InitData.MultipleRequestPerLu       = TRUE;
+    InitData.HwAdapterControl           = AdapterHwAdapterControl;
+    InitData.HwBuildIo                  = AdapterHwBuildIo;
+
+    status = StorPortInitialize(DriverObject,
+                                RegistryPath,
+                                &InitData,
+                                NULL);
     if (!NT_SUCCESS(status))
-        return NULL;
+        goto fail1;
 
-    return &Adapter->Suspend;
+    return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 %08x\n", status);
+    return status;
 }
+
+#define ADAPTER_GET_INTERFACE(_name, _type)                     \
+VOID                                                            \
+AdapterGet ## _name ## Interface(                               \
+    IN  PXENVBD_ADAPTER Adapter,                                \
+    OUT _type           _name ## Interface                      \
+    )                                                           \
+{                                                               \
+    * ## _name ## Interface = Adapter-> ## _name ## Interface;  \
+}
+
+ADAPTER_GET_INTERFACE(Store, PXENBUS_STORE_INTERFACE)
+ADAPTER_GET_INTERFACE(Debug, PXENBUS_DEBUG_INTERFACE)
+ADAPTER_GET_INTERFACE(Evtchn, PXENBUS_EVTCHN_INTERFACE)
+ADAPTER_GET_INTERFACE(Gnttab, PXENBUS_GNTTAB_INTERFACE)
+ADAPTER_GET_INTERFACE(Suspend, PXENBUS_SUSPEND_INTERFACE)
+
+#undef ADAPTER_GET_INTERFACE
diff --git a/src/xenvbd/adapter.h b/src/xenvbd/adapter.h
index 09d5ee6..2867398 100644
--- a/src/xenvbd/adapter.h
+++ b/src/xenvbd/adapter.h
@@ -37,126 +37,57 @@
 typedef struct _XENVBD_ADAPTER XENVBD_ADAPTER, *PXENVBD_ADAPTER;
 
 #include <storport.h>
-#include "target.h"
 #include <store_interface.h>
 #include <evtchn_interface.h>
 #include <gnttab_interface.h>
 #include <debug_interface.h>
 #include <suspend_interface.h>
-#include <unplug_interface.h>
 
-// Link TARGETs
-extern BOOLEAN
-AdapterLinkTarget(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PXENVBD_TARGET                 Target
-    );
-
-extern BOOLEAN
-AdapterUnlinkTarget(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PXENVBD_TARGET                 Target
-    );
-// Query Methods
-__checkReturn
-extern PDEVICE_OBJECT
-AdapterGetDeviceObject(
-    __in PXENVBD_ADAPTER                 Adapter
+#define ADAPTER_GET_INTERFACE(_name, _type)     \
+extern VOID                                     \
+AdapterGet ## _name ## Interface(               \
+    IN  PXENVBD_ADAPTER Adapter,                \
+    OUT _type           _name ## Interface      \
     );
 
-extern ULONG
-AdapterSizeofXenvbdAdapter(
-    );
+ADAPTER_GET_INTERFACE(Store, PXENBUS_STORE_INTERFACE)
+ADAPTER_GET_INTERFACE(Debug, PXENBUS_DEBUG_INTERFACE)
+ADAPTER_GET_INTERFACE(Evtchn, PXENBUS_EVTCHN_INTERFACE)
+ADAPTER_GET_INTERFACE(Gnttab, PXENBUS_GNTTAB_INTERFACE)
+ADAPTER_GET_INTERFACE(Suspend, PXENBUS_SUSPEND_INTERFACE)
 
-extern PCHAR
-AdapterEnum(
-    __in PXENVBD_ADAPTER                 Adapter
-    );
+#undef ADAPTER_GET_INTERFACE
 
-// SRB Methods
-extern VOID
-AdapterStartSrb(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PSCSI_REQUEST_BLOCK         Srb
+extern BOOLEAN
+AdapterIsTargetEmulated(
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  ULONG           TargetId
     );
 
 extern VOID
 AdapterCompleteSrb(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PSCSI_REQUEST_BLOCK         Srb
-    );
-
-// StorPort Methods
-extern BOOLEAN
-AdapterResetBus(
-    __in PXENVBD_ADAPTER                 Adapter
-    );
-
-extern ULONG
-AdapterFindAdapter(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __inout PPORT_CONFIGURATION_INFORMATION  ConfigInfo
-    );
-
-extern BOOLEAN 
-AdapterBuildIo(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PSCSI_REQUEST_BLOCK         Srb
-    );
-
-extern BOOLEAN 
-AdapterStartIo(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PSCSI_REQUEST_BLOCK         Srb
-    );
-
-__checkReturn
-extern NTSTATUS
-AdapterForwardPnp(
-    __in PXENVBD_ADAPTER                Adapter,
-    __in PDEVICE_OBJECT             DeviceObject,
-    __in PIRP                       Irp
+    IN  PXENVBD_ADAPTER     Adapter,
+    IN  PSCSI_REQUEST_BLOCK Srb
     );
 
-__checkReturn
 extern NTSTATUS
 AdapterDispatchPnp(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PDEVICE_OBJECT              DeviceObject,
-    __in PIRP                        Irp
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp
     );
 
-__checkReturn
 extern NTSTATUS
 AdapterDispatchPower(
-    __in PXENVBD_ADAPTER                 Adapter,
-    __in PDEVICE_OBJECT              DeviceObject,
-    __in PIRP                        Irp
-    );
-
-extern PXENBUS_STORE_INTERFACE
-AdapterAcquireStore(
-    __in PXENVBD_ADAPTER                 Adapter
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp
     );
 
-extern PXENBUS_EVTCHN_INTERFACE
-AdapterAcquireEvtchn(
-    __in PXENVBD_ADAPTER                 Adapter
-    );
-
-extern PXENBUS_GNTTAB_INTERFACE
-AdapterAcquireGnttab(
-    __in PXENVBD_ADAPTER                 Adapter
-    );
-
-extern PXENBUS_DEBUG_INTERFACE
-AdapterAcquireDebug(
-    __in PXENVBD_ADAPTER                 Adapter
-    );
-
-extern PXENBUS_SUSPEND_INTERFACE
-AdapterAcquireSuspend(
-    __in PXENVBD_ADAPTER                 Adapter
+extern NTSTATUS
+AdapterDriverEntry(
+    IN  PUNICODE_STRING RegistryPath,
+    IN  PDRIVER_OBJECT  DriverObject
     );
 
 #endif // _XENVBD_ADAPTER_H
diff --git a/src/xenvbd/blockring.c b/src/xenvbd/blockring.c
index a0ba7c7..bcef877 100644
--- a/src/xenvbd/blockring.c
+++ b/src/xenvbd/blockring.c
@@ -49,7 +49,7 @@ struct _XENVBD_BLOCKRING {
     BOOLEAN                         Connected;
     BOOLEAN                         Enabled;
 
-    PXENBUS_STORE_INTERFACE         StoreInterface;
+    XENBUS_STORE_INTERFACE          StoreInterface;
 
     KSPIN_LOCK                      Lock;
     PMDL                            Mdl;
@@ -284,10 +284,10 @@ BlockRingConnect(
 
     ASSERT(BlockRing->Connected == FALSE);
 
-    BlockRing->StoreInterface = AdapterAcquireStore(Adapter);
-
-    status = STATUS_UNSUCCESSFUL;
-    if (BlockRing->StoreInterface == NULL)
+    AdapterGetStoreInterface(Adapter, &BlockRing->StoreInterface);
+   
+    status = XENBUS_STORE(Acquire, &BlockRing->StoreInterface);
+    if (!NT_SUCCESS(status))
         goto fail1;
 
     status = FrontendStoreReadBackend(BlockRing->Frontend, 
"max-ring-page-order", &Value);
@@ -355,7 +355,7 @@ BlockRingStoreWrite(
 
     if (BlockRing->Order == 0) {
         status = XENBUS_STORE(Printf, 
-                              BlockRing->StoreInterface, 
+                              &BlockRing->StoreInterface, 
                               Transaction, 
                               FrontendPath,
                               "ring-ref", 
@@ -367,7 +367,7 @@ BlockRingStoreWrite(
         ULONG   Index, RingPages;
 
         status = XENBUS_STORE(Printf, 
-                              BlockRing->StoreInterface, 
+                              &BlockRing->StoreInterface, 
                               Transaction, 
                               FrontendPath, 
                               "ring-page-order", 
@@ -383,7 +383,7 @@ BlockRingStoreWrite(
             if (!NT_SUCCESS(status))
                 return status;
             status = XENBUS_STORE(Printf, 
-                                  BlockRing->StoreInterface, 
+                                  &BlockRing->StoreInterface, 
                                   Transaction, 
                                   FrontendPath,
                                   Name, 
@@ -395,7 +395,7 @@ BlockRingStoreWrite(
     }
 
     status = XENBUS_STORE(Printf, 
-                          BlockRing->StoreInterface, 
+                          &BlockRing->StoreInterface, 
                           Transaction, 
                           FrontendPath,
                           "protocol", 
@@ -453,8 +453,8 @@ BlockRingDisconnect(
 
     BlockRing->Order = 0;
 
-    XENBUS_STORE(Release, BlockRing->StoreInterface);
-    BlockRing->StoreInterface = NULL;
+    XENBUS_STORE(Release, &BlockRing->StoreInterface);
+    RtlZeroMemory(&BlockRing->StoreInterface, sizeof(XENBUS_STORE_INTERFACE));
 
     BlockRing->Connected = FALSE;
 }
diff --git a/src/xenvbd/driver.c b/src/xenvbd/driver.c
index 233318f..d45c6b6 100644
--- a/src/xenvbd/driver.c
+++ b/src/xenvbd/driver.c
@@ -59,6 +59,16 @@ static XENVBD_DRIVER Driver;
 
 #define XENVBD_POOL_TAG     'dbvX'
 
+VOID
+DriverSetAdapter(
+    IN  PVOID   Adapter
+    )
+{
+    ASSERT3P(Driver.Adapter, ==, NULL);
+    ASSERT3P(Adapter, !=, NULL);
+    Driver.Adapter = Adapter;
+}
+
 static FORCEINLINE HANDLE
 __DriverGetParametersKey(
     VOID
@@ -168,141 +178,6 @@ fail1:
     Error("fail1 (%08x)\n", status);
 }
 
-HW_INITIALIZE   HwInitialize;
-
-BOOLEAN 
-HwInitialize(
-    IN  PVOID   DevExt
-    )
-{
-    UNREFERENCED_PARAMETER(DevExt);
-    return TRUE;
-}
-
-HW_INTERRUPT    HwInterrupt;
-
-BOOLEAN 
-HwInterrupt(
-    IN  PVOID   DevExt
-    )
-{
-    UNREFERENCED_PARAMETER(DevExt);
-    return TRUE;
-}
-
-HW_ADAPTER_CONTROL  HwAdapterControl;
-
-SCSI_ADAPTER_CONTROL_STATUS
-HwAdapterControl(
-    IN  PVOID                       DevExt,
-    IN  SCSI_ADAPTER_CONTROL_TYPE   ControlType,
-    IN  PVOID                       Parameters
-    )
-{
-    PSCSI_SUPPORTED_CONTROL_TYPE_LIST   List;
-
-    UNREFERENCED_PARAMETER(DevExt);
-
-    switch (ControlType) {
-    case ScsiQuerySupportedControlTypes:
-        List = Parameters;
-        List->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
-        break;
-
-    case ScsiStopAdapter:
-    case ScsiRestartAdapter:
-    case ScsiSetBootConfig:
-    case ScsiSetRunningConfig:
-    default:
-        break;
-    }
-    return ScsiAdapterControlSuccess;
-}
-
-HW_RESET_BUS        HwResetBus;
-
-BOOLEAN
-HwResetBus(
-    IN  PVOID   DevExt,
-    IN  ULONG   PathId
-    )
-{
-    UNREFERENCED_PARAMETER(PathId);
-
-    return AdapterResetBus(DevExt);
-}
-
-HW_FIND_ADAPTER     HwFindAdapter;
-
-ULONG
-HwFindAdapter(
-    IN  PVOID                               DevExt,
-    IN  PVOID                               Context,
-    IN  PVOID                               BusInformation,
-    IN  PCHAR                               ArgumentString,
-    IN OUT PPORT_CONFIGURATION_INFORMATION  ConfigInfo,
-    OUT PBOOLEAN                            Again
-    )
-{
-    ULONG                                   Return;
-
-    UNREFERENCED_PARAMETER(Context);
-    UNREFERENCED_PARAMETER(BusInformation);
-    UNREFERENCED_PARAMETER(ArgumentString);
-    UNREFERENCED_PARAMETER(Again);
-
-    Return = AdapterFindAdapter(DevExt, ConfigInfo);
-    if (Return == SP_RETURN_FOUND)
-        Driver.Adapter = DevExt;
-    return Return;
-}
-
-static FORCEINLINE BOOLEAN
-__FailStorageRequest(
-    IN  PVOID               DevExt,
-    IN  PSCSI_REQUEST_BLOCK Srb
-    )
-{
-    if (Srb->Function == SRB_FUNCTION_STORAGE_REQUEST_BLOCK) {
-        // Win8 and above storport request. not supported
-        // complete the request (with fail code)
-        Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
-        StorPortNotification(RequestComplete, DevExt, Srb);
-        Error("(0x%p) STORAGE_REQUEST_BLOCK not supported\n", DevExt);
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-HW_BUILDIO          HwBuildIo;
-
-BOOLEAN 
-HwBuildIo(
-    IN  PVOID               DevExt,
-    IN  PSCSI_REQUEST_BLOCK Srb
-    )
-{
-    if (__FailStorageRequest(DevExt, Srb))
-        return FALSE; // dont pass to HwStartIo
-
-    return AdapterBuildIo(DevExt, Srb);
-}
-
-HW_STARTIO          HwStartIo;
-
-BOOLEAN 
-HwStartIo(
-    IN  PVOID               DevExt,
-    IN  PSCSI_REQUEST_BLOCK Srb
-    )
-{
-    if (__FailStorageRequest(DevExt, Srb))
-        return TRUE; // acknowledge the srb
-
-    return AdapterStartIo(DevExt, Srb);
-}
-
 __drv_dispatchType(IRP_MJ_PNP)
 DRIVER_DISPATCH             DispatchPnp;
 
@@ -315,10 +190,7 @@ DispatchPnp(
     if (Driver.Adapter == NULL)
         return DriverDispatchPnp(DeviceObject, Irp);
 
-    if (AdapterGetDeviceObject(Driver.Adapter) == DeviceObject)
-        return AdapterDispatchPnp(Driver.Adapter, DeviceObject, Irp);
-
-    return AdapterForwardPnp(Driver.Adapter, DeviceObject, Irp);
+    return AdapterDispatchPnp(Driver.Adapter, DeviceObject, Irp);
 }
 
 __drv_dispatchType(IRP_MJ_POWER)
@@ -333,10 +205,7 @@ DispatchPower(
     if (Driver.Adapter == NULL)
         return DriverDispatchPower(DeviceObject, Irp);
 
-    if (AdapterGetDeviceObject(Driver.Adapter) == DeviceObject)
-        return AdapterDispatchPower(Driver.Adapter, DeviceObject, Irp);
-
-    return DriverDispatchPower(DeviceObject, Irp);
+    return AdapterDispatchPower(Driver.Adapter, DeviceObject, Irp);
 }
 
 DRIVER_UNLOAD           DriverUnload;
@@ -378,7 +247,6 @@ DriverEntry(
     IN  PUNICODE_STRING     RegistryPath
     )
 {
-    HW_INITIALIZATION_DATA  InitData;
     HANDLE                  ServiceKey;
     HANDLE                  ParametersKey;
     NTSTATUS                status;
@@ -418,33 +286,8 @@ DriverEntry(
     Driver.Adapter = NULL;
     BufferInitialize();
 
-    RtlZeroMemory(&InitData, sizeof(InitData));
-    InitData.HwInitializationDataSize   = sizeof(InitData);
-    InitData.AdapterInterfaceType       = Internal;
-    InitData.HwInitialize               = HwInitialize;
-    InitData.HwStartIo                  = HwStartIo;
-    InitData.HwInterrupt                = HwInterrupt;
-#pragma warning(suppress : 4152)
-    InitData.HwFindAdapter              = HwFindAdapter;
-    InitData.HwResetBus                 = HwResetBus;
-    InitData.HwDmaStarted               = NULL;
-    InitData.HwAdapterState             = NULL;
-    InitData.DeviceExtensionSize        = AdapterSizeofXenvbdAdapter();
-    InitData.SpecificLuExtensionSize    = sizeof(ULONG); // not actually used
-    InitData.SrbExtensionSize           = sizeof(XENVBD_SRBEXT);
-    InitData.NumberOfAccessRanges       = 2;
-    InitData.MapBuffers                 = STOR_MAP_NON_READ_WRITE_BUFFERS;
-    InitData.NeedPhysicalAddresses      = TRUE;
-    InitData.TaggedQueuing              = TRUE;
-    InitData.AutoRequestSense           = TRUE;
-    InitData.MultipleRequestPerLu       = TRUE;
-    InitData.HwAdapterControl           = HwAdapterControl;
-    InitData.HwBuildIo                  = HwBuildIo;
-
-    status = StorPortInitialize(DriverObject,
-                                RegistryPath,
-                                &InitData,
-                                NULL);
+    status = AdapterDriverEntry(RegistryPath,
+                                DriverObject);
     if (!NT_SUCCESS(status))
         goto fail4;
 
diff --git a/src/xenvbd/driver.h b/src/xenvbd/driver.h
index 13c6135..6b73c4d 100644
--- a/src/xenvbd/driver.h
+++ b/src/xenvbd/driver.h
@@ -39,6 +39,11 @@
 #define XENVBD_MAX_TRANSFER_LENGTH      (XENVBD_MAX_PAGES_PER_SRB * PAGE_SIZE)
 #define XENVBD_MAX_PHYSICAL_BREAKS      (XENVBD_MAX_PAGES_PER_SRB - 1)
 
+extern VOID
+DriverSetAdapter(
+    IN  PVOID   Adapter
+    ); 
+
 extern HANDLE
 DriverGetParametersKey(
     VOID
diff --git a/src/xenvbd/frontend.c b/src/xenvbd/frontend.c
index 150710d..d82eaa2 100644
--- a/src/xenvbd/frontend.c
+++ b/src/xenvbd/frontend.c
@@ -66,8 +66,8 @@ struct _XENVBD_FRONTEND {
     PVOID                       Inquiry;
 
     // Interfaces to XenBus
-    PXENBUS_STORE_INTERFACE     Store;
-    PXENBUS_SUSPEND_INTERFACE   Suspend;
+    XENBUS_STORE_INTERFACE      StoreInterface;
+    XENBUS_SUSPEND_INTERFACE    SuspendInterface;
 
     PXENBUS_SUSPEND_CALLBACK    SuspendLateCallback;
 
@@ -181,6 +181,13 @@ FrontendGetTargetId(
 {
     return Frontend->TargetId;
 }
+ULONG
+FrontendGetDeviceId(
+    __in  PXENVBD_FRONTEND      Frontend
+    )
+{
+     return Frontend->DeviceId;
+}
 PVOID
 FrontendGetInquiry(
     __in  PXENVBD_FRONTEND      Frontend
@@ -225,7 +232,7 @@ FrontendStoreWriteFrontend(
     )
 {
     return XENBUS_STORE(Printf,
-                        Frontend->Store,
+                        &Frontend->StoreInterface,
                         NULL,
                         Frontend->FrontendPath,
                         Name,
@@ -241,24 +248,20 @@ FrontendStoreReadBackend(
     NTSTATUS    Status;
 
     Status = STATUS_INVALID_PARAMETER;
-    if (Frontend->Store == NULL) 
-        goto fail1;
-
     if (Frontend->BackendPath == NULL)
-        goto fail2;
+        goto fail1;
 
     Status = XENBUS_STORE(Read,
-                          Frontend->Store,
+                          &Frontend->StoreInterface,
                           NULL,
                           Frontend->BackendPath,
                           Name,
                           Value);
     if (!NT_SUCCESS(Status))
-        goto fail3;
+        goto fail2;
 
     return STATUS_SUCCESS;
 
-fail3:
 fail2:
 fail1:
     return Status;
@@ -270,7 +273,7 @@ FrontendStoreFree(
     )
 {
     XENBUS_STORE(Free,
-                 Frontend->Store,
+                 &Frontend->StoreInterface,
                  Value);
 }
 __drv_maxIRQL(DISPATCH_LEVEL)
@@ -282,7 +285,7 @@ FrontendWriteUsage(
     NTSTATUS    Status;
 
     Status = XENBUS_STORE(Printf,
-                          Frontend->Store,
+                          &Frontend->StoreInterface,
                           NULL,
                           Frontend->TargetPath, 
                           "paging",
@@ -292,7 +295,7 @@ FrontendWriteUsage(
         goto out;
 
     Status = XENBUS_STORE(Printf,
-                          Frontend->Store,
+                          &Frontend->StoreInterface,
                           NULL,
                           Frontend->TargetPath, 
                           "hibernation",
@@ -302,7 +305,7 @@ FrontendWriteUsage(
         goto out;
 
     Status = XENBUS_STORE(Printf,
-                          Frontend->Store,
+                          &Frontend->StoreInterface,
                           NULL,
                           Frontend->TargetPath, 
                           "dump",
@@ -343,7 +346,7 @@ __UpdateBackendPath(
     ULONG       Length;
 
     Status = XENBUS_STORE(Read,
-                          Frontend->Store,
+                          &Frontend->StoreInterface,
                           NULL,
                           Frontend->FrontendPath, 
                           "backend-id",
@@ -351,14 +354,14 @@ __UpdateBackendPath(
     if (NT_SUCCESS(Status)) {
         Frontend->BackendId = (USHORT)strtoul(Value, NULL, 10);
         XENBUS_STORE(Free,
-                     Frontend->Store,
+                     &Frontend->StoreInterface,
                      Value);
     } else {
         Frontend->BackendId = 0;
     }
 
     Status = XENBUS_STORE(Read,
-                          Frontend->Store,
+                          &Frontend->StoreInterface,
                           NULL,
                           Frontend->FrontendPath,
                           "backend",
@@ -379,7 +382,7 @@ __UpdateBackendPath(
         }
 
         XENBUS_STORE(Free,
-                     Frontend->Store,
+                     &Frontend->StoreInterface,
                      Value);
     } else {
         Warning("Failed to read \'backend\' from \'%s\' (%08x)\n", 
@@ -401,7 +404,7 @@ __ReadState(
     PCHAR           Buffer;
 
     Status = XENBUS_STORE(Read,
-                          Frontend->Store,
+                          &Frontend->StoreInterface,
                           Transaction,
                           Path, 
                           "state",
@@ -411,7 +414,7 @@ __ReadState(
 
     *State = (XenbusState)strtoul(Buffer, NULL, 10);
     XENBUS_STORE(Free,
-                 Frontend->Store,
+                 &Frontend->StoreInterface,
                  Buffer);
 
     return STATUS_SUCCESS;
@@ -442,7 +445,7 @@ __WaitState(
 
     ASSERT3P(Frontend->BackendPath, !=, NULL);
     Status = XENBUS_STORE(WatchAdd,
-                          Frontend->Store,
+                          &Frontend->StoreInterface,
                           Frontend->BackendPath,
                           "state", 
                           &Event,
@@ -458,7 +461,7 @@ __WaitState(
         if (KeWaitForSingleObject(&Event, Executive, KernelMode, 
                                     FALSE, &Timeout) == STATUS_TIMEOUT) {
             XENBUS_STORE(Poll,
-                         Frontend->Store);
+                         &Frontend->StoreInterface);
 
             KeQuerySystemTime(&CurrentTime);
             if ((CurrentTime.QuadPart - StartTime.QuadPart) > 10000) {
@@ -477,7 +480,7 @@ __WaitState(
     }
 
     XENBUS_STORE(WatchRemove,
-                 Frontend->Store,
+                 &Frontend->StoreInterface,
                  Watch);
 
     Trace("Target[%d] : BACKEND_STATE  -> %s\n",
@@ -490,7 +493,7 @@ fail2:
     Error("Fail2\n");
 
     XENBUS_STORE(WatchRemove,
-                 Frontend->Store,
+                 &Frontend->StoreInterface,
                  Watch);
 fail1:
     Error("Fail1 (%08x)\n", Status);
@@ -507,7 +510,7 @@ ___SetState(
     NTSTATUS    Status;
 
     Status = XENBUS_STORE(Printf,
-                          Frontend->Store,
+                          &Frontend->StoreInterface,
                           NULL,
                           Frontend->FrontendPath,
                           "state",
@@ -535,8 +538,6 @@ __CheckBackendForEject(
     ULONG           Attempt;
     NTSTATUS        Status;
 
-    if (Frontend->Store == NULL)
-        return;
     if (Frontend->FrontendPath == NULL)
         return;
     if (Frontend->BackendPath == NULL)
@@ -552,7 +553,7 @@ __CheckBackendForEject(
         PCHAR                       Buffer;
 
         Status = XENBUS_STORE(TransactionStart,
-                              Frontend->Store,
+                              &Frontend->StoreInterface,
                               &Transaction);
         if (!NT_SUCCESS(Status))
             break;
@@ -572,7 +573,7 @@ __CheckBackendForEject(
             goto abort;
 
         Status = XENBUS_STORE(Read,
-                              Frontend->Store,
+                              &Frontend->StoreInterface,
                               Transaction,
                               Frontend->BackendPath, 
                               "online",
@@ -582,11 +583,11 @@ __CheckBackendForEject(
 
         Online = (BOOLEAN)strtol(Buffer, NULL, 2);
         XENBUS_STORE(Free,
-                     Frontend->Store,
+                     &Frontend->StoreInterface,
                      Buffer);
 
         Status = XENBUS_STORE(TransactionEnd,
-                              Frontend->Store,
+                              &Frontend->StoreInterface,
                               Transaction,
                               TRUE);
         if (Status != STATUS_RETRY || ++Attempt > 10)
@@ -596,7 +597,7 @@ __CheckBackendForEject(
 
 abort:
         (VOID) XENBUS_STORE(TransactionEnd,
-                            Frontend->Store,
+                            &Frontend->StoreInterface,
                             Transaction,
                             FALSE);
         break;
@@ -626,7 +627,7 @@ FrontendReadFeature(
     BOOLEAN         Old = *Value;
 
     status = XENBUS_STORE(Read,
-                          Frontend->Store,
+                          &Frontend->StoreInterface,
                           NULL,
                           Frontend->BackendPath,
                           Name,
@@ -636,7 +637,7 @@ FrontendReadFeature(
 
     *Value = !!(strtoul(Buffer, NULL, 10));
     XENBUS_STORE(Free,
-                    Frontend->Store,
+                    &Frontend->StoreInterface,
                     Buffer);
 
     // check registry for disable-override
@@ -665,7 +666,7 @@ FrontendReadValue32(
     ULONG           Old = *Value;
 
     status = XENBUS_STORE(Read,
-                          Frontend->Store,
+                          &Frontend->StoreInterface,
                           NULL,
                           Frontend->BackendPath,
                           Name,
@@ -675,7 +676,7 @@ FrontendReadValue32(
 
     *Value = strtoul(Buffer, NULL, 10);
     XENBUS_STORE(Free,
-                    Frontend->Store,
+                    &Frontend->StoreInterface,
                     Buffer);
 
     // check registry for disable-override
@@ -703,7 +704,7 @@ FrontendReadValue64(
     ULONG64         Old = *Value;
 
     status = XENBUS_STORE(Read,
-                          Frontend->Store,
+                          &Frontend->StoreInterface,
                           NULL,
                           Frontend->BackendPath,
                           Name,
@@ -713,7 +714,7 @@ FrontendReadValue64(
 
     *Value = _strtoui64(Buffer, NULL, 10);
     XENBUS_STORE(Free,
-                    Frontend->Store,
+                    &Frontend->StoreInterface,
                     Buffer);
 
     return Old != *Value;
@@ -896,7 +897,7 @@ FrontendClose(
     // unwatch backend (null check for initial close operation)
     if (Frontend->BackendWatch)
         XENBUS_STORE(WatchRemove,
-                     Frontend->Store,
+                     &Frontend->StoreInterface,
                      Frontend->BackendWatch);
     Frontend->BackendWatch = NULL;
     
@@ -964,7 +965,7 @@ FrontendPrepare(
 
     // watch backend (4 paths needed)
     Status = XENBUS_STORE(WatchAdd,
-                          Frontend->Store,
+                          &Frontend->StoreInterface,
                           NULL,
                           Frontend->BackendPath,
                           ThreadGetEvent(Frontend->BackendThread),
@@ -978,7 +979,7 @@ FrontendPrepare(
         goto fail3;
 
     Status = XENBUS_STORE(Printf,
-                          Frontend->Store,
+                          &Frontend->StoreInterface,
                           NULL,
                           Frontend->TargetPath, 
                           "frontend",
@@ -988,7 +989,7 @@ FrontendPrepare(
         goto fail4;
 
     Status = XENBUS_STORE(Printf,
-                          Frontend->Store,
+                          &Frontend->StoreInterface,
                           NULL,
                           Frontend->TargetPath, 
                           "device",
@@ -1042,7 +1043,7 @@ fail4:
 fail3:
     Error("Fail3\n");
     (VOID) XENBUS_STORE(WatchRemove,
-                        Frontend->Store,
+                        &Frontend->StoreInterface,
                         Frontend->BackendWatch);
     Frontend->BackendWatch = NULL;
 fail2:
@@ -1078,7 +1079,7 @@ FrontendConnect(
         PXENBUS_STORE_TRANSACTION   Transaction;
         
         Status = XENBUS_STORE(TransactionStart,
-                              Frontend->Store,
+                              &Frontend->StoreInterface,
                               &Transaction);
         if (!NT_SUCCESS(Status))
             break;
@@ -1096,7 +1097,7 @@ FrontendConnect(
             goto abort;
 
         Status = XENBUS_STORE(Printf,
-                              Frontend->Store,
+                              &Frontend->StoreInterface,
                               Transaction,
                               Frontend->FrontendPath,
                               "target-id",
@@ -1106,7 +1107,7 @@ FrontendConnect(
             goto abort;
 
         Status = XENBUS_STORE(Printf,
-                              Frontend->Store,
+                              &Frontend->StoreInterface,
                               Transaction,
                               Frontend->FrontendPath,
                               "feature-surprise-remove",
@@ -1116,7 +1117,7 @@ FrontendConnect(
             goto abort;
 
         Status = XENBUS_STORE(Printf,
-                              Frontend->Store,
+                              &Frontend->StoreInterface,
                               Transaction,
                               Frontend->FrontendPath,
                               "feature-online-resize",
@@ -1126,7 +1127,7 @@ FrontendConnect(
             goto abort;
 
         Status = XENBUS_STORE(TransactionEnd,
-                              Frontend->Store,
+                              &Frontend->StoreInterface,
                               Transaction,
                               TRUE);
         if (Status == STATUS_RETRY)
@@ -1136,7 +1137,7 @@ FrontendConnect(
 
 abort:
         (VOID) XENBUS_STORE(TransactionEnd,
-                            Frontend->Store,
+                            &Frontend->StoreInterface,
                             Transaction,
                             FALSE);
         break;
@@ -1436,28 +1437,28 @@ FrontendD3ToD0(
     __in  PXENVBD_FRONTEND        Frontend
     )
 {
+    PXENVBD_ADAPTER Adapter = TargetGetAdapter(Frontend->Target);
     NTSTATUS    Status;
     KIRQL       Irql;
 
     KeAcquireSpinLock(&Frontend->StateLock, &Irql);
 
     // acquire interfaces
-    Frontend->Store   = 
AdapterAcquireStore(TargetGetAdapter(Frontend->Target));
+    AdapterGetStoreInterface(Adapter, &Frontend->StoreInterface);
+    AdapterGetSuspendInterface(Adapter, &Frontend->SuspendInterface);
 
-    Status = STATUS_UNSUCCESSFUL;
-    if (Frontend->Store == NULL)
+    Status = XENBUS_STORE(Acquire, &Frontend->StoreInterface);
+    if (!NT_SUCCESS(Status))
         goto fail1;
 
-    Frontend->Suspend = 
AdapterAcquireSuspend(TargetGetAdapter(Frontend->Target));
-
-    Status = STATUS_UNSUCCESSFUL;
-    if (Frontend->Suspend == NULL)
+    Status = XENBUS_SUSPEND(Acquire, &Frontend->SuspendInterface);
+    if (!NT_SUCCESS(Status))
         goto fail2;
 
     // register suspend callback
     ASSERT3P(Frontend->SuspendLateCallback, ==, NULL);
     Status = XENBUS_SUSPEND(Register,
-                            Frontend->Suspend,
+                            &Frontend->SuspendInterface,
                             SUSPEND_CALLBACK_LATE,
                             FrontendSuspendLateCallback,
                             Frontend,
@@ -1474,14 +1475,14 @@ FrontendD3ToD0(
 fail3:
     Error("Fail3\n");
 
-    XENBUS_SUSPEND(Release, Frontend->Suspend);
-    Frontend->Suspend = NULL;
+    XENBUS_SUSPEND(Release, &Frontend->SuspendInterface);
+    RtlZeroMemory(&Frontend->SuspendInterface, 
sizeof(XENBUS_SUSPEND_INTERFACE));
 
 fail2:
     Error("Fail2\n");
 
-    XENBUS_STORE(Release, Frontend->Store);
-    Frontend->Store = NULL;
+    XENBUS_STORE(Release, &Frontend->StoreInterface);
+    RtlZeroMemory(&Frontend->StoreInterface, sizeof(XENBUS_STORE_INTERFACE));
 
 fail1:
     Error("Fail1 (%08x)\n", Status);
@@ -1506,7 +1507,7 @@ FrontendD0ToD3(
     // deregister suspend callback
     if (Frontend->SuspendLateCallback != NULL) {
         XENBUS_SUSPEND(Deregister,
-                       Frontend->Suspend,
+                       &Frontend->SuspendInterface,
                        Frontend->SuspendLateCallback);
         Frontend->SuspendLateCallback = NULL;
     }
@@ -1517,11 +1518,11 @@ FrontendD0ToD3(
     }
 
     // release interfaces
-    XENBUS_SUSPEND(Release, Frontend->Suspend);
-    Frontend->Suspend = NULL;
+    XENBUS_SUSPEND(Release, &Frontend->SuspendInterface);
+    RtlZeroMemory(&Frontend->SuspendInterface, 
sizeof(XENBUS_SUSPEND_INTERFACE));
     
-    XENBUS_STORE(Release, Frontend->Store);
-    Frontend->Store = NULL;
+    XENBUS_STORE(Release, &Frontend->StoreInterface);
+    RtlZeroMemory(&Frontend->StoreInterface, sizeof(XENBUS_STORE_INTERFACE));
 
     KeReleaseSpinLock(&Frontend->StateLock, Irql);
 }
diff --git a/src/xenvbd/frontend.h b/src/xenvbd/frontend.h
index 69dd13b..f466ef8 100644
--- a/src/xenvbd/frontend.h
+++ b/src/xenvbd/frontend.h
@@ -96,6 +96,10 @@ extern ULONG
 FrontendGetTargetId(
     __in  PXENVBD_FRONTEND      Frontend
     );
+extern ULONG
+FrontendGetDeviceId(
+    __in  PXENVBD_FRONTEND      Frontend
+    );
 extern PVOID
 FrontendGetInquiry(
     __in  PXENVBD_FRONTEND      Frontend
diff --git a/src/xenvbd/granter.c b/src/xenvbd/granter.c
index bd0fa5b..57b7df8 100644
--- a/src/xenvbd/granter.c
+++ b/src/xenvbd/granter.c
@@ -42,7 +42,7 @@ struct _XENVBD_GRANTER {
     BOOLEAN                         Connected;
     BOOLEAN                         Enabled;
 
-    PXENBUS_GNTTAB_INTERFACE        GnttabInterface;
+    XENBUS_GNTTAB_INTERFACE         GnttabInterface;
     PXENBUS_GNTTAB_CACHE            Cache;
     KSPIN_LOCK                      Lock;
 
@@ -145,10 +145,10 @@ GranterConnect(
 
     ASSERT(Granter->Connected == FALSE);
 
-    Granter->GnttabInterface = AdapterAcquireGnttab(Adapter);
+    AdapterGetGnttabInterface(Adapter, &Granter->GnttabInterface);
 
-    status = STATUS_UNSUCCESSFUL;
-    if (Granter->GnttabInterface == NULL)
+    status = XENBUS_GNTTAB(Acquire, &Granter->GnttabInterface);
+    if (!NT_SUCCESS(status))
         goto fail1;
 
     Granter->BackendDomain = BackendDomain;
@@ -161,7 +161,7 @@ GranterConnect(
         goto fail2;
 
     status = XENBUS_GNTTAB(CreateCache,
-                           Granter->GnttabInterface,
+                           &Granter->GnttabInterface,
                            Name,
                            0,
                            GranterAcquireLock,
@@ -177,8 +177,8 @@ GranterConnect(
 fail3:
 fail2:
     Granter->BackendDomain = 0;
-    XENBUS_GNTTAB(Release, Granter->GnttabInterface);
-    Granter->GnttabInterface = NULL;
+    XENBUS_GNTTAB(Release, &Granter->GnttabInterface);
+    RtlZeroMemory(&Granter->GnttabInterface, sizeof(XENBUS_GNTTAB_INTERFACE));
 fail1:
     return status;
 }
@@ -228,12 +228,12 @@ GranterDisconnect(
     Granter->Maximum = 0;
 
     XENBUS_GNTTAB(DestroyCache,
-                  Granter->GnttabInterface,
+                  &Granter->GnttabInterface,
                   Granter->Cache);
     Granter->Cache = NULL;
 
-    XENBUS_GNTTAB(Release, Granter->GnttabInterface);
-    Granter->GnttabInterface = NULL;
+    XENBUS_GNTTAB(Release, &Granter->GnttabInterface);
+    RtlZeroMemory(&Granter->GnttabInterface, sizeof(XENBUS_GNTTAB_INTERFACE));
 
     Granter->BackendDomain = 0;
     Granter->Connected = FALSE;
@@ -273,7 +273,7 @@ GranterGet(
         goto fail1;
 
     status = XENBUS_GNTTAB(PermitForeignAccess, 
-                           Granter->GnttabInterface, 
+                           &Granter->GnttabInterface, 
                            Granter->Cache,
                            FALSE,
                            Granter->BackendDomain,
@@ -308,7 +308,7 @@ GranterPut(
         return;
 
     status = XENBUS_GNTTAB(RevokeForeignAccess,
-                           Granter->GnttabInterface,
+                           &Granter->GnttabInterface,
                            Granter->Cache,
                            FALSE,
                            Entry);
@@ -329,6 +329,6 @@ GranterReference(
         return 0;
 
     return XENBUS_GNTTAB(GetReference,
-                         Granter->GnttabInterface,
+                         &Granter->GnttabInterface,
                          Entry);
 }
diff --git a/src/xenvbd/notifier.c b/src/xenvbd/notifier.c
index 4835a46..1e0c057 100644
--- a/src/xenvbd/notifier.c
+++ b/src/xenvbd/notifier.c
@@ -42,8 +42,8 @@ struct _XENVBD_NOTIFIER {
     BOOLEAN                         Connected;
     BOOLEAN                         Enabled;
 
-    PXENBUS_STORE_INTERFACE         StoreInterface;
-    PXENBUS_EVTCHN_INTERFACE        EvtchnInterface;
+    XENBUS_STORE_INTERFACE          StoreInterface;
+    XENBUS_EVTCHN_INTERFACE         EvtchnInterface;
 
     PXENBUS_EVTCHN_CHANNEL          Channel;
     ULONG                           Port;
@@ -119,7 +119,7 @@ NotifierDpc(
     FrontendNotifyResponses(Notifier->Frontend);
 
     XENBUS_EVTCHN(Unmask,
-                  Notifier->EvtchnInterface,
+                  &Notifier->EvtchnInterface,
                   Notifier->Channel,
                   FALSE);
 }
@@ -167,20 +167,19 @@ NotifierConnect(
 
     ASSERT(Notifier->Connected == FALSE);
 
-    Notifier->StoreInterface = AdapterAcquireStore(Adapter);
+    AdapterGetStoreInterface(Adapter, &Notifier->StoreInterface);
+    AdapterGetEvtchnInterface(Adapter, &Notifier->EvtchnInterface);
 
-    status = STATUS_UNSUCCESSFUL;
-    if (Notifier->StoreInterface == NULL)
+    status = XENBUS_STORE(Acquire, &Notifier->StoreInterface);
+    if (!NT_SUCCESS(status))
         goto fail1;
 
-    Notifier->EvtchnInterface = AdapterAcquireEvtchn(Adapter);
-
-    status = STATUS_UNSUCCESSFUL;
-    if (Notifier->EvtchnInterface == NULL)
+    status = XENBUS_EVTCHN(Acquire, &Notifier->EvtchnInterface);
+    if (!NT_SUCCESS(status))
         goto fail2;
 
     Notifier->Channel = XENBUS_EVTCHN(Open, 
-                                      Notifier->EvtchnInterface, 
+                                      &Notifier->EvtchnInterface, 
                                       XENBUS_EVTCHN_TYPE_UNBOUND, 
                                       NotifierInterrupt,
                                       Notifier, 
@@ -192,11 +191,11 @@ NotifierConnect(
         goto fail3;
 
     Notifier->Port = XENBUS_EVTCHN(GetPort,
-                                   Notifier->EvtchnInterface,
+                                   &Notifier->EvtchnInterface,
                                    Notifier->Channel);
 
     XENBUS_EVTCHN(Unmask,
-                  Notifier->EvtchnInterface,
+                  &Notifier->EvtchnInterface,
                   Notifier->Channel,
                   FALSE);
 
@@ -204,12 +203,12 @@ NotifierConnect(
     return STATUS_SUCCESS;
 
 fail3:
-    XENBUS_EVTCHN(Release, Notifier->EvtchnInterface);
-    Notifier->EvtchnInterface = NULL;
+    XENBUS_EVTCHN(Release, &Notifier->EvtchnInterface);
+    RtlZeroMemory(&Notifier->EvtchnInterface, sizeof(XENBUS_EVTCHN_INTERFACE));
 
 fail2:
-    XENBUS_STORE(Release, Notifier->StoreInterface);
-    Notifier->StoreInterface = NULL;
+    XENBUS_STORE(Release, &Notifier->StoreInterface);
+    RtlZeroMemory(&Notifier->StoreInterface, sizeof(XENBUS_STORE_INTERFACE));
 
 fail1:
     return status;
@@ -223,7 +222,7 @@ NotifierStoreWrite(
     )
 {
     return XENBUS_STORE(Printf, 
-                        Notifier->StoreInterface, 
+                        &Notifier->StoreInterface, 
                         Transaction, 
                         FrontendPath, 
                         "event-channel", 
@@ -239,7 +238,7 @@ NotifierEnable(
     ASSERT(Notifier->Enabled == FALSE);
 
     XENBUS_EVTCHN(Trigger,
-                  Notifier->EvtchnInterface,
+                  &Notifier->EvtchnInterface,
                   Notifier->Channel);
 
     Notifier->Enabled = TRUE;
@@ -263,16 +262,16 @@ NotifierDisconnect(
     ASSERT(Notifier->Connected == TRUE);
 
     XENBUS_EVTCHN(Close,
-                  Notifier->EvtchnInterface,
+                  &Notifier->EvtchnInterface,
                   Notifier->Channel);
     Notifier->Channel = NULL;
     Notifier->Port = 0;
 
-    XENBUS_EVTCHN(Release, Notifier->EvtchnInterface);
-    Notifier->EvtchnInterface = NULL;
+    XENBUS_EVTCHN(Release, &Notifier->EvtchnInterface);
+    RtlZeroMemory(&Notifier->EvtchnInterface, sizeof(XENBUS_EVTCHN_INTERFACE));
 
-    XENBUS_STORE(Release, Notifier->StoreInterface);
-    Notifier->StoreInterface = NULL;
+    XENBUS_STORE(Release, &Notifier->StoreInterface);
+    RtlZeroMemory(&Notifier->StoreInterface, sizeof(XENBUS_STORE_INTERFACE));
 
     Notifier->NumInts = Notifier->NumDpcs = 0;
 
@@ -318,7 +317,7 @@ NotifierTrigger(
 {
     if (Notifier->Enabled)
         XENBUS_EVTCHN(Trigger,
-                      Notifier->EvtchnInterface,
+                      &Notifier->EvtchnInterface,
                       Notifier->Channel);
 }
 
@@ -329,7 +328,7 @@ NotifierSend(
 {
     if (Notifier->Enabled)
         XENBUS_EVTCHN(Send,
-                      Notifier->EvtchnInterface,
+                      &Notifier->EvtchnInterface,
                       Notifier->Channel);
 }
 
diff --git a/src/xenvbd/pdoinquiry.c b/src/xenvbd/pdoinquiry.c
index c1ca3cb..2608fbf 100644
--- a/src/xenvbd/pdoinquiry.c
+++ b/src/xenvbd/pdoinquiry.c
@@ -211,7 +211,6 @@ fail1:
 
 static FORCEINLINE BOOLEAN
 __HandlePageStd(
-    __in XENVBD_DEVICE_TYPE         DeviceType,
     __in PSCSI_REQUEST_BLOCK        Srb
     )
 {
@@ -221,35 +220,15 @@ __HandlePageStd(
     if (Length < INQUIRYDATABUFFERSIZE)
         return FALSE;
 
-    switch (DeviceType) {
-    case XENVBD_DEVICE_TYPE_DISK:
-        Data->DeviceType            = DIRECT_ACCESS_DEVICE;
-        Data->DeviceTypeQualifier   = DEVICE_CONNECTED;
-        Data->Versions              = 4;
-        Data->ResponseDataFormat    = 2;
-        Data->AdditionalLength      = INQUIRYDATABUFFERSIZE - 4;
-        Data->CommandQueue          = 1;
-        RtlCopyMemory(Data->VendorId,               "XENSRC  ", 8);
-        RtlCopyMemory(Data->ProductId,              "PVDISK          ", 16);
-        RtlCopyMemory(Data->ProductRevisionLevel,   "2.0 ", 4);
-        break;
-    case XENVBD_DEVICE_TYPE_CDROM:
-        Data->DeviceType            = READ_ONLY_DIRECT_ACCESS_DEVICE;
-        Data->DeviceTypeQualifier   = DEVICE_CONNECTED;
-        Data->RemovableMedia        = TRUE;
-        Data->Versions              = 2;
-        Data->ResponseDataFormat    = 2;
-        Data->Wide32Bit             = TRUE;
-        Data->Synchronous           = TRUE;
-        Data->AdditionalLength      = INQUIRYDATABUFFERSIZE - 4;
-        RtlCopyMemory(Data->VendorId,               "XENSRC  ", 8);
-        RtlCopyMemory(Data->ProductId,              "PVCDROM         ", 16);
-        RtlCopyMemory(Data->ProductRevisionLevel,   "2.0 ", 4);
-        break;
-    default:
-        return FALSE;
-        break;
-    }
+    Data->DeviceType            = DIRECT_ACCESS_DEVICE;
+    Data->DeviceTypeQualifier   = DEVICE_CONNECTED;
+    Data->Versions              = 4;
+    Data->ResponseDataFormat    = 2;
+    Data->AdditionalLength      = INQUIRYDATABUFFERSIZE - 4;
+    Data->CommandQueue          = 1;
+    RtlCopyMemory(Data->VendorId,               "XENSRC  ", 8);
+    RtlCopyMemory(Data->ProductId,              "PVDISK          ", 16);
+    RtlCopyMemory(Data->ProductRevisionLevel,   "2.0 ", 4);
 
     Srb->DataTransferLength = INQUIRYDATABUFFERSIZE;
     return TRUE;
@@ -518,8 +497,7 @@ VOID
 PdoInquiry(
     __in ULONG                   TargetId,
     __in PVOID                   Inquiry,
-    __in PSCSI_REQUEST_BLOCK     Srb,
-    __in XENVBD_DEVICE_TYPE      DeviceType
+    __in PSCSI_REQUEST_BLOCK     Srb
     )
 {
     BOOLEAN         Success;
@@ -536,7 +514,7 @@ PdoInquiry(
         }
     } else {
         switch (PageCode) {
-        case 0x00:  Success = __HandlePageStd(DeviceType, Srb);         break;
+        case 0x00:  Success = __HandlePageStd(Srb);                     break;
         default:    Success = FALSE;                                    break;
         }
     }
diff --git a/src/xenvbd/pdoinquiry.h b/src/xenvbd/pdoinquiry.h
index 41d7c30..a8cb155 100644
--- a/src/xenvbd/pdoinquiry.h
+++ b/src/xenvbd/pdoinquiry.h
@@ -57,8 +57,7 @@ extern VOID
 PdoInquiry(
     __in ULONG                   TargetId,
     __in PVOID                   Inquiry,
-    __in PSCSI_REQUEST_BLOCK     Srb,
-    __in XENVBD_DEVICE_TYPE      DeviceType
+    __in PSCSI_REQUEST_BLOCK     Srb
     );
 
 #endif // _XENVBD_PDO_INQUIRY_H
diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c
index 2a48f0a..5764292 100644
--- a/src/xenvbd/target.c
+++ b/src/xenvbd/target.c
@@ -47,6 +47,7 @@
 #include <gnttab_interface.h>
 #include <debug_interface.h>
 #include <suspend_interface.h>
+#include <stdlib.h>
 
 #define XENVBD_MAX_QUEUE_DEPTH          (254)
 
@@ -77,8 +78,6 @@ struct _XENVBD_TARGET {
     ULONG                       Signature;
     PXENVBD_ADAPTER                 Adapter;
     PDEVICE_OBJECT              DeviceObject;
-    KEVENT                      RemoveEvent;
-    LONG                        ReferenceCount;
     DEVICE_PNP_STATE            DevicePnpState;
     DEVICE_PNP_STATE            PrevPnpState;
     DEVICE_POWER_STATE          DevicePowerState;
@@ -86,7 +85,6 @@ struct _XENVBD_TARGET {
 
     // Frontend (Ring, includes XenBus interfaces)
     PXENVBD_FRONTEND            Frontend;
-    XENVBD_DEVICE_TYPE          DeviceType;
 
     // State
     LONG                        Paused;
@@ -274,9 +272,6 @@ TargetDebugCallback(
                  Target->Adapter,
                  Target->DeviceObject);
     XENBUS_DEBUG(Printf, DebugInterface,
-                 "TARGET: ReferenceCount %d\n",
-                 Target->ReferenceCount);
-    XENBUS_DEBUG(Printf, DebugInterface,
                  "TARGET: DevicePnpState %s (%s)\n",
                  __PnpStateName(Target->DevicePnpState),
                  __PnpStateName(Target->PrevPnpState));
@@ -438,57 +433,23 @@ __TargetRestoreDevicePnpState(
 }
 
 //=============================================================================
-// Reference Counting
-FORCEINLINE LONG
-__TargetReference(
-    __in PXENVBD_TARGET             Target,
-    __in PCHAR                   Caller
-    )
-{
-    LONG Result;
-
-    ASSERT3P(Target, !=, NULL);
-    Result = InterlockedIncrement(&Target->ReferenceCount);
-    ASSERTREFCOUNT(Result, >, 0, Caller);
-
-    if (Result == 1) {
-        Result = InterlockedDecrement(&Target->ReferenceCount);
-        Error("Target[%d] : %s: Attempting to take reference of removed TARGET 
from %d\n", TargetGetTargetId(Target), Caller, Result);
-        return 0;
-    } else {
-        ASSERTREFCOUNT(Result, >, 1, Caller);
-        return Result;
-    }
-}
-
-FORCEINLINE LONG
-__TargetDereference(
-    __in PXENVBD_TARGET             Target,
-    __in PCHAR                   Caller
+// Query Methods
+FORCEINLINE ULONG
+TargetGetTargetId(
+    __in PXENVBD_TARGET             Target
     )
 {
-    LONG    Result;
-    
     ASSERT3P(Target, !=, NULL);
-    Result = InterlockedDecrement(&Target->ReferenceCount);
-    ASSERTREFCOUNT(Result, >=, 0, Caller);
-    
-    if (Result == 0) {
-        Verbose("Final ReferenceCount dropped, Target[%d] able to be 
removed\n", TargetGetTargetId(Target));
-        KeSetEvent(&Target->RemoveEvent, IO_NO_INCREMENT, FALSE);
-    }
-    return Result;
+    return FrontendGetTargetId(Target->Frontend);
 }
 
-//=============================================================================
-// Query Methods
-FORCEINLINE ULONG
-TargetGetTargetId(
+ULONG
+TargetGetDeviceId(
     __in PXENVBD_TARGET             Target
     )
 {
     ASSERT3P(Target, !=, NULL);
-    return FrontendGetTargetId(Target->Frontend);
+    return FrontendGetDeviceId(Target->Frontend);
 }
 
 __checkReturn
@@ -835,8 +796,6 @@ __TargetPriority(
     return HighPagePriority;
 }
 
-#define __min(_x, _y) ((_x) < (_y)) ? (_x) : (_y)
-
 static FORCEINLINE VOID
 SGListGet(
     IN OUT  PXENVBD_SG_LIST         SGList
@@ -2101,7 +2060,7 @@ __TargetExecuteScsi(
                                          XENVBD_MAX_QUEUE_DEPTH))
             Verbose("Target[%d] : Failed to set queue depth\n",
                     TargetGetTargetId(Target));
-        PdoInquiry(TargetGetTargetId(Target), 
FrontendGetInquiry(Target->Frontend), Srb, Target->DeviceType);
+        PdoInquiry(TargetGetTargetId(Target), 
FrontendGetInquiry(Target->Frontend), Srb);
         break;
     case SCSIOP_MODE_SENSE:
         TargetModeSense(Target, Srb);
@@ -2485,7 +2444,6 @@ TargetDispatchPnp(
     default:
         break;
     }
-    TargetDereference(Target);
     return DriverDispatchPnp(DeviceObject, Irp);
 }
 
@@ -2587,17 +2545,51 @@ TargetD0ToD3(
     Trace("Target[%d] @ (%d) <=====\n", TargetId, KeGetCurrentIrql());
 }
 
+static FORCEINLINE ULONG
+__ParseVbd(
+    IN  PCHAR   DeviceIdStr
+    )
+{
+    ULONG   DeviceId = strtoul(DeviceIdStr, NULL, 10);
+    
+    ASSERT3U((DeviceId & ~((1 << 29) - 1)), ==, 0);
+
+    if (DeviceId & (1 << 28))
+        return (DeviceId & ((1 << 20) - 1)) >> 8;       /* xvd    */
+
+    switch (DeviceId >> 8) {
+    case 202:   return (DeviceId & 0xF0) >> 4;          /* xvd    */
+    case 8:     return (DeviceId & 0xF0) >> 4;          /* sd     */
+    case 3:     return (DeviceId & 0xC0) >> 6;          /* hda..b */
+    case 22:    return ((DeviceId & 0xC0) >> 6) + 2;    /* hdc..d */
+    case 33:    return ((DeviceId & 0xC0) >> 6) + 4;    /* hde..f */
+    case 34:    return ((DeviceId & 0xC0) >> 6) + 6;    /* hdg..h */
+    case 56:    return ((DeviceId & 0xC0) >> 6) + 8;    /* hdi..j */
+    case 57:    return ((DeviceId & 0xC0) >> 6) + 10;   /* hdk..l */
+    case 88:    return ((DeviceId & 0xC0) >> 6) + 12;   /* hdm..n */
+    case 89:    return ((DeviceId & 0xC0) >> 6) + 14;   /* hdo..p */
+    default:    return 0xFFFFFFFF;                      /* ERROR  */
+    }
+}
+
 __checkReturn
-BOOLEAN
+NTSTATUS
 TargetCreate(
     __in PXENVBD_ADAPTER             Adapter,
     __in __nullterminated PCHAR  DeviceId,
-    __in ULONG                   TargetId,
-    __in XENVBD_DEVICE_TYPE      DeviceType
+    OUT PXENVBD_TARGET*         _Target
     )
 {
     NTSTATUS    Status;
     PXENVBD_TARGET Target;
+    ULONG           TargetId;
+
+    TargetId = __ParseVbd(DeviceId);
+    if (TargetId >= XENVBD_MAX_TARGETS)
+        return STATUS_RETRY;
+
+    if (AdapterIsTargetEmulated(Adapter, TargetId))
+        return STATUS_RETRY;
 
     Trace("Target[%d] @ (%d) =====>\n", TargetId, KeGetCurrentIrql());
 
@@ -2611,12 +2603,9 @@ TargetCreate(
     Target->Signature      = TARGET_SIGNATURE;
     Target->Adapter            = Adapter;
     Target->DeviceObject   = NULL; // filled in later
-    KeInitializeEvent(&Target->RemoveEvent, SynchronizationEvent, FALSE);
-    Target->ReferenceCount = 1;
     Target->Paused         = 1; // Paused until D3->D0 transition
     Target->DevicePnpState = Present;
     Target->DevicePowerState = PowerDeviceD3;
-    Target->DeviceType     = DeviceType;
 
     KeInitializeSpinLock(&Target->Lock);
     QueueInit(&Target->FreshSrbs);
@@ -2635,16 +2624,11 @@ TargetCreate(
     if (!NT_SUCCESS(Status))
         goto fail3;
 
-    if (!AdapterLinkTarget(Adapter, Target))
-        goto fail4;
+    *_Target = Target;
 
     Verbose("Target[%d] : Created (%s)\n", TargetId, Target);
     Trace("Target[%d] @ (%d) <=====\n", TargetId, KeGetCurrentIrql());
-    return TRUE;
-
-fail4:
-    Error("Fail4\n");
-    TargetD0ToD3(Target);
+    return STATUS_SUCCESS;
 
 fail3:
     Error("Fail3\n");
@@ -2660,7 +2644,7 @@ fail2:
 
 fail1:
     Error("Fail1 (%08x)\n", Status);
-    return FALSE;
+    return Status;
 }
 
 VOID
@@ -2669,26 +2653,20 @@ TargetDestroy(
     )
 {
     const ULONG         TargetId = TargetGetTargetId(Target);
-    PVOID               Objects[4];
+    PVOID               Objects[3];
     PKWAIT_BLOCK        WaitBlock;
 
     Trace("Target[%d] @ (%d) =====>\n", TargetId, KeGetCurrentIrql());
     Verbose("Target[%d] : Destroying\n", TargetId);
 
     ASSERT3U(Target->Signature, ==, TARGET_SIGNATURE);
-    if (!AdapterUnlinkTarget(TargetGetAdapter(Target), Target)) {
-        Error("Target[%d] : TARGET 0x%p not linked to ADAPTER 0x%p\n", 
TargetId, Target, TargetGetAdapter(Target));
-    }
 
     TargetD0ToD3(Target);
-    TargetDereference(Target); // drop initial ref count
 
-    // Wait for ReferenceCount == 0 and RequestListUsed == 0
-    Verbose("Target[%d] : ReferenceCount %d, RequestListUsed %d\n", TargetId, 
Target->ReferenceCount, Target->RequestList.Used);
-    Objects[0] = &Target->RemoveEvent;
-    Objects[1] = &Target->RequestList.Empty;
-    Objects[2] = &Target->SegmentList.Empty;
-    Objects[3] = &Target->IndirectList.Empty;
+    Verbose("Target[%d] : RequestListUsed %d\n", TargetId, 
Target->RequestList.Used);
+    Objects[0] = &Target->RequestList.Empty;
+    Objects[1] = &Target->SegmentList.Empty;
+    Objects[2] = &Target->IndirectList.Empty;
 
     WaitBlock = (PKWAIT_BLOCK)__TargetAlloc(sizeof(KWAIT_BLOCK) * 
ARRAYSIZE(Objects));
     if (WaitBlock == NULL) {
@@ -2715,7 +2693,6 @@ TargetDestroy(
         __TargetFree(WaitBlock);
     }
 
-    ASSERT3S(Target->ReferenceCount, ==, 0);
     ASSERT3U(TargetGetDevicePnpState(Target), ==, Deleted);
 
     FrontendDestroy(Target->Frontend);
diff --git a/src/xenvbd/target.h b/src/xenvbd/target.h
index cdbc139..f97c121 100644
--- a/src/xenvbd/target.h
+++ b/src/xenvbd/target.h
@@ -50,12 +50,11 @@ TargetDebugCallback(
 
 // Creation/Deletion
 __checkReturn
-extern BOOLEAN
+extern NTSTATUS
 TargetCreate(
     __in PXENVBD_ADAPTER             Adapter,
     __in __nullterminated PCHAR  DeviceId,
-    __in ULONG                   TargetId,
-    __in XENVBD_DEVICE_TYPE      DeviceType
+    OUT PXENVBD_TARGET*         _Target
     );
 
 extern VOID
@@ -110,29 +109,17 @@ TargetGetDevicePnpState(
     __in PXENVBD_TARGET             Target
     );
 
-// Reference Counting
-extern LONG
-__TargetReference(
-    __in PXENVBD_TARGET             Target,
-    __in PCHAR                   Caller
-    );
-
-#define TargetReference(_x_) __TargetReference(_x_, __FUNCTION__)
-
-extern LONG
-__TargetDereference(
-    __in PXENVBD_TARGET             Target,
-    __in PCHAR                   Caller
-    );
-
-#define TargetDereference(_x_) __TargetDereference(_x_, __FUNCTION__)
-
 // Query Methods
 extern ULONG
 TargetGetTargetId(
     __in PXENVBD_TARGET             Target
     );
 
+extern ULONG
+TargetGetDeviceId(
+    __in PXENVBD_TARGET             Target
+    );
+
 __checkReturn
 extern PDEVICE_OBJECT
 TargetGetDeviceObject(
-- 
2.8.3


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.