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

[win-pv-devel] [PATCH 1/7] Merge Notifier and BlockRing into Ring



From: Owen Smith <owen.smith@xxxxxxxxxx>

Remove the seperation between the event channel and shared ring.
Fixes the debug callback and adds more error messages.

Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
 src/xenvbd/blockring.c       | 597 ----------------------------
 src/xenvbd/blockring.h       |  97 -----
 src/xenvbd/frontend.c        | 129 +++---
 src/xenvbd/frontend.h        |  36 +-
 src/xenvbd/notifier.c        | 390 ------------------
 src/xenvbd/notifier.h        | 101 -----
 src/xenvbd/ring.c            | 911 +++++++++++++++++++++++++++++++++++++++++++
 src/xenvbd/ring.h            | 103 +++++
 src/xenvbd/target.c          |  27 +-
 vs2015/xenvbd/xenvbd.vcxproj |   3 +-
 10 files changed, 1110 insertions(+), 1284 deletions(-)
 delete mode 100644 src/xenvbd/blockring.c
 delete mode 100644 src/xenvbd/blockring.h
 delete mode 100644 src/xenvbd/notifier.c
 delete mode 100644 src/xenvbd/notifier.h
 create mode 100755 src/xenvbd/ring.c
 create mode 100755 src/xenvbd/ring.h

diff --git a/src/xenvbd/blockring.c b/src/xenvbd/blockring.c
deleted file mode 100644
index cf15a6f..0000000
--- a/src/xenvbd/blockring.c
+++ /dev/null
@@ -1,597 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */ 
-
-#include "blockring.h"
-#include "frontend.h"
-#include "target.h"
-#include "adapter.h"
-#include "util.h"
-#include "debug.h"
-#include "srbext.h"
-#include "driver.h"
-#include <stdlib.h>
-#include <xenvbd-ntstrsafe.h>
-
-#define TAG_HEADER                  'gaTX'
-#define XENVBD_MAX_RING_PAGE_ORDER  (4)
-#define XENVBD_MAX_RING_PAGES       (1 << XENVBD_MAX_RING_PAGE_ORDER)
-
-struct _XENVBD_BLOCKRING {
-    PXENVBD_FRONTEND                Frontend;
-    BOOLEAN                         Connected;
-    BOOLEAN                         Enabled;
-
-    XENBUS_STORE_INTERFACE          StoreInterface;
-
-    KSPIN_LOCK                      Lock;
-    PMDL                            Mdl;
-    blkif_sring_t*                  SharedRing;
-    blkif_front_ring_t              FrontRing;
-    ULONG                           DeviceId;
-    ULONG                           Order;
-    PVOID                           Grants[XENVBD_MAX_RING_PAGES];
-    ULONG                           Submitted;
-    ULONG                           Received;
-};
-
-#define MAX_NAME_LEN                64
-#define BLOCKRING_POOL_TAG          'gnRX'
-
-#define XEN_IO_PROTO_ABI    "x86_64-abi"
-
-static FORCEINLINE PVOID
-__BlockRingAllocate(
-    IN  ULONG                       Length
-    )
-{
-    return __AllocatePoolWithTag(NonPagedPool, Length, BLOCKRING_POOL_TAG);
-}
-
-static FORCEINLINE VOID
-__BlockRingFree(
-    IN  PVOID                       Buffer
-    )
-{
-    if (Buffer)
-        __FreePoolWithTag(Buffer, BLOCKRING_POOL_TAG);
-}
-
-static FORCEINLINE VOID
-xen_mb()
-{
-    KeMemoryBarrier();
-    _ReadWriteBarrier();
-}
-
-static FORCEINLINE VOID
-xen_wmb()
-{
-    KeMemoryBarrier();
-    _WriteBarrier();
-}
-
-static FORCEINLINE PFN_NUMBER
-__Pfn(
-    __in  PVOID                   VirtAddr
-    )
-{
-    return (PFN_NUMBER)(ULONG_PTR)(MmGetPhysicalAddress(VirtAddr).QuadPart >> 
PAGE_SHIFT);
-}
-
-static FORCEINLINE ULONG64
-__BlockRingGetTag(
-    IN  PXENVBD_BLOCKRING           BlockRing,
-    IN  PXENVBD_REQUEST             Request
-    )
-{
-    UNREFERENCED_PARAMETER(BlockRing);
-    return ((ULONG64)TAG_HEADER << 32) | (ULONG64)Request->Id;
-}
-
-static FORCEINLINE BOOLEAN
-__BlockRingPutTag(
-    IN  PXENVBD_BLOCKRING           BlockRing,
-    IN  ULONG64                     Id,
-    OUT PULONG                      Tag
-    )
-{
-    ULONG   Header = (ULONG)((Id >> 32) & 0xFFFFFFFF);
-
-    UNREFERENCED_PARAMETER(BlockRing);
-
-    *Tag    = (ULONG)(Id & 0xFFFFFFFF);
-    if (Header != TAG_HEADER) {
-        Error("PUT_TAG (%llx) TAG_HEADER (%08x%08x)\n", Id, Header, *Tag);
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-static FORCEINLINE VOID
-__BlockRingInsert(
-    IN  PXENVBD_BLOCKRING           BlockRing,
-    IN  PXENVBD_REQUEST             Request,
-    IN  blkif_request_t*            req
-    )
-{
-    PXENVBD_GRANTER                 Granter = 
FrontendGetGranter(BlockRing->Frontend);
-
-    switch (Request->Operation) {
-    case BLKIF_OP_READ:
-    case BLKIF_OP_WRITE:
-        if (Request->NrSegments > BLKIF_MAX_SEGMENTS_PER_REQUEST) {
-            // Indirect
-            ULONG                       PageIdx;
-            ULONG                       SegIdx;
-            PLIST_ENTRY                 PageEntry;
-            PLIST_ENTRY                 SegEntry;
-            blkif_request_indirect_t*   req_indirect;
-
-            req_indirect = (blkif_request_indirect_t*)req;
-            req_indirect->operation         = BLKIF_OP_INDIRECT;
-            req_indirect->indirect_op       = Request->Operation;
-            req_indirect->nr_segments       = Request->NrSegments;
-            req_indirect->id                = __BlockRingGetTag(BlockRing, 
Request);
-            req_indirect->sector_number     = Request->FirstSector;
-            req_indirect->handle            = (USHORT)BlockRing->DeviceId;
-
-            for (PageIdx = 0,
-                 PageEntry = Request->Indirects.Flink,
-                 SegEntry = Request->Segments.Flink;
-                    PageIdx < BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST &&
-                    PageEntry != &Request->Indirects &&
-                    SegEntry != &Request->Segments;
-                        ++PageIdx, PageEntry = PageEntry->Flink) {
-                PXENVBD_INDIRECT Page = CONTAINING_RECORD(PageEntry, 
XENVBD_INDIRECT, Entry);
-
-                req_indirect->indirect_grefs[PageIdx] = 
GranterReference(Granter, Page->Grant);
-
-                for (SegIdx = 0;
-                        SegIdx < XENVBD_MAX_SEGMENTS_PER_PAGE &&
-                        SegEntry != &Request->Segments;
-                            ++SegIdx, SegEntry = SegEntry->Flink) {
-                    PXENVBD_SEGMENT Segment = CONTAINING_RECORD(SegEntry, 
XENVBD_SEGMENT, Entry);
-
-                    Page->Page[SegIdx].GrantRef = GranterReference(Granter, 
Segment->Grant);
-                    Page->Page[SegIdx].First    = Segment->FirstSector;
-                    Page->Page[SegIdx].Last     = Segment->LastSector;
-                }
-            }
-        } else {
-            // Direct
-            ULONG           Index;
-            PLIST_ENTRY     Entry;
-
-            req->operation                  = Request->Operation;
-            req->nr_segments                = (UCHAR)Request->NrSegments;
-            req->handle                     = (USHORT)BlockRing->DeviceId;
-            req->id                         = __BlockRingGetTag(BlockRing, 
Request);
-            req->sector_number              = Request->FirstSector;
-
-            for (Index = 0, Entry = Request->Segments.Flink;
-                    Index < BLKIF_MAX_SEGMENTS_PER_REQUEST &&
-                    Entry != &Request->Segments;
-                        ++Index, Entry = Entry->Flink) {
-                PXENVBD_SEGMENT Segment = CONTAINING_RECORD(Entry, 
XENVBD_SEGMENT, Entry);
-                req->seg[Index].gref        = GranterReference(Granter, 
Segment->Grant);
-                req->seg[Index].first_sect  = Segment->FirstSector;
-                req->seg[Index].last_sect   = Segment->LastSector;
-            }
-        }
-        break;
-
-    case BLKIF_OP_WRITE_BARRIER:
-    case BLKIF_OP_FLUSH_DISKCACHE:
-        req->operation                  = Request->Operation;
-        req->nr_segments                = 0;
-        req->handle                     = (USHORT)BlockRing->DeviceId;
-        req->id                         = __BlockRingGetTag(BlockRing, 
Request);
-        req->sector_number              = Request->FirstSector;
-        break;
-
-    case BLKIF_OP_DISCARD: {
-        blkif_request_discard_t*        req_discard;
-        req_discard = (blkif_request_discard_t*)req;
-        req_discard->operation          = BLKIF_OP_DISCARD;
-        req_discard->flag               = Request->Flags;
-        req_discard->handle             = (USHORT)BlockRing->DeviceId;
-        req_discard->id                 = __BlockRingGetTag(BlockRing, 
Request);
-        req_discard->sector_number      = Request->FirstSector;
-        req_discard->nr_sectors         = Request->NrSectors;
-        } break;
-
-    default:
-        ASSERT(FALSE);
-        break;
-    }
-    ++BlockRing->Submitted;
-}
-
-NTSTATUS
-BlockRingCreate(
-    IN  PXENVBD_FRONTEND            Frontend,
-    IN  ULONG                       DeviceId,
-    OUT PXENVBD_BLOCKRING*          BlockRing
-    )
-{
-    *BlockRing = __BlockRingAllocate(sizeof(XENVBD_BLOCKRING));
-    if (*BlockRing == NULL)
-        goto fail1;
-
-    (*BlockRing)->Frontend = Frontend;
-    (*BlockRing)->DeviceId = DeviceId;
-    KeInitializeSpinLock(&(*BlockRing)->Lock);
-
-    return STATUS_SUCCESS;
-
-fail1:
-    return STATUS_NO_MEMORY;
-}
-
-VOID
-BlockRingDestroy(
-    IN  PXENVBD_BLOCKRING           BlockRing
-    )
-{
-    BlockRing->Frontend = NULL;
-    BlockRing->DeviceId = 0;
-    RtlZeroMemory(&BlockRing->Lock, sizeof(KSPIN_LOCK));
-    
-    ASSERT(IsZeroMemory(BlockRing, sizeof(XENVBD_BLOCKRING)));
-    
-    __BlockRingFree(BlockRing);
-}
-
-NTSTATUS
-BlockRingConnect(
-    IN  PXENVBD_BLOCKRING           BlockRing
-    )
-{
-    NTSTATUS        status;
-    PCHAR           Value;
-    ULONG           Index, RingPages;
-    PXENVBD_ADAPTER     Adapter = 
TargetGetAdapter(FrontendGetTarget(BlockRing->Frontend));
-    PXENVBD_GRANTER Granter = FrontendGetGranter(BlockRing->Frontend);
-
-    ASSERT(BlockRing->Connected == FALSE);
-
-    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);
-    if (NT_SUCCESS(status)) {
-        BlockRing->Order = __min(strtoul(Value, NULL, 10), 
XENVBD_MAX_RING_PAGE_ORDER);
-        FrontendStoreFree(BlockRing->Frontend, Value);
-    } else {
-        BlockRing->Order = 0;
-    }
-
-    BlockRing->Mdl = __AllocatePages(1 << BlockRing->Order);
-
-    status = STATUS_NO_MEMORY;
-    if (BlockRing->Mdl == NULL)
-        goto fail2;
-
-    BlockRing->SharedRing = MmGetSystemAddressForMdlSafe(BlockRing->Mdl,
-                                                         NormalPagePriority);
-    ASSERT(BlockRing->SharedRing != NULL);
-
-#pragma warning(push)
-#pragma warning(disable: 4305)
-#pragma warning(disable: 4311)
-    SHARED_RING_INIT(BlockRing->SharedRing);
-    FRONT_RING_INIT(&BlockRing->FrontRing, BlockRing->SharedRing, PAGE_SIZE << 
BlockRing->Order);
-#pragma warning(pop)
-
-    RingPages = (1 << BlockRing->Order);
-    for (Index = 0; Index < RingPages; ++Index) {
-        status = GranterGet(Granter, __Pfn((PUCHAR)BlockRing->SharedRing + 
(Index * PAGE_SIZE)), 
-                                FALSE, &BlockRing->Grants[Index]);
-        if (!NT_SUCCESS(status))
-            goto fail3;
-    }
-
-    BlockRing->Connected = TRUE;
-    return STATUS_SUCCESS;
-
-fail3:
-    for (Index = 0; Index < XENVBD_MAX_RING_PAGES; ++Index) {
-        if (BlockRing->Grants[Index])
-            GranterPut(Granter, BlockRing->Grants[Index]);
-        BlockRing->Grants[Index] = 0;
-    }
-
-    RtlZeroMemory(&BlockRing->FrontRing, sizeof(BlockRing->FrontRing));
-    __FreePages(BlockRing->Mdl);
-    BlockRing->SharedRing = NULL;
-    BlockRing->Mdl = NULL;
-
-fail2:
-fail1:
-    return status;
-}
-
-NTSTATUS
-BlockRingStoreWrite(
-    IN  PXENVBD_BLOCKRING           BlockRing,
-    IN  PXENBUS_STORE_TRANSACTION   Transaction,
-    IN  PCHAR                       FrontendPath
-    )
-{
-    PXENVBD_GRANTER                 Granter = 
FrontendGetGranter(BlockRing->Frontend);
-    NTSTATUS                        status;
-
-    if (BlockRing->Order == 0) {
-        status = XENBUS_STORE(Printf, 
-                              &BlockRing->StoreInterface,
-                              Transaction, 
-                              FrontendPath,
-                              "ring-ref", 
-                              "%u", 
-                              GranterReference(Granter, BlockRing->Grants[0]));
-        if (!NT_SUCCESS(status))
-            return status;
-    } else {
-        ULONG   Index, RingPages;
-
-        status = XENBUS_STORE(Printf, 
-                              &BlockRing->StoreInterface,
-                              Transaction, 
-                              FrontendPath, 
-                              "ring-page-order", 
-                              "%u", 
-                              BlockRing->Order);
-        if (!NT_SUCCESS(status))
-            return status;
-
-        RingPages = (1 << BlockRing->Order);
-        for (Index = 0; Index < RingPages; ++Index) {
-            CHAR    Name[MAX_NAME_LEN+1];
-            status = RtlStringCchPrintfA(Name, MAX_NAME_LEN, "ring-ref%u", 
Index);
-            if (!NT_SUCCESS(status))
-                return status;
-            status = XENBUS_STORE(Printf, 
-                                  &BlockRing->StoreInterface,
-                                  Transaction, 
-                                  FrontendPath,
-                                  Name, 
-                                  "%u", 
-                                  GranterReference(Granter, 
BlockRing->Grants[Index]));
-            if (!NT_SUCCESS(status))
-                return status;
-        }
-    }
-
-    status = XENBUS_STORE(Printf, 
-                          &BlockRing->StoreInterface,
-                          Transaction, 
-                          FrontendPath,
-                          "protocol", 
-                          XEN_IO_PROTO_ABI);
-    if (!NT_SUCCESS(status))
-        return status;
-
-    return STATUS_SUCCESS;
-}
-
-VOID
-BlockRingEnable(
-    IN  PXENVBD_BLOCKRING           BlockRing
-    )
-{
-    ASSERT(BlockRing->Enabled == FALSE);
-
-    BlockRing->Enabled = TRUE;
-}
-
-VOID
-BlockRingDisable(
-    IN  PXENVBD_BLOCKRING           BlockRing
-    )
-{
-    ASSERT(BlockRing->Enabled == TRUE);
-
-    BlockRing->Enabled = FALSE;
-}
-
-VOID
-BlockRingDisconnect(
-    IN  PXENVBD_BLOCKRING           BlockRing
-    )
-{
-    ULONG           Index;
-    PXENVBD_GRANTER Granter = FrontendGetGranter(BlockRing->Frontend);
-
-    ASSERT(BlockRing->Connected == TRUE);
-
-    BlockRing->Submitted = 0;
-    BlockRing->Received = 0;
-
-    for (Index = 0; Index < XENVBD_MAX_RING_PAGES; ++Index) {
-        if (BlockRing->Grants[Index]) {
-            GranterPut(Granter, BlockRing->Grants[Index]);
-        }
-        BlockRing->Grants[Index] = 0;
-    }
-
-    RtlZeroMemory(&BlockRing->FrontRing, sizeof(BlockRing->FrontRing));
-    __FreePages(BlockRing->Mdl);
-    BlockRing->SharedRing = NULL;
-    BlockRing->Mdl = NULL;
-
-    BlockRing->Order = 0;
-
-    XENBUS_STORE(Release, &BlockRing->StoreInterface);
-    RtlZeroMemory(&BlockRing->StoreInterface, sizeof(XENBUS_STORE_INTERFACE));
-
-    BlockRing->Connected = FALSE;
-}
-
-VOID
-BlockRingDebugCallback(
-    IN  PXENVBD_BLOCKRING           BlockRing,
-    IN  PXENBUS_DEBUG_INTERFACE     Debug
-    )
-{
-    ULONG           Index;
-    PXENVBD_GRANTER Granter = FrontendGetGranter(BlockRing->Frontend);
-
-    XENBUS_DEBUG(Printf, Debug,
-                 "BLOCKRING: Requests  : %d / %d\n",
-                 BlockRing->Submitted,
-                 BlockRing->Received);
-
-    XENBUS_DEBUG(Printf, Debug,
-                 "BLOCKRING: SharedRing : 0x%p\n", 
-                 BlockRing->SharedRing);
-
-    if (BlockRing->SharedRing) {
-        XENBUS_DEBUG(Printf, Debug,
-                     "BLOCKRING: SharedRing : %d / %d - %d / %d\n",
-                     BlockRing->SharedRing->req_prod,
-                     BlockRing->SharedRing->req_event,
-                     BlockRing->SharedRing->rsp_prod,
-                     BlockRing->SharedRing->rsp_event);
-    }
-
-    XENBUS_DEBUG(Printf, Debug,
-                 "BLOCKRING: FrontRing  : %d / %d (%d)\n",
-                 BlockRing->FrontRing.req_prod_pvt,
-                 BlockRing->FrontRing.rsp_cons,
-                 BlockRing->FrontRing.nr_ents);
-
-    XENBUS_DEBUG(Printf, Debug,
-                 "BLOCKRING: Order      : %d\n",
-                 BlockRing->Order);
-    for (Index = 0; Index < (1ul << BlockRing->Order); ++Index) {
-        XENBUS_DEBUG(Printf, Debug,
-                     "BLOCKRING: Grants[%-2d] : 0x%p (%u)\n", 
-                     Index,
-                     BlockRing->Grants[Index],
-                     GranterReference(Granter, BlockRing->Grants[Index]));
-    }
-
-    BlockRing->Submitted = BlockRing->Received = 0;
-}
-
-BOOLEAN
-BlockRingPoll(
-    IN  PXENVBD_BLOCKRING           BlockRing
-    )
-{
-    PXENVBD_TARGET Target = FrontendGetTarget(BlockRing->Frontend);
-    BOOLEAN        Retry = FALSE;
-
-    ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
-    KeAcquireSpinLockAtDpcLevel(&BlockRing->Lock);
-
-    // Guard against this locked region being called after the 
-    // lock on FrontendSetState
-    if (BlockRing->Enabled == FALSE)
-        goto done;
-
-    for (;;) {
-        ULONG   rsp_prod;
-        ULONG   rsp_cons;
-
-        KeMemoryBarrier();
-
-        rsp_prod = BlockRing->SharedRing->rsp_prod;
-        rsp_cons = BlockRing->FrontRing.rsp_cons;
-
-        KeMemoryBarrier();
-
-        if (rsp_cons == rsp_prod || Retry)
-            break;
-
-        while (rsp_cons != rsp_prod && !Retry) {
-            blkif_response_t*   Response;
-            ULONG               Tag;
-
-            Response = RING_GET_RESPONSE(&BlockRing->FrontRing, rsp_cons);
-            ++rsp_cons;
-
-            if (__BlockRingPutTag(BlockRing, Response->id, &Tag)) {
-                ++BlockRing->Received;
-                TargetCompleteResponse(Target, Tag, Response->status);
-            }
-
-            RtlZeroMemory(Response, sizeof(union blkif_sring_entry));
-
-            if (rsp_cons - BlockRing->FrontRing.rsp_cons > 
RING_SIZE(&BlockRing->FrontRing) / 4)
-                Retry = TRUE;
-        }
-
-        KeMemoryBarrier();
-
-        BlockRing->FrontRing.rsp_cons = rsp_cons;
-        BlockRing->SharedRing->rsp_event = rsp_cons + 1;
-    }
-
-done:
-    KeReleaseSpinLockFromDpcLevel(&BlockRing->Lock);
-
-    return Retry;
-}
-
-BOOLEAN
-BlockRingSubmit(
-    IN  PXENVBD_BLOCKRING           BlockRing,
-    IN  PXENVBD_REQUEST             Request
-    )
-{
-    KIRQL               Irql;
-    blkif_request_t*    req;
-    BOOLEAN             Notify;
-
-    KeAcquireSpinLock(&BlockRing->Lock, &Irql);
-    if (RING_FULL(&BlockRing->FrontRing)) {
-        KeReleaseSpinLock(&BlockRing->Lock, Irql);
-        return FALSE;
-    }
-
-    req = RING_GET_REQUEST(&BlockRing->FrontRing, 
BlockRing->FrontRing.req_prod_pvt);
-    __BlockRingInsert(BlockRing, Request, req);
-    KeMemoryBarrier();
-    ++BlockRing->FrontRing.req_prod_pvt;
-
-    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&BlockRing->FrontRing, Notify);
-    KeReleaseSpinLock(&BlockRing->Lock, Irql);
-
-    if (Notify)
-        NotifierSend(FrontendGetNotifier(BlockRing->Frontend));
-
-    return TRUE;
-}
diff --git a/src/xenvbd/blockring.h b/src/xenvbd/blockring.h
deleted file mode 100644
index 98fe278..0000000
--- a/src/xenvbd/blockring.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */ 
-
-#ifndef _XENVBD_BLOCKRING_H
-#define _XENVBD_BLOCKRING_H
-
-typedef struct _XENVBD_BLOCKRING XENVBD_BLOCKRING, *PXENVBD_BLOCKRING;
-
-#include "frontend.h"
-#include <debug_interface.h>
-#include <store_interface.h>
-
-extern NTSTATUS
-BlockRingCreate(
-    IN  PXENVBD_FRONTEND            Frontend,
-    IN  ULONG                       DeviceId,
-    OUT PXENVBD_BLOCKRING*          BlockRing
-    );
-
-extern VOID
-BlockRingDestroy(
-    IN  PXENVBD_BLOCKRING           BlockRing
-    );
-
-extern NTSTATUS
-BlockRingConnect(
-    IN  PXENVBD_BLOCKRING           BlockRing
-    );
-
-extern NTSTATUS
-BlockRingStoreWrite(
-    IN  PXENVBD_BLOCKRING           BlockRing,
-    IN  PXENBUS_STORE_TRANSACTION   Transaction,
-    IN  PCHAR                       FrontendPath
-    );
-
-extern VOID
-BlockRingEnable(
-    IN  PXENVBD_BLOCKRING           BlockRing
-    );
-
-extern VOID
-BlockRingDisable(
-    IN  PXENVBD_BLOCKRING           BlockRing
-    );
-
-extern VOID
-BlockRingDisconnect(
-    IN  PXENVBD_BLOCKRING           BlockRing
-    );
-
-extern VOID
-BlockRingDebugCallback(
-    IN  PXENVBD_BLOCKRING           BlockRing,
-    IN  PXENBUS_DEBUG_INTERFACE     Debug
-    );
-
-extern BOOLEAN
-BlockRingPoll(
-    IN  PXENVBD_BLOCKRING           BlockRing
-    );
-
-extern BOOLEAN
-BlockRingSubmit(
-    IN  PXENVBD_BLOCKRING           BlockRing,
-    IN  PXENVBD_REQUEST             Request
-    );
-
-#endif // _XENVBD_BLOCKRING_H
diff --git a/src/xenvbd/frontend.c b/src/xenvbd/frontend.c
index 1e2b026..0b23b70 100644
--- a/src/xenvbd/frontend.c
+++ b/src/xenvbd/frontend.c
@@ -39,8 +39,7 @@
 #include "assert.h"
 #include "util.h"
 #include "names.h"
-#include "notifier.h"
-#include "blockring.h"
+#include "ring.h"
 #include "granter.h"
 #include "thread.h"
 #include <store_interface.h>
@@ -73,8 +72,7 @@ struct _XENVBD_FRONTEND {
     PXENBUS_SUSPEND_CALLBACK    SuspendLateCallback;
 
     // Ring
-    PXENVBD_NOTIFIER            Notifier;
-    PXENVBD_BLOCKRING           BlockRing;
+    PXENVBD_RING                Ring;
     PXENVBD_GRANTER             Granter;
 
     // Backend State Watch
@@ -127,6 +125,38 @@ __FrontendFree(
 
 //=============================================================================
 // Accessors
+ULONG
+FrontendGetDeviceId(
+    IN  PXENVBD_FRONTEND    Frontend
+    )
+{
+    return Frontend->DeviceId;
+}
+
+ULONG
+FrontendGetBackendDomain(
+    IN  PXENVBD_FRONTEND    Frontend
+    )
+{
+    return Frontend->BackendId;
+}
+
+PCHAR
+FrontendGetBackendPath(
+    IN  PXENVBD_FRONTEND    Frontend
+    )
+{
+    return Frontend->BackendPath;
+}
+
+PCHAR
+FrontendGetFrontendPath(
+    IN  PXENVBD_FRONTEND    Frontend
+    )
+{
+    return Frontend->FrontendPath;
+}
+
 VOID
 FrontendRemoveFeature(
     IN  PXENVBD_FRONTEND        Frontend,
@@ -182,13 +212,6 @@ FrontendGetTargetId(
 {
     return Frontend->TargetId;
 }
-ULONG
-FrontendGetDeviceId(
-    __in  PXENVBD_FRONTEND      Frontend
-    )
-{
-     return Frontend->DeviceId;
-}
 PVOID
 FrontendGetInquiry(
     __in  PXENVBD_FRONTEND      Frontend
@@ -203,19 +226,12 @@ FrontendGetTarget(
 {
     return Frontend->Target;
 }
-PXENVBD_BLOCKRING
-FrontendGetBlockRing(
-    __in  PXENVBD_FRONTEND      Frontend
-    )
-{
-    return Frontend->BlockRing;
-}
-PXENVBD_NOTIFIER
-FrontendGetNotifier(
+PXENVBD_RING
+FrontendGetRing(
     __in  PXENVBD_FRONTEND      Frontend
     )
 {
-    return Frontend->Notifier;
+    return Frontend->Ring;
 }
 PXENVBD_GRANTER
 FrontendGetGranter(
@@ -333,7 +349,7 @@ FrontendNotifyResponses(
 {
     BOOLEAN     Retry = FALSE;
 
-    Retry |= BlockRingPoll(Frontend->BlockRing);
+    Retry |= RingPoll(Frontend->Ring);
     Retry |= TargetSubmitRequests(Frontend->Target);
 
     return Retry;
@@ -1146,14 +1162,10 @@ FrontendConnect(
     if (!NT_SUCCESS(Status))
         goto fail1;
 
-    Status = BlockRingConnect(Frontend->BlockRing);
+    Status = RingConnect(Frontend->Ring);
     if (!NT_SUCCESS(Status))
         goto fail2;
 
-    Status = NotifierConnect(Frontend->Notifier, Frontend->BackendId);
-    if (!NT_SUCCESS(Status))
-        goto fail3;
-
     // write evtchn/gnttab details in xenstore
     for (;;) {
         PXENBUS_STORE_TRANSACTION   Transaction;
@@ -1164,11 +1176,7 @@ FrontendConnect(
         if (!NT_SUCCESS(Status))
             break;
 
-        Status = NotifierStoreWrite(Frontend->Notifier, Transaction, 
Frontend->FrontendPath);
-        if (!NT_SUCCESS(Status))
-            goto abort;
-
-        Status = BlockRingStoreWrite(Frontend->BlockRing, Transaction, 
Frontend->FrontendPath);
+        Status = RingStoreWrite(Frontend->Ring, Transaction);
         if (!NT_SUCCESS(Status))
             goto abort;
 
@@ -1223,25 +1231,25 @@ abort:
         break;
     }
     if (!NT_SUCCESS(Status))
-        goto fail4;
+        goto fail3;
 
     // Frontend: -> INITIALIZED
     Status = ___SetState(Frontend, XenbusStateInitialised);
     if (!NT_SUCCESS(Status))
-        goto fail5;
+        goto fail4;
 
     // Backend : -> CONNECTED
     BackendState = XenbusStateUnknown;
     do {
         Status = __WaitState(Frontend, &BackendState);
         if (!NT_SUCCESS(Status))
-            goto fail6;
+            goto fail5;
     } while (BackendState == XenbusStateInitWait ||
              BackendState == XenbusStateInitialising ||
              BackendState == XenbusStateInitialised);
     Status = STATUS_UNSUCCESSFUL;
     if (BackendState != XenbusStateConnected)
-        goto fail7;
+        goto fail6;
 
     // read disk info
     __ReadDiskInfo(Frontend);
@@ -1253,12 +1261,10 @@ abort:
     // Frontend: -> CONNECTED
     Status = ___SetState(Frontend, XenbusStateConnected);
     if (!NT_SUCCESS(Status))
-        goto fail8;
+        goto fail7;
 
     return STATUS_SUCCESS;
 
-fail8:
-    Error("Fail8\n");
 fail7:
     Error("Fail7\n");
 fail6:
@@ -1267,10 +1273,9 @@ fail5:
     Error("Fail5\n");
 fail4:
     Error("Fail4\n");
-    NotifierDisconnect(Frontend->Notifier);
 fail3:
     Error("Fail3\n");
-    BlockRingDisconnect(Frontend->BlockRing);
+    RingDisconnect(Frontend->Ring);
 fail2:
     Error("Fail2\n");
     GranterDisconnect(Frontend->Granter);
@@ -1284,8 +1289,7 @@ FrontendDisconnect(
     __in  PXENVBD_FRONTEND        Frontend
     )
 {
-    NotifierDisconnect(Frontend->Notifier);
-    BlockRingDisconnect(Frontend->BlockRing);
+    RingDisconnect(Frontend->Ring);
     GranterDisconnect(Frontend->Granter);
 }
 __drv_requiresIRQL(DISPATCH_LEVEL)
@@ -1298,8 +1302,7 @@ FrontendEnable(
     KeMemoryBarrier();
 
     GranterEnable(Frontend->Granter);
-    BlockRingEnable(Frontend->BlockRing);
-    NotifierEnable(Frontend->Notifier);
+    RingEnable(Frontend->Ring);
 }
 __drv_requiresIRQL(DISPATCH_LEVEL)
 static FORCEINLINE VOID
@@ -1309,8 +1312,7 @@ FrontendDisable(
 {
     Frontend->Caps.Connected = FALSE;
 
-    NotifierDisable(Frontend->Notifier);
-    BlockRingDisable(Frontend->BlockRing);
+    RingDisable(Frontend->Ring);
     GranterDisable(Frontend->Granter);
 }
 
@@ -1505,7 +1507,7 @@ FrontendSuspendLateCallback(
         ASSERT(FALSE);
     }
 
-    NotifierTrigger(Frontend->Notifier);
+    RingTrigger(Frontend->Ring);
 
     Verbose("Target[%d] : <=== restored %s\n", Frontend->TargetId, 
__XenvbdStateName(Frontend->State));
 }
@@ -1694,21 +1696,17 @@ FrontendCreate(
     if (!NT_SUCCESS(status))
         goto fail3;
 
-    status = NotifierCreate(Frontend, &Frontend->Notifier);
+    status = RingCreate(Frontend, &Frontend->Ring);
     if (!NT_SUCCESS(status))
         goto fail4;
 
-    status = BlockRingCreate(Frontend, Frontend->DeviceId, 
&Frontend->BlockRing);
-    if (!NT_SUCCESS(status))
-        goto fail5;
-
     status = GranterCreate(Frontend, &Frontend->Granter);
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail5;
 
     status = ThreadCreate(FrontendBackend, Frontend, &Frontend->BackendThread);
     if (!NT_SUCCESS(status))
-        goto fail7;
+        goto fail6;
 
     // kernel objects
     KeInitializeSpinLock(&Frontend->StateLock);
@@ -1717,18 +1715,14 @@ FrontendCreate(
     *_Frontend = Frontend;
     return STATUS_SUCCESS;
 
-fail7:
-    Error("fail7\n");
-    GranterDestroy(Frontend->Granter);
-    Frontend->Granter = NULL;
 fail6:
     Error("fail6\n");
-    BlockRingDestroy(Frontend->BlockRing);
-    Frontend->BlockRing = NULL;
+    GranterDestroy(Frontend->Granter);
+    Frontend->Granter = NULL;
 fail5:
     Error("fail5\n");
-    NotifierDestroy(Frontend->Notifier);
-    Frontend->Notifier = NULL;
+    RingDestroy(Frontend->Ring);
+    Frontend->Ring = NULL;
 fail4:
     Error("fail4\n");
 fail3:
@@ -1761,11 +1755,8 @@ FrontendDestroy(
     GranterDestroy(Frontend->Granter);
     Frontend->Granter = NULL;
 
-    BlockRingDestroy(Frontend->BlockRing);
-    Frontend->BlockRing = NULL;
-
-    NotifierDestroy(Frontend->Notifier);
-    Frontend->Notifier = NULL;
+    RingDestroy(Frontend->Ring);
+    Frontend->Ring = NULL;
 
     ASSERT3P(Frontend->BackendPath, ==, NULL);
     ASSERT3P(Frontend->Inquiry, ==, NULL);
@@ -1840,7 +1831,5 @@ FrontendDebugCallback(
                  Frontend->DiskInfo.DiskInfo);
 
     GranterDebugCallback(Frontend->Granter, Debug);
-    BlockRingDebugCallback(Frontend->BlockRing, Debug);
-    NotifierDebugCallback(Frontend->Notifier, Debug);
 }
 
diff --git a/src/xenvbd/frontend.h b/src/xenvbd/frontend.h
index 4490aeb..513ace4 100644
--- a/src/xenvbd/frontend.h
+++ b/src/xenvbd/frontend.h
@@ -74,7 +74,26 @@ typedef struct _XENVBD_DISKINFO {
 
 typedef struct _XENVBD_FRONTEND XENVBD_FRONTEND, *PXENVBD_FRONTEND;
 
-// Accessors
+extern ULONG
+FrontendGetDeviceId(
+    IN  PXENVBD_FRONTEND    Frontend
+    );
+
+extern ULONG
+FrontendGetBackendDomain(
+    IN  PXENVBD_FRONTEND    Frontend
+    );
+
+extern PCHAR
+FrontendGetBackendPath(
+    IN  PXENVBD_FRONTEND    Frontend
+    );
+
+extern PCHAR
+FrontendGetFrontendPath(
+    IN  PXENVBD_FRONTEND    Frontend
+    );
+
 extern VOID
 FrontendRemoveFeature(
     IN  PXENVBD_FRONTEND        Frontend,
@@ -96,10 +115,6 @@ extern ULONG
 FrontendGetTargetId(
     __in  PXENVBD_FRONTEND      Frontend
     );
-extern ULONG
-FrontendGetDeviceId(
-    __in  PXENVBD_FRONTEND      Frontend
-    );
 extern PVOID
 FrontendGetInquiry(
     __in  PXENVBD_FRONTEND      Frontend
@@ -108,14 +123,9 @@ extern PXENVBD_TARGET
 FrontendGetTarget(
     __in  PXENVBD_FRONTEND      Frontend
     );
-#include "blockring.h"
-extern PXENVBD_BLOCKRING
-FrontendGetBlockRing(
-    __in  PXENVBD_FRONTEND      Frontend
-    );
-#include "notifier.h"
-extern PXENVBD_NOTIFIER
-FrontendGetNotifier(
+#include "ring.h"
+extern PXENVBD_RING
+FrontendGetRing(
     __in  PXENVBD_FRONTEND      Frontend
     );
 #include "granter.h"
diff --git a/src/xenvbd/notifier.c b/src/xenvbd/notifier.c
deleted file mode 100644
index 22bfe00..0000000
--- a/src/xenvbd/notifier.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */ 
-
-#include "notifier.h"
-#include "frontend.h"
-#include "target.h"
-#include "adapter.h"
-#include "util.h"
-#include "debug.h"
-#include <evtchn_interface.h>
-
-struct _XENVBD_NOTIFIER {
-    PXENVBD_FRONTEND                Frontend;
-    BOOLEAN                         Connected;
-    BOOLEAN                         Enabled;
-
-    XENBUS_STORE_INTERFACE          StoreInterface;
-    XENBUS_EVTCHN_INTERFACE         EvtchnInterface;
-
-    PXENBUS_EVTCHN_CHANNEL          Channel;
-    ULONG                           Port;
-    ULONG                           NumInts;
-    ULONG                           NumDpcs;
-    KDPC                            Dpc;
-    KDPC                            TimerDpc;
-    KTIMER                          Timer;
-};
-
-#define NOTIFIER_POOL_TAG           'yfNX'
-
-static FORCEINLINE PVOID
-__NotifierAllocate(
-    IN  ULONG                       Length
-    )
-{
-    return __AllocatePoolWithTag(NonPagedPool, Length, NOTIFIER_POOL_TAG);
-}
-
-static FORCEINLINE VOID
-__NotifierFree(
-    IN  PVOID                       Buffer
-    )
-{
-    if (Buffer)
-        __FreePoolWithTag(Buffer, NOTIFIER_POOL_TAG);
-}
-
-KSERVICE_ROUTINE NotifierInterrupt;
-
-BOOLEAN
-NotifierInterrupt(
-    __in  PKINTERRUPT               Interrupt,
-    _In_opt_ PVOID                  Context
-    )
-{
-    PXENVBD_NOTIFIER    Notifier = Context;
-    
-    UNREFERENCED_PARAMETER(Interrupt);
-
-    ASSERT(Notifier != NULL);
-
-       ++Notifier->NumInts;
-       if (Notifier->Connected) {
-               if (KeInsertQueueDpc(&Notifier->Dpc, NULL, NULL)) {
-                       ++Notifier->NumDpcs;
-        }
-       }
-
-    return TRUE;
-}
-
-static FORCEINLINE BOOLEAN
-__NotifierDpcTimeout(
-    IN  PXENVBD_NOTIFIER        Notifier
-    )
-{
-    KDPC_WATCHDOG_INFORMATION   Watchdog;
-    NTSTATUS                    status;
-
-    UNREFERENCED_PARAMETER(Notifier);
-
-    RtlZeroMemory(&Watchdog, sizeof (Watchdog));
-
-    status = KeQueryDpcWatchdogInformation(&Watchdog);
-    ASSERT(NT_SUCCESS(status));
-
-    if (Watchdog.DpcTimeLimit == 0 ||
-        Watchdog.DpcWatchdogLimit == 0)
-        return FALSE;
-
-    if (Watchdog.DpcTimeCount > (Watchdog.DpcTimeLimit / 2) &&
-        Watchdog.DpcWatchdogCount > (Watchdog.DpcWatchdogLimit / 2))
-        return FALSE;
-
-    return TRUE;
-}
-
-#define TIME_US(_us)        ((_us) * 10)
-#define TIME_MS(_ms)        (TIME_US((_ms) * 1000))
-#define TIME_S(_s)          (TIME_MS((_s) * 1000))
-#define TIME_RELATIVE(_t)   (-(_t))
-
-KDEFERRED_ROUTINE NotifierDpc;
-
-VOID 
-NotifierDpc(
-    __in  PKDPC                     Dpc,
-    __in_opt PVOID                  Context,
-    __in_opt PVOID                  Arg1,
-    __in_opt PVOID                  Arg2
-    )
-{
-    PXENVBD_NOTIFIER    Notifier = Context;
-
-    UNREFERENCED_PARAMETER(Dpc);
-    UNREFERENCED_PARAMETER(Arg1);
-    UNREFERENCED_PARAMETER(Arg2);
-
-    ASSERT(Notifier != NULL);
-
-    if (!Notifier->Connected)
-        return;
-
-    for (;;) {
-        if (!FrontendNotifyResponses(Notifier->Frontend)) {
-            XENBUS_EVTCHN(Unmask,
-                          &Notifier->EvtchnInterface,
-                          Notifier->Channel,
-                          FALSE);
-            break;
-        }
-        if (__NotifierDpcTimeout(Notifier)) {
-            LARGE_INTEGER   Delay;
-
-            Delay.QuadPart = TIME_RELATIVE(TIME_US(100));
-
-            KeSetTimer(&Notifier->Timer,
-                       Delay,
-                       &Notifier->TimerDpc);
-            break;
-        }
-    }
-}
-
-NTSTATUS
-NotifierCreate(
-    IN  PXENVBD_FRONTEND            Frontend,
-    OUT PXENVBD_NOTIFIER*           Notifier
-    )
-{
-    *Notifier = __NotifierAllocate(sizeof(XENVBD_NOTIFIER));
-    if (*Notifier == NULL)
-        goto fail1;
-
-    (*Notifier)->Frontend = Frontend;
-    KeInitializeDpc(&(*Notifier)->Dpc, NotifierDpc, *Notifier);
-    KeInitializeDpc(&(*Notifier)->TimerDpc, NotifierDpc, *Notifier);
-    KeInitializeTimer(&(*Notifier)->Timer);
-
-    return STATUS_SUCCESS;
-
-fail1:
-    return STATUS_NO_MEMORY;
-}
-
-VOID
-NotifierDestroy(
-    IN  PXENVBD_NOTIFIER            Notifier
-    )
-{
-    Notifier->Frontend = NULL;
-    RtlZeroMemory(&Notifier->Dpc, sizeof(KDPC));
-    RtlZeroMemory(&Notifier->TimerDpc, sizeof(KDPC));
-    RtlZeroMemory(&Notifier->Timer, sizeof(KTIMER));
-
-    ASSERT(IsZeroMemory(Notifier, sizeof(XENVBD_NOTIFIER)));
-    
-    __NotifierFree(Notifier);
-}
-
-NTSTATUS
-NotifierConnect(
-    IN  PXENVBD_NOTIFIER            Notifier,
-    IN  USHORT                      BackendDomain
-    )
-{
-    PXENVBD_ADAPTER Adapter = 
TargetGetAdapter(FrontendGetTarget(Notifier->Frontend));
-    NTSTATUS    status;
-
-    ASSERT(Notifier->Connected == FALSE);
-
-    AdapterGetStoreInterface(Adapter, &Notifier->StoreInterface);
-    AdapterGetEvtchnInterface(Adapter, &Notifier->EvtchnInterface);
-
-    status = XENBUS_STORE(Acquire, &Notifier->StoreInterface);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = XENBUS_EVTCHN(Acquire, &Notifier->EvtchnInterface);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    Notifier->Channel = XENBUS_EVTCHN(Open, 
-                                      &Notifier->EvtchnInterface,
-                                      XENBUS_EVTCHN_TYPE_UNBOUND, 
-                                      NotifierInterrupt,
-                                      Notifier, 
-                                      BackendDomain, 
-                                      TRUE);
-
-    status = STATUS_NO_MEMORY;
-    if (Notifier->Channel == NULL)
-        goto fail3;
-
-    Notifier->Port = XENBUS_EVTCHN(GetPort,
-                                   &Notifier->EvtchnInterface,
-                                   Notifier->Channel);
-
-    XENBUS_EVTCHN(Unmask,
-                  &Notifier->EvtchnInterface,
-                  Notifier->Channel,
-                  FALSE);
-
-    Notifier->Connected = TRUE;
-    return STATUS_SUCCESS;
-
-fail3:
-    XENBUS_EVTCHN(Release, &Notifier->EvtchnInterface);
-    RtlZeroMemory(&Notifier->EvtchnInterface, sizeof(XENBUS_EVTCHN_INTERFACE));
-
-fail2:
-    XENBUS_STORE(Release, &Notifier->StoreInterface);
-    RtlZeroMemory(&Notifier->StoreInterface, sizeof(XENBUS_STORE_INTERFACE));
-
-fail1:
-    return status;
-}
-
-NTSTATUS
-NotifierStoreWrite(
-    IN  PXENVBD_NOTIFIER            Notifier,
-    IN  PXENBUS_STORE_TRANSACTION   Transaction,
-    IN  PCHAR                       FrontendPath
-    )
-{
-    return XENBUS_STORE(Printf, 
-                        &Notifier->StoreInterface,
-                        Transaction, 
-                        FrontendPath, 
-                        "event-channel", 
-                        "%u", 
-                        Notifier->Port);
-}
-
-VOID
-NotifierEnable(
-    IN  PXENVBD_NOTIFIER            Notifier
-    )
-{
-    ASSERT(Notifier->Enabled == FALSE);
-
-    XENBUS_EVTCHN(Trigger,
-                  &Notifier->EvtchnInterface,
-                  Notifier->Channel);
-
-    Notifier->Enabled = TRUE;
-}
-
-VOID
-NotifierDisable(
-    IN  PXENVBD_NOTIFIER            Notifier
-    )
-{
-    ASSERT(Notifier->Enabled == TRUE);
-
-    Notifier->Enabled = FALSE;
-
-    //
-    // No new timers can be scheduled once Enabled goes to FALSE.
-    // Cancel any existing ones.
-    //
-    (VOID) KeCancelTimer(&Notifier->Timer);
-}
-
-VOID
-NotifierDisconnect(
-    IN  PXENVBD_NOTIFIER            Notifier
-    )
-{
-    ASSERT(Notifier->Connected == TRUE);
-
-    XENBUS_EVTCHN(Close,
-                  &Notifier->EvtchnInterface,
-                  Notifier->Channel);
-    Notifier->Channel = NULL;
-    Notifier->Port = 0;
-
-    XENBUS_EVTCHN(Release, &Notifier->EvtchnInterface);
-    RtlZeroMemory(&Notifier->EvtchnInterface, sizeof(XENBUS_EVTCHN_INTERFACE));
-
-    XENBUS_STORE(Release, &Notifier->StoreInterface);
-    RtlZeroMemory(&Notifier->StoreInterface, sizeof(XENBUS_STORE_INTERFACE));
-
-    Notifier->NumInts = Notifier->NumDpcs = 0;
-
-    Notifier->Connected = FALSE;
-}
-
-VOID
-NotifierDebugCallback(
-    IN  PXENVBD_NOTIFIER            Notifier,
-    IN  PXENBUS_DEBUG_INTERFACE     Debug
-    )
-{
-    XENBUS_DEBUG(Printf, Debug,
-                 "NOTIFIER: Int / DPC : %d / %d\n",
-                 Notifier->NumInts, Notifier->NumDpcs);
-
-    if (Notifier->Channel) {
-        XENBUS_DEBUG(Printf, Debug,
-                     "NOTIFIER: Channel : %p (%d)\n", 
-                     Notifier->Channel, Notifier->Port);
-    }
-
-    Notifier->NumInts = 0;
-    Notifier->NumDpcs = 0;
-}
-
-VOID
-NotifierKick(
-    IN  PXENVBD_NOTIFIER            Notifier
-    )
-{
-    if (Notifier->Enabled) {
-               if (KeInsertQueueDpc(&Notifier->Dpc, NULL, NULL)) {
-                       ++Notifier->NumDpcs;
-        }
-    }
-}
-
-VOID
-NotifierTrigger(
-    IN  PXENVBD_NOTIFIER            Notifier
-    )
-{
-    if (Notifier->Enabled)
-        XENBUS_EVTCHN(Trigger,
-                      &Notifier->EvtchnInterface,
-                      Notifier->Channel);
-}
-
-VOID
-NotifierSend(
-    IN  PXENVBD_NOTIFIER            Notifier
-    )
-{
-    if (Notifier->Enabled)
-        XENBUS_EVTCHN(Send,
-                      &Notifier->EvtchnInterface,
-                      Notifier->Channel);
-}
-
diff --git a/src/xenvbd/notifier.h b/src/xenvbd/notifier.h
deleted file mode 100644
index 4cf35e7..0000000
--- a/src/xenvbd/notifier.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */ 
-
-#ifndef _XENVBD_NOTIFIER_H
-#define _XENVBD_NOTIFIER_H
-
-typedef struct _XENVBD_NOTIFIER XENVBD_NOTIFIER, *PXENVBD_NOTIFIER;
-
-#include "frontend.h"
-#include <debug_interface.h>
-#include <store_interface.h>
-
-extern NTSTATUS
-NotifierCreate(
-    IN  PXENVBD_FRONTEND            Frontend,
-    OUT PXENVBD_NOTIFIER*           Notifier
-    );
-
-extern VOID
-NotifierDestroy(
-    IN  PXENVBD_NOTIFIER            Notifier
-    );
-
-extern NTSTATUS
-NotifierConnect(
-    IN  PXENVBD_NOTIFIER            Notifier,
-    IN  USHORT                      BackendDomain
-    );
-
-extern NTSTATUS
-NotifierStoreWrite(
-    IN  PXENVBD_NOTIFIER            Notifier,
-    IN  PXENBUS_STORE_TRANSACTION   Transaction,
-    IN  PCHAR                       FrontendPath
-    );
-
-extern VOID
-NotifierEnable(
-    IN  PXENVBD_NOTIFIER            Notifier
-    );
-
-extern VOID
-NotifierDisable(
-    IN  PXENVBD_NOTIFIER            Notifier
-    );
-
-extern VOID
-NotifierDisconnect(
-    IN  PXENVBD_NOTIFIER            Notifier
-    );
-
-extern VOID
-NotifierDebugCallback(
-    IN  PXENVBD_NOTIFIER            Notifier,
-    IN  PXENBUS_DEBUG_INTERFACE     Debug
-    );
-
-extern VOID
-NotifierKick(
-    IN  PXENVBD_NOTIFIER            Notifier
-    );
-
-extern VOID
-NotifierTrigger(
-    IN  PXENVBD_NOTIFIER            Notifier
-    );
-
-extern VOID
-NotifierSend(
-    IN  PXENVBD_NOTIFIER            Notifier
-    );
-
-#endif // _XENVBD_NOTIFIER_H
diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
new file mode 100755
index 0000000..eb5fcc7
--- /dev/null
+++ b/src/xenvbd/ring.c
@@ -0,0 +1,911 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */ 
+
+#include <ntddk.h>
+#include <stdlib.h>
+#include <ntstrsafe.h>
+
+#include <store_interface.h>
+#include <evtchn_interface.h>
+#include <debug_interface.h>
+
+#include "ring.h"
+#include "frontend.h"
+#include "target.h"
+#include "adapter.h"
+#include "srbext.h"
+#include "driver.h"
+#include "granter.h"
+
+#include "util.h"
+#include "debug.h"
+#include "assert.h"
+
+#define TAG_HEADER                  'gaTX'
+#define XENVBD_MAX_RING_PAGE_ORDER  (4)
+#define XENVBD_MAX_RING_PAGES       (1 << XENVBD_MAX_RING_PAGE_ORDER)
+
+struct _XENVBD_RING {
+    PXENVBD_FRONTEND                Frontend;
+    BOOLEAN                         Connected;
+    BOOLEAN                         Enabled;
+
+    XENBUS_STORE_INTERFACE          StoreInterface;
+    XENBUS_EVTCHN_INTERFACE         EvtchnInterface;
+    XENBUS_DEBUG_INTERFACE          DebugInterface;
+
+    PXENBUS_DEBUG_CALLBACK          DebugCallback;
+
+    KSPIN_LOCK                      Lock;
+    PMDL                            Mdl;
+    blkif_sring_t*                  Shared;
+    blkif_front_ring_t              Front;
+    ULONG                           Order;
+    PVOID                           Grants[XENVBD_MAX_RING_PAGES];
+    PXENBUS_EVTCHN_CHANNEL          Channel;
+    KDPC                            Dpc;
+    KDPC                            TimerDpc;
+    KTIMER                          Timer;
+
+    ULONG                           Submitted;
+    ULONG                           Received;
+    ULONG                           Events;
+    ULONG                           Dpcs;
+};
+
+#define MAX_NAME_LEN                64
+#define RING_POOL_TAG               'gnRX'
+#define XEN_IO_PROTO_ABI            "x86_64-abi"
+
+static FORCEINLINE PVOID
+__RingAllocate(
+    IN  ULONG                       Length
+    )
+{
+    return __AllocatePoolWithTag(NonPagedPool,
+                                 Length,
+                                 RING_POOL_TAG);
+}
+
+static FORCEINLINE VOID
+__RingFree(
+    IN  PVOID                       Buffer
+    )
+{
+    if (Buffer)
+        __FreePoolWithTag(Buffer,
+                          RING_POOL_TAG);
+}
+
+static FORCEINLINE VOID
+xen_mb()
+{
+    KeMemoryBarrier();
+    _ReadWriteBarrier();
+}
+
+static FORCEINLINE VOID
+xen_wmb()
+{
+    KeMemoryBarrier();
+    _WriteBarrier();
+}
+
+static FORCEINLINE PFN_NUMBER
+__Pfn(
+    __in  PVOID                   VirtAddr
+    )
+{
+    return (PFN_NUMBER)(ULONG_PTR)(MmGetPhysicalAddress(VirtAddr).QuadPart >> 
PAGE_SHIFT);
+}
+
+static FORCEINLINE ULONG64
+__RingGetTag(
+    IN  PXENVBD_RING    Ring,
+    IN  PXENVBD_REQUEST Request
+    )
+{
+    UNREFERENCED_PARAMETER(Ring);
+    return ((ULONG64)TAG_HEADER << 32) | (ULONG64)Request->Id;
+}
+
+static FORCEINLINE BOOLEAN
+__RingPutTag(
+    IN  PXENVBD_RING    Ring,
+    IN  ULONG64         Id,
+    OUT PULONG          Tag
+    )
+{
+    ULONG   Header = (ULONG)((Id >> 32) & 0xFFFFFFFF);
+
+    UNREFERENCED_PARAMETER(Ring);
+
+    *Tag    = (ULONG)(Id & 0xFFFFFFFF);
+    if (Header != TAG_HEADER) {
+        Error("PUT_TAG (%llx) TAG_HEADER (%08x%08x)\n", Id, Header, *Tag);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static FORCEINLINE VOID
+__RingInsert(
+    IN  PXENVBD_RING        Ring,
+    IN  PXENVBD_REQUEST     Request,
+    IN  blkif_request_t*    req
+    )
+{
+    PXENVBD_GRANTER         Granter = FrontendGetGranter(Ring->Frontend);
+
+    switch (Request->Operation) {
+    case BLKIF_OP_READ:
+    case BLKIF_OP_WRITE:
+        if (Request->NrSegments > BLKIF_MAX_SEGMENTS_PER_REQUEST) {
+            // Indirect
+            ULONG                       PageIdx;
+            ULONG                       SegIdx;
+            PLIST_ENTRY                 PageEntry;
+            PLIST_ENTRY                 SegEntry;
+            blkif_request_indirect_t*   req_indirect;
+
+            req_indirect = (blkif_request_indirect_t*)req;
+            req_indirect->operation         = BLKIF_OP_INDIRECT;
+            req_indirect->indirect_op       = Request->Operation;
+            req_indirect->nr_segments       = Request->NrSegments;
+            req_indirect->id                = __RingGetTag(Ring, Request);
+            req_indirect->sector_number     = Request->FirstSector;
+            req_indirect->handle            = 
(USHORT)FrontendGetDeviceId(Ring->Frontend);
+
+            for (PageIdx = 0,
+                 PageEntry = Request->Indirects.Flink,
+                 SegEntry = Request->Segments.Flink;
+                    PageIdx < BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST &&
+                    PageEntry != &Request->Indirects &&
+                    SegEntry != &Request->Segments;
+                        ++PageIdx, PageEntry = PageEntry->Flink) {
+                PXENVBD_INDIRECT Page = CONTAINING_RECORD(PageEntry, 
XENVBD_INDIRECT, Entry);
+
+                req_indirect->indirect_grefs[PageIdx] = 
GranterReference(Granter, Page->Grant);
+
+                for (SegIdx = 0;
+                        SegIdx < XENVBD_MAX_SEGMENTS_PER_PAGE &&
+                        SegEntry != &Request->Segments;
+                            ++SegIdx, SegEntry = SegEntry->Flink) {
+                    PXENVBD_SEGMENT Segment = CONTAINING_RECORD(SegEntry, 
XENVBD_SEGMENT, Entry);
+
+                    Page->Page[SegIdx].GrantRef = GranterReference(Granter, 
Segment->Grant);
+                    Page->Page[SegIdx].First    = Segment->FirstSector;
+                    Page->Page[SegIdx].Last     = Segment->LastSector;
+                }
+            }
+        } else {
+            // Direct
+            ULONG           Index;
+            PLIST_ENTRY     Entry;
+
+            req->operation                  = Request->Operation;
+            req->nr_segments                = (UCHAR)Request->NrSegments;
+            req->handle                     = 
(USHORT)FrontendGetDeviceId(Ring->Frontend);
+            req->id                         = __RingGetTag(Ring, Request);
+            req->sector_number              = Request->FirstSector;
+
+            for (Index = 0, Entry = Request->Segments.Flink;
+                    Index < BLKIF_MAX_SEGMENTS_PER_REQUEST &&
+                    Entry != &Request->Segments;
+                        ++Index, Entry = Entry->Flink) {
+                PXENVBD_SEGMENT Segment = CONTAINING_RECORD(Entry, 
XENVBD_SEGMENT, Entry);
+                req->seg[Index].gref        = GranterReference(Granter, 
Segment->Grant);
+                req->seg[Index].first_sect  = Segment->FirstSector;
+                req->seg[Index].last_sect   = Segment->LastSector;
+            }
+        }
+        break;
+
+    case BLKIF_OP_WRITE_BARRIER:
+    case BLKIF_OP_FLUSH_DISKCACHE:
+        req->operation                  = Request->Operation;
+        req->nr_segments                = 0;
+        req->handle                     = 
(USHORT)FrontendGetDeviceId(Ring->Frontend);
+        req->id                         = __RingGetTag(Ring, Request);
+        req->sector_number              = Request->FirstSector;
+        break;
+
+    case BLKIF_OP_DISCARD: {
+        blkif_request_discard_t*        req_discard;
+        req_discard = (blkif_request_discard_t*)req;
+        req_discard->operation          = BLKIF_OP_DISCARD;
+        req_discard->flag               = Request->Flags;
+        req_discard->handle             = 
(USHORT)FrontendGetDeviceId(Ring->Frontend);
+        req_discard->id                 = __RingGetTag(Ring, Request);
+        req_discard->sector_number      = Request->FirstSector;
+        req_discard->nr_sectors         = Request->NrSectors;
+        } break;
+
+    default:
+        ASSERT(FALSE);
+        break;
+    }
+    ++Ring->Submitted;
+}
+
+KSERVICE_ROUTINE    RingInterrupt;
+
+BOOLEAN
+RingInterrupt(
+    IN  PKINTERRUPT Interrupt,
+    IN  PVOID       Context
+    )
+{
+    PXENVBD_RING    Ring = Context;
+
+    UNREFERENCED_PARAMETER(Interrupt);
+
+    ASSERT(Ring != NULL);
+
+    ++Ring->Events;
+    if (!Ring->Connected)
+        return TRUE;
+
+    if (KeInsertQueueDpc(&Ring->Dpc, NULL, NULL))
+        ++Ring->Dpcs;
+
+    return TRUE;
+}
+
+static FORCEINLINE BOOLEAN
+__RingDpcTimeout(
+    IN  PXENVBD_RING            Ring
+    )
+{
+    KDPC_WATCHDOG_INFORMATION   Watchdog;
+    NTSTATUS                    status;
+
+    UNREFERENCED_PARAMETER(Ring);
+
+    RtlZeroMemory(&Watchdog, sizeof (Watchdog));
+
+    status = KeQueryDpcWatchdogInformation(&Watchdog);
+    ASSERT(NT_SUCCESS(status));
+
+    if (Watchdog.DpcTimeLimit == 0 ||
+        Watchdog.DpcWatchdogLimit == 0)
+        return FALSE;
+
+    if (Watchdog.DpcTimeCount > (Watchdog.DpcTimeLimit / 2) &&
+        Watchdog.DpcWatchdogCount > (Watchdog.DpcWatchdogLimit / 2))
+        return FALSE;
+
+    return TRUE;
+}
+
+#define TIME_US(_us)        ((_us) * 10)
+#define TIME_MS(_ms)        (TIME_US((_ms) * 1000))
+#define TIME_S(_s)          (TIME_MS((_s) * 1000))
+#define TIME_RELATIVE(_t)   (-(_t))
+
+KDEFERRED_ROUTINE RingDpc;
+
+VOID 
+RingDpc(
+    __in  PKDPC     Dpc,
+    __in_opt PVOID  Context,
+    __in_opt PVOID  Arg1,
+    __in_opt PVOID  Arg2
+    )
+{
+    PXENVBD_RING    Ring = Context;
+
+    UNREFERENCED_PARAMETER(Dpc);
+    UNREFERENCED_PARAMETER(Arg1);
+    UNREFERENCED_PARAMETER(Arg2);
+
+    ASSERT(Ring != NULL);
+
+    if (!Ring->Connected)
+        return;
+
+    for (;;) {
+        if (!FrontendNotifyResponses(Ring->Frontend)) {
+            XENBUS_EVTCHN(Unmask,
+                          &Ring->EvtchnInterface,
+                          Ring->Channel,
+                          FALSE);
+            break;
+        }
+        if (__RingDpcTimeout(Ring)) {
+            LARGE_INTEGER   Delay;
+
+            Delay.QuadPart = TIME_RELATIVE(TIME_US(100));
+
+            KeSetTimer(&Ring->Timer,
+                       Delay,
+                       &Ring->TimerDpc);
+            break;
+        }
+    }
+}
+
+static DECLSPEC_NOINLINE VOID
+RingDebugCallback(
+    IN  PVOID       Argument,
+    IN  BOOLEAN     Crashing
+    )
+{
+    PXENVBD_RING    Ring = Argument;
+    PXENVBD_GRANTER Granter = FrontendGetGranter(Ring->Frontend);
+    ULONG           Index;
+
+    UNREFERENCED_PARAMETER(Crashing);
+
+    XENBUS_DEBUG(Printf,
+                 &Ring->DebugInterface,
+                 "Submitted: %u Received: %u\n",
+                 Ring->Submitted,
+                 Ring->Received);
+
+    XENBUS_DEBUG(Printf,
+                 &Ring->DebugInterface,
+                 "Events: %u Dpcs: %u\n",
+                 Ring->Events, 
+                 Ring->Dpcs);
+
+    XENBUS_DEBUG(Printf,
+                 &Ring->DebugInterface,
+                 "Shared : 0x%p\n", 
+                 Ring->Shared);
+
+    if (Ring->Shared) {
+        XENBUS_DEBUG(Printf,
+                     &Ring->DebugInterface,
+                     "Shared: %d / %d - %d / %d\n",
+                     Ring->Shared->req_prod,
+                     Ring->Shared->req_event,
+                     Ring->Shared->rsp_prod,
+                     Ring->Shared->rsp_event);
+    }
+
+    XENBUS_DEBUG(Printf,
+                 &Ring->DebugInterface,
+                 "Front: %d / %d (%d)\n",
+                 Ring->Front.req_prod_pvt,
+                 Ring->Front.rsp_cons,
+                 Ring->Front.nr_ents);
+
+    XENBUS_DEBUG(Printf,
+                 &Ring->DebugInterface,
+                 "Order: %d\n",
+                 Ring->Order);
+
+    for (Index = 0; Index < (1ul << Ring->Order); ++Index) {
+        XENBUS_DEBUG(Printf,
+                     &Ring->DebugInterface,
+                     "Grants[%-2d]: 0x%p (%u)\n", 
+                     Index,
+                     Ring->Grants[Index],
+                     GranterReference(Granter, Ring->Grants[Index]));
+    }
+
+    if (Ring->Channel) {
+        ULONG       Port = XENBUS_EVTCHN(GetPort,
+                                         &Ring->EvtchnInterface,
+                                         Ring->Channel);
+
+        XENBUS_DEBUG(Printf,
+                     &Ring->DebugInterface,
+                     "Channel : %p (%d)\n", 
+                     Ring->Channel,
+                     Port);
+    }
+}
+
+NTSTATUS
+RingCreate(
+    IN  PXENVBD_FRONTEND    Frontend,
+    OUT PXENVBD_RING*       Ring
+    )
+{
+    NTSTATUS                status;
+
+    *Ring = __RingAllocate(sizeof(XENVBD_RING));
+
+    status = STATUS_NO_MEMORY;
+    if (*Ring == NULL)
+        goto fail1;
+
+    (*Ring)->Frontend = Frontend;
+    KeInitializeSpinLock(&(*Ring)->Lock);
+    KeInitializeDpc(&(*Ring)->Dpc, RingDpc, *Ring);
+    KeInitializeDpc(&(*Ring)->TimerDpc, RingDpc, *Ring);
+    KeInitializeTimer(&(*Ring)->Timer);
+
+    return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 %08x\n", status);
+    return status;
+}
+
+VOID
+RingDestroy(
+    IN  PXENVBD_RING    Ring
+    )
+{
+    RtlZeroMemory(&Ring->Timer, sizeof(KTIMER));
+    RtlZeroMemory(&Ring->TimerDpc, sizeof(KDPC));
+    RtlZeroMemory(&Ring->Dpc, sizeof(KDPC));
+    RtlZeroMemory(&Ring->Lock, sizeof(KSPIN_LOCK));
+    Ring->Frontend = NULL;
+
+    ASSERT(IsZeroMemory(Ring, sizeof(XENVBD_RING)));
+    __RingFree(Ring);
+}
+
+NTSTATUS
+RingConnect(
+    IN  PXENVBD_RING    Ring
+    )
+{
+    PXENVBD_TARGET      Target = FrontendGetTarget(Ring->Frontend);
+    PXENVBD_ADAPTER     Adapter = TargetGetAdapter(Target);
+    PXENVBD_GRANTER     Granter = FrontendGetGranter(Ring->Frontend);
+    PCHAR               Buffer;
+    ULONG               Index;
+    NTSTATUS            status;
+
+    ASSERT(Ring->Connected == FALSE);
+
+    AdapterGetStoreInterface(Adapter, &Ring->StoreInterface);
+    AdapterGetEvtchnInterface(Adapter, &Ring->EvtchnInterface);
+    AdapterGetDebugInterface(Adapter, &Ring->DebugInterface);
+
+    status = XENBUS_STORE(Acquire, &Ring->StoreInterface);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = XENBUS_EVTCHN(Acquire, &Ring->EvtchnInterface);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    status = XENBUS_DEBUG(Acquire, &Ring->DebugInterface);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    status = XENBUS_STORE(Read,
+                          &Ring->StoreInterface,
+                          NULL,
+                          FrontendGetBackendPath(Ring->Frontend),
+                          "max-ring-page-order",
+                          &Buffer);
+    if (NT_SUCCESS(status)) {
+        Ring->Order = strtoul(Buffer, NULL, 10);
+        if (Ring->Order > XENVBD_MAX_RING_PAGE_ORDER)
+            Ring->Order = XENVBD_MAX_RING_PAGE_ORDER;
+
+        XENBUS_STORE(Free,
+                     &Ring->StoreInterface,
+                     Buffer);
+    } else {
+        Ring->Order = 0;
+    }
+                          
+    Ring->Mdl = __AllocatePages(1 << Ring->Order);
+
+    status = STATUS_NO_MEMORY;
+    if (Ring->Mdl == NULL)
+        goto fail4;
+
+    Ring->Shared = MmGetSystemAddressForMdlSafe(Ring->Mdl,
+                                                NormalPagePriority);
+    ASSERT(Ring->Shared != NULL);
+
+#pragma warning(push)
+#pragma warning(disable: 4305)
+#pragma warning(disable: 4311) // 'type cast' pointer truncation from 
'blkif_sring_entry[1]' to 'long'
+    SHARED_RING_INIT(Ring->Shared);
+    FRONT_RING_INIT(&Ring->Front, Ring->Shared, PAGE_SIZE << Ring->Order);
+#pragma warning(pop)
+
+    for (Index = 0; Index < (1ul << Ring->Order); ++Index) {
+        status = GranterGet(Granter,
+                            MmGetMdlPfnArray(Ring->Mdl)[Index],
+                            FALSE,
+                            &Ring->Grants[Index]);
+        if (!NT_SUCCESS(status))
+            goto fail5;
+    }
+
+    Ring->Channel = XENBUS_EVTCHN(Open,
+                                  &Ring->EvtchnInterface,
+                                  XENBUS_EVTCHN_TYPE_UNBOUND,
+                                  RingInterrupt,
+                                  Ring,
+                                  FrontendGetBackendDomain(Ring->Frontend),
+                                  TRUE);
+    status = STATUS_NO_MEMORY;
+    if (Ring->Channel == NULL)
+        goto fail6;
+
+    XENBUS_EVTCHN(Unmask,
+                  &Ring->EvtchnInterface,
+                  Ring->Channel,
+                  FALSE);
+
+    status = XENBUS_DEBUG(Register,
+                          &Ring->DebugInterface,
+                          __MODULE__"|RING",
+                          RingDebugCallback,
+                          Ring,
+                          &Ring->DebugCallback);
+    if (!NT_SUCCESS(status))
+        goto fail7;
+
+    Ring->Connected = TRUE;
+    return STATUS_SUCCESS;
+
+fail7:
+    Error("fail7\n");
+    XENBUS_EVTCHN(Close,
+                  &Ring->EvtchnInterface,
+                  Ring->Channel);
+    Ring->Channel = NULL;
+fail6:
+    Error("fail6\n");
+fail5:
+    Error("fail5\n");
+    for (Index = 0; Index < (1ul << Ring->Order); ++Index) {
+        if (Ring->Grants[Index] == NULL)
+            continue;
+
+        GranterPut(Granter, Ring->Grants[Index]);
+        Ring->Grants[Index] = NULL;
+    }
+
+    RtlZeroMemory(&Ring->Front, sizeof(blkif_front_ring_t));
+    
+    __FreePages(Ring->Mdl);
+    Ring->Shared = NULL;
+    Ring->Mdl = NULL;
+
+    Ring->Order = 0;
+fail4:
+    Error("fail4\n");
+    XENBUS_DEBUG(Release, &Ring->DebugInterface);
+fail3:
+    Error("fail3\n");
+    XENBUS_EVTCHN(Release, &Ring->EvtchnInterface);
+fail2:
+    Error("fail2\n");
+    XENBUS_STORE(Release, &Ring->StoreInterface);
+fail1:
+    Error("fail1 %08x\n", status);
+
+    RtlZeroMemory(&Ring->DebugInterface,
+                  sizeof(XENBUS_DEBUG_INTERFACE));
+    RtlZeroMemory(&Ring->EvtchnInterface,
+                  sizeof(XENBUS_EVTCHN_INTERFACE));
+    RtlZeroMemory(&Ring->StoreInterface,
+                  sizeof(XENBUS_STORE_INTERFACE));
+
+    return status;
+}
+
+NTSTATUS
+RingStoreWrite(
+    IN  PXENVBD_RING    Ring,
+    IN  PVOID           Transaction
+    )
+{
+    PXENVBD_GRANTER     Granter = FrontendGetGranter(Ring->Frontend);
+    ULONG               Port;
+    NTSTATUS            status;
+
+    if (Ring->Order == 0) {
+        status = XENBUS_STORE(Printf, 
+                              &Ring->StoreInterface,
+                              Transaction, 
+                              FrontendGetFrontendPath(Ring->Frontend),
+                              "ring-ref", 
+                              "%u", 
+                              GranterReference(Granter, Ring->Grants[0]));
+        if (!NT_SUCCESS(status))
+            return status;
+    } else {
+        ULONG           Index;
+
+        status = XENBUS_STORE(Printf, 
+                              &Ring->StoreInterface,
+                              Transaction, 
+                              FrontendGetFrontendPath(Ring->Frontend),
+                              "ring-page-order", 
+                              "%u", 
+                              Ring->Order);
+        if (!NT_SUCCESS(status))
+            return status;
+
+        for (Index = 0; Index < (1ul << Ring->Order); ++Index) {
+            CHAR        Name[MAX_NAME_LEN+1];
+
+            status = RtlStringCchPrintfA(Name,
+                                         MAX_NAME_LEN,
+                                         "ring-ref%u",
+                                         Index);
+            if (!NT_SUCCESS(status))
+                return status;
+
+            status = XENBUS_STORE(Printf, 
+                                  &Ring->StoreInterface,
+                                  Transaction, 
+                                  FrontendGetFrontendPath(Ring->Frontend),
+                                  Name, 
+                                  "%u", 
+                                  GranterReference(Granter, 
Ring->Grants[Index]));
+            if (!NT_SUCCESS(status))
+                return status;
+        }
+    }
+
+    status = XENBUS_STORE(Printf, 
+                          &Ring->StoreInterface,
+                          Transaction, 
+                          FrontendGetFrontendPath(Ring->Frontend),
+                          "protocol", 
+                          XEN_IO_PROTO_ABI);
+    if (!NT_SUCCESS(status))
+        return status;
+
+    Port = XENBUS_EVTCHN(GetPort,
+                         &Ring->EvtchnInterface,
+                         Ring->Channel);
+
+    status = XENBUS_STORE(Printf, 
+                          &Ring->StoreInterface,
+                          Transaction, 
+                          FrontendGetFrontendPath(Ring->Frontend),
+                          "event-channel", 
+                          "%u",
+                          Port);
+    if (!NT_SUCCESS(status))
+        return status;
+
+    return STATUS_SUCCESS;
+}
+
+VOID
+RingEnable(
+    IN  PXENVBD_RING    Ring
+    )
+{
+    ASSERT(Ring->Enabled == FALSE);
+    Ring->Enabled = TRUE;
+
+    XENBUS_EVTCHN(Trigger,
+                  &Ring->EvtchnInterface,
+                  Ring->Channel);
+}
+
+VOID
+RingDisable(
+    IN  PXENVBD_RING    Ring
+    )
+{
+    ASSERT(Ring->Enabled == TRUE);
+    Ring->Enabled = FALSE;
+
+    //
+    // No new timers can be scheduled once Enabled goes to FALSE.
+    // Cancel any existing ones.
+    //
+    (VOID) KeCancelTimer(&Ring->Timer);
+}
+
+VOID
+RingDisconnect(
+    IN  PXENVBD_RING    Ring
+    )
+{
+    PXENVBD_GRANTER     Granter = FrontendGetGranter(Ring->Frontend);
+    ULONG               Index;
+
+    ASSERT3U(Ring->Submitted, ==, Ring->Received);
+    ASSERT(Ring->Connected);
+    Ring->Connected = FALSE;
+
+    XENBUS_DEBUG(Deregister,
+                 &Ring->DebugInterface,
+                 Ring->DebugCallback);
+    Ring->DebugCallback = NULL;
+
+    XENBUS_EVTCHN(Close,
+                  &Ring->EvtchnInterface,
+                  Ring->Channel);
+    Ring->Channel = NULL;
+
+    for (Index = 0; Index < (1ul << Ring->Order); ++Index) {
+        if (Ring->Grants[Index] == NULL)
+            continue;
+
+        GranterPut(Granter, Ring->Grants[Index]);
+        Ring->Grants[Index] = NULL;
+    }
+
+    RtlZeroMemory(&Ring->Front, sizeof(blkif_front_ring_t));
+    
+    __FreePages(Ring->Mdl);
+    Ring->Shared = NULL;
+    Ring->Mdl = NULL;
+
+    Ring->Order = 0;
+
+    XENBUS_DEBUG(Release, &Ring->DebugInterface);
+    XENBUS_EVTCHN(Release, &Ring->EvtchnInterface);
+    XENBUS_STORE(Release, &Ring->StoreInterface);
+
+    RtlZeroMemory(&Ring->DebugInterface,
+                  sizeof(XENBUS_DEBUG_INTERFACE));
+    RtlZeroMemory(&Ring->EvtchnInterface,
+                  sizeof(XENBUS_EVTCHN_INTERFACE));
+    RtlZeroMemory(&Ring->StoreInterface,
+                  sizeof(XENBUS_STORE_INTERFACE));
+
+    Ring->Events = 0;
+    Ring->Dpcs = 0;
+    Ring->Submitted = 0;
+    Ring->Received = 0;
+}
+
+BOOLEAN
+RingPoll(
+    IN  PXENVBD_RING    Ring
+    )
+{
+    PXENVBD_TARGET      Target = FrontendGetTarget(Ring->Frontend);
+    BOOLEAN             Retry = FALSE;
+
+    ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
+    KeAcquireSpinLockAtDpcLevel(&Ring->Lock);
+
+    // Guard against this locked region being called after the 
+    // lock on FrontendSetState
+    if (Ring->Enabled == FALSE)
+        goto done;
+
+    for (;;) {
+        ULONG   rsp_prod;
+        ULONG   rsp_cons;
+
+        KeMemoryBarrier();
+
+        rsp_prod = Ring->Shared->rsp_prod;
+        rsp_cons = Ring->Front.rsp_cons;
+
+        KeMemoryBarrier();
+
+        if (rsp_cons == rsp_prod || Retry)
+            break;
+
+        while (rsp_cons != rsp_prod && !Retry) {
+            blkif_response_t*   Response;
+            ULONG               Tag;
+
+            Response = RING_GET_RESPONSE(&Ring->Front, rsp_cons);
+            ++rsp_cons;
+
+            if (__RingPutTag(Ring, Response->id, &Tag)) {
+                ++Ring->Received;
+                TargetCompleteResponse(Target, Tag, Response->status);
+            }
+
+            RtlZeroMemory(Response, sizeof(union blkif_sring_entry));
+
+            if (rsp_cons - Ring->Front.rsp_cons > RING_SIZE(&Ring->Front) / 4)
+                Retry = TRUE;
+        }
+
+        KeMemoryBarrier();
+
+        Ring->Front.rsp_cons = rsp_cons;
+        Ring->Shared->rsp_event = rsp_cons + 1;
+    }
+
+done:
+    KeReleaseSpinLockFromDpcLevel(&Ring->Lock);
+
+    return Retry;
+}
+
+BOOLEAN
+RingSubmit(
+    IN  PXENVBD_RING    Ring,
+    IN  PXENVBD_REQUEST Request
+    )
+{
+    KIRQL               Irql;
+    blkif_request_t*    req;
+    BOOLEAN             Notify;
+
+    KeAcquireSpinLock(&Ring->Lock, &Irql);
+    if (RING_FULL(&Ring->Front)) {
+        KeReleaseSpinLock(&Ring->Lock, Irql);
+        return FALSE;
+    }
+
+    req = RING_GET_REQUEST(&Ring->Front, Ring->Front.req_prod_pvt);
+    __RingInsert(Ring, Request, req);
+    KeMemoryBarrier();
+    ++Ring->Front.req_prod_pvt;
+
+    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&Ring->Front, Notify);
+    KeReleaseSpinLock(&Ring->Lock, Irql);
+
+    if (Notify)
+        RingSend(Ring);
+
+    return TRUE;
+}
+
+VOID
+RingKick(
+    IN  PXENVBD_RING    Ring
+    )
+{
+    if (!Ring->Enabled)
+        return;
+
+    if (KeInsertQueueDpc(&Ring->Dpc, NULL, NULL))
+           ++Ring->Dpcs;
+}
+
+VOID
+RingTrigger(
+    IN  PXENVBD_RING    Ring
+    )
+{
+    if (!Ring->Enabled)
+        return;
+
+    XENBUS_EVTCHN(Trigger,
+                  &Ring->EvtchnInterface,
+                  Ring->Channel);
+}
+
+VOID
+RingSend(
+    IN  PXENVBD_RING    Ring
+    )
+{
+    if (!Ring->Enabled)
+        return;
+
+    XENBUS_EVTCHN(Send,
+                  &Ring->EvtchnInterface,
+                  Ring->Channel);
+}
diff --git a/src/xenvbd/ring.h b/src/xenvbd/ring.h
new file mode 100755
index 0000000..3ac1c71
--- /dev/null
+++ b/src/xenvbd/ring.h
@@ -0,0 +1,103 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */ 
+
+#ifndef _XENVBD_RING_H
+#define _XENVBD_RING_H
+
+typedef struct _XENVBD_RING XENVBD_RING, *PXENVBD_RING;
+
+#include "frontend.h"
+#include "srbext.h"
+
+extern NTSTATUS
+RingCreate(
+    IN  PXENVBD_FRONTEND    Frontend,
+    OUT PXENVBD_RING*       Ring
+    );
+
+extern VOID
+RingDestroy(
+    IN  PXENVBD_RING    Ring
+    );
+
+extern NTSTATUS
+RingConnect(
+    IN  PXENVBD_RING    Ring
+    );
+
+extern NTSTATUS
+RingStoreWrite(
+    IN  PXENVBD_RING    Ring,
+    IN  PVOID           Transaction
+    );
+
+extern VOID
+RingEnable(
+    IN  PXENVBD_RING    Ring
+    );
+
+extern VOID
+RingDisable(
+    IN  PXENVBD_RING    Ring
+    );
+
+extern VOID
+RingDisconnect(
+    IN  PXENVBD_RING    Ring
+    );
+
+extern BOOLEAN
+RingPoll(
+    IN  PXENVBD_RING    Ring
+    );
+
+extern BOOLEAN
+RingSubmit(
+    IN  PXENVBD_RING    Ring,
+    IN  PXENVBD_REQUEST Request
+    );
+
+extern VOID
+RingKick(
+    IN  PXENVBD_RING    Ring
+    );
+
+extern VOID
+RingTrigger(
+    IN  PXENVBD_RING    Ring
+    );
+
+extern VOID
+RingSend(
+    IN  PXENVBD_RING    Ring
+    );
+
+#endif // _XENVBD_RING_H
diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c
index 697f309..c0fa4e9 100644
--- a/src/xenvbd/target.c
+++ b/src/xenvbd/target.c
@@ -1063,8 +1063,7 @@ __TargetPauseDataPath(
     KIRQL               Irql;
     ULONG               Requests;
     ULONG               Count = 0;
-    PXENVBD_NOTIFIER    Notifier = FrontendGetNotifier(Target->Frontend);
-    PXENVBD_BLOCKRING   BlockRing = FrontendGetBlockRing(Target->Frontend);
+    PXENVBD_RING        Ring = FrontendGetRing(Target->Frontend);
 
     KeAcquireSpinLock(&Target->Lock, &Irql);
     ++Target->Paused;
@@ -1080,9 +1079,9 @@ __TargetPauseDataPath(
         if (Timeout && Count > 180000)
             break;
         KeRaiseIrql(DISPATCH_LEVEL, &Irql);
-        BlockRingPoll(BlockRing);
+        RingPoll(Ring);
         KeLowerIrql(Irql);
-        NotifierSend(Notifier);         // let backend know it needs to do 
some work
+        RingSend(Ring);         // let backend know it needs to do some work
         StorPortStallExecution(1000);   // 1000 micro-seconds
         ++Count;
     }
@@ -1180,7 +1179,7 @@ TargetSubmitPrepared(
     __in PXENVBD_TARGET             Target
     )
 {
-    PXENVBD_BLOCKRING   BlockRing = FrontendGetBlockRing(Target->Frontend);
+    PXENVBD_RING   Ring = FrontendGetRing(Target->Frontend);
     if (TargetIsPaused(Target)) {
         if (QueueCount(&Target->PreparedReqs))
             Warning("Target[%d] : Paused, not submitting new requests (%u)\n",
@@ -1202,7 +1201,7 @@ TargetSubmitPrepared(
         QueueAppend(&Target->SubmittedReqs, &Request->Entry);
         KeMemoryBarrier();
 
-        if (BlockRingSubmit(BlockRing, Request))
+        if (RingSubmit(Ring, Request))
             continue;
 
         QueueRemove(&Target->SubmittedReqs, &Request->Entry);
@@ -1393,7 +1392,7 @@ TargetReadWrite(
 {
     PXENVBD_DISKINFO    DiskInfo = FrontendGetDiskInfo(Target->Frontend);
     PXENVBD_SRBEXT      SrbExt = GetSrbExt(Srb);
-    PXENVBD_NOTIFIER    Notifier = FrontendGetNotifier(Target->Frontend);
+    PXENVBD_RING        Ring = FrontendGetRing(Target->Frontend);
 
     if (FrontendGetCaps(Target->Frontend)->Connected == FALSE) {
         Trace("Target[%d] : Not Ready, fail SRB\n", TargetGetTargetId(Target));
@@ -1409,7 +1408,7 @@ TargetReadWrite(
     }
 
     QueueAppend(&Target->FreshSrbs, &SrbExt->Entry);
-    NotifierKick(Notifier);
+    RingKick(Ring);
 
     return FALSE;
 }
@@ -1422,7 +1421,7 @@ TargetSyncCache(
     )
 {
     PXENVBD_SRBEXT      SrbExt = GetSrbExt(Srb);
-    PXENVBD_NOTIFIER    Notifier = FrontendGetNotifier(Target->Frontend);
+    PXENVBD_RING        Ring = FrontendGetRing(Target->Frontend);
 
     if (FrontendGetCaps(Target->Frontend)->Connected == FALSE) {
         Trace("Target[%d] : Not Ready, fail SRB\n", TargetGetTargetId(Target));
@@ -1439,7 +1438,7 @@ TargetSyncCache(
     }
 
     QueueAppend(&Target->FreshSrbs, &SrbExt->Entry);
-    NotifierKick(Notifier);
+    RingKick(Ring);
 
     return FALSE;
 }
@@ -1452,7 +1451,7 @@ TargetUnmap(
     )
 {
     PXENVBD_SRBEXT      SrbExt = GetSrbExt(Srb);
-    PXENVBD_NOTIFIER    Notifier = FrontendGetNotifier(Target->Frontend);
+    PXENVBD_RING        Ring = FrontendGetRing(Target->Frontend);
 
     if (FrontendGetCaps(Target->Frontend)->Connected == FALSE) {
         Trace("Target[%d] : Not Ready, fail SRB\n", TargetGetTargetId(Target));
@@ -1468,7 +1467,7 @@ TargetUnmap(
     }
 
     QueueAppend(&Target->FreshSrbs, &SrbExt->Entry);
-    NotifierKick(Notifier);
+    RingKick(Ring);
 
     return FALSE;
 }
@@ -1893,7 +1892,7 @@ TargetFlush(
     )
 {
     QueueAppend(&Target->ShutdownSrbs, &SrbExt->Entry);
-    NotifierKick(FrontendGetNotifier(Target->Frontend));
+    RingKick(FrontendGetRing(Target->Frontend));
 }
 
 VOID
@@ -1903,7 +1902,7 @@ TargetShutdown(
     )
 {
     QueueAppend(&Target->ShutdownSrbs, &SrbExt->Entry);
-    NotifierKick(FrontendGetNotifier(Target->Frontend));
+    RingKick(FrontendGetRing(Target->Frontend));
 }
 
 VOID
diff --git a/vs2015/xenvbd/xenvbd.vcxproj b/vs2015/xenvbd/xenvbd.vcxproj
index f5b9cf7..82749ad 100644
--- a/vs2015/xenvbd/xenvbd.vcxproj
+++ b/vs2015/xenvbd/xenvbd.vcxproj
@@ -73,8 +73,7 @@
     <ClCompile Include="../../src/xenvbd/pdoinquiry.c" />
     <ClCompile Include="../../src/xenvbd/queue.c" />
     <ClCompile Include="../../src/xenvbd/thread.c" />
-    <ClCompile Include="../../src/xenvbd/notifier.c" />
-    <ClCompile Include="../../src/xenvbd/blockring.c" />
+    <ClCompile Include="../../src/xenvbd/ring.c" />
     <ClCompile Include="../../src/xenvbd/granter.c" />
   </ItemGroup>
   <ItemGroup>
-- 
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®.