ahci: device queue implemented
authorRoni Häcki <roni.haecki@inf.ethz.ch>
Fri, 13 Jan 2017 11:33:31 +0000 (12:33 +0100)
committerRoni Häcki <roni.haecki@inf.ethz.ch>
Fri, 13 Jan 2017 11:33:31 +0000 (12:33 +0100)
Signed-off-by: Roni Häcki <roni.haecki@inf.ethz.ch>

include/devif/backends/blk/ahci_devq.h [new file with mode: 0644]
lib/blk/Hakefile
lib/blk/blk_ahci/ahci_port.c
lib/blk/blk_ahci/blk_ahci.h
lib/blk/blk_ahci/device_impl.c
usr/drivers/ahcid/Hakefile
usr/drivers/ahcid/ahcid.c
usr/drivers/ahcid/test.c

diff --git a/include/devif/backends/blk/ahci_devq.h b/include/devif/backends/blk/ahci_devq.h
new file mode 100644 (file)
index 0000000..a7001cc
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2011 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef _AHCI_DEVQ_H
+#define _AHCI_DEVQ_H
+
+#include <barrelfish/barrelfish.h>
+
+#define MAX_BUFFERS 256
+
+struct ahci_queue;
+
+errval_t ahci_create(struct ahci_queue** q, void* st, uint64_t flags);
+errval_t ahci_destroy(struct ahci_queue* q);
+void ahci_interrupt_handler(void* q);
+
+
+#endif // _AHCI_DEVQ_H
index 2401859..b1ac8dd 100644 (file)
@@ -2,6 +2,7 @@
   build library {
     target = "blk",
     mackerelDevices = [ "ata_identify", "ahci_port", "ahci_hba" ],
-    cFiles = [ "blk.c", "blk_ahci/ahci_init.c", "blk_ahci/ahci_port.c", "blk_ahci/ahci_dev.c", "blk_ahci/sata_fis.c", "blk_ahci/device_impl.c", "dma_mem/dma_mem.c" ]
+    cFiles = [ "blk.c", "blk_ahci/ahci_init.c", "blk_ahci/ahci_port.c", "blk_ahci/ahci_dev.c", "blk_ahci/sata_fis.c", "blk_ahci/device_impl.c", "dma_mem/dma_mem.c" ],
+    addLibraries = libDeps ["pci", "skb", "devif_internal"]
   }
 ]
index ddec091..6494fe6 100644 (file)
@@ -81,16 +81,16 @@ static errval_t port_init_ctba(struct ahci_port* port, size_t command_slot)
     return err;
 }
 
-static void blk_ahci_interrupt(struct ahci_port* port, struct dev_queue *queue)
+static void blk_ahci_interrupt(struct ahci_port* port, struct dev_queue_request* reqs, 
+                               size_t slots)
 {
     ahci_port_is_t status = ahci_port_is_rd(&port->port);
 
     // A request was handled:
     //if (ahci_port_is_dhrs_extract(status) > 0) {
-        BLK_DEBUG("Done with DMA command.\n");
 
-        for (size_t slot = 0; slot < queue->port->ncs; slot++) {
-            struct dev_queue_request *dqr = &queue->requests[slot];
+        for (size_t slot = 0; slot < slots; slot++) {
+            struct dev_queue_request *dqr = &reqs[slot];
 
             bool slot_has_request = dqr->status == RequestStatus_InProgress;
             bool slot_done = ahci_port_slot_free(&port->port, slot);
@@ -98,7 +98,6 @@ static void blk_ahci_interrupt(struct ahci_port* port, struct dev_queue *queue)
                 //printf("waiting for slot %zu.\n", slot);
             }
             if (slot_has_request && slot_done) {
-                //printf("AHCI slot %zu is done now.\n", slot);
                 dqr->status = RequestStatus_Done;
             }
         }
@@ -149,6 +148,7 @@ errval_t blk_ahci_port_dma_async(struct ahci_port *port, size_t slot, uint64_t b
     ct->prdt[0] = region_descriptor_new(base, (length - 1) | 0x1, false);
 
     while (!ahci_port_is_ready(&port->port)) {
+        
         // TODO: Abort return error on timeout
     }
 
index 40c0e8f..6b116ea 100644 (file)
@@ -52,27 +52,6 @@ struct __attribute__((__packed__)) command_table {
 
 struct ahci_port;
 struct dev_queue;
-typedef void (*ahci_port_interrupt_handler_fn)(struct ahci_port*, struct dev_queue*);
-
-struct ahci_port {
-    bool is_initialized; //< Port is up and running, ready to read/write.
-    ahci_port_t port;
-    struct dma_mem fb;
-    struct dma_mem clb;
-    struct dma_mem ctba_mem[MAX_CTBA_SLOTS];
-    struct command_table* command_table[MAX_CTBA_SLOTS]; //< Points to ctba_mem[i].vaddr
-    size_t ncs; //< Number of command slots actually implemented
-    ahci_port_interrupt_handler_fn interrupt;
-    struct ahci_mgmt_binding *binding;
-    struct dma_mem identify_mem;
-    ata_identify_t identify; //< Points to identify_mem.vaddr, valid after port_identify() is done.
-};
-
-struct ahci_disk {
-    struct device_mem* bar5;
-    ahci_hba_t controller;
-    struct ahci_port ports[MAX_AHCI_PORTS];
-};
 
 
 enum RequestStatus {
@@ -98,6 +77,31 @@ struct dev_queue_request {
     enum RequestStatus status;
 };
 
+
+typedef void (*ahci_port_interrupt_handler_fn)(struct ahci_port*, struct dev_queue_request* reqs, size_t slots);
+
+struct ahci_port {
+    bool is_initialized; //< Port is up and running, ready to read/write.
+    ahci_port_t port;
+    struct dma_mem fb;
+    struct dma_mem clb;
+    struct dma_mem ctba_mem[MAX_CTBA_SLOTS];
+    struct command_table* command_table[MAX_CTBA_SLOTS]; //< Points to ctba_mem[i].vaddr
+    size_t ncs; //< Number of command slots actually implemented
+    ahci_port_interrupt_handler_fn interrupt;
+    struct ahci_mgmt_binding *binding;
+    struct dma_mem identify_mem;
+    ata_identify_t identify; //< Points to identify_mem.vaddr, valid after port_identify() is done.
+};
+
+struct ahci_disk {
+    struct device_mem* bar5;
+    ahci_hba_t controller;
+    struct ahci_port ports[MAX_AHCI_PORTS];
+};
+
+
+
 struct dev_queue {
     struct ahci_port* port;
     struct dma_mem buffers[MAX_BUFFERS];
index 417ba7e..a9a6d73 100644 (file)
@@ -1,19 +1,28 @@
 #include <barrelfish/barrelfish.h>
 #include <assert.h>
-//#include <devif/queue.h>
+#include <devif/queue_interface.h>
+#include <devif/backends/blk/ahci_devq.h>
 
 #include "blk_ahci.h"
 #include "ahci_dev.h" // TODO: get rid of this include
 #include "../dma_mem/dma_mem.h"
 #include "../blk_debug.h"
+#include "../../devif/queue_interface_internal.h"
 
-#if 0
-static bool is_valid_buffer(struct dev_queue* dq, size_t slot)
+struct ahci_queue {
+    struct devq q;
+    struct ahci_port* port;
+    struct dma_mem buffers[MAX_BUFFERS];
+    struct dev_queue_request requests[MAX_REQUESTS];
+};
+
+
+static bool is_valid_buffer(struct ahci_queue* dq, size_t slot)
 {
     return !capref_is_null(dq->buffers[slot].frame);
 }
 
-static errval_t request_slot_alloc(struct dev_queue* dq, size_t* slot)
+static errval_t request_slot_alloc(struct ahci_queue* dq, size_t* slot)
 {
     assert(dq->port->ncs <= MAX_REQUESTS);
 
@@ -43,13 +52,12 @@ static errval_t get_port(struct ahci_disk* hba, size_t port_num, struct ahci_por
     return SYS_ERR_OK;
 }
 
-static errval_t init_queue(struct dev_queue** dq, struct ahci_port *port) {
-    struct dev_queue* queue = calloc(1, sizeof(struct dev_queue));
+static errval_t init_queue(struct ahci_queue** dq) {
+    struct ahci_queue* queue = calloc(1, sizeof(struct ahci_queue));
     if (dq == NULL) {
         return LIB_ERR_MALLOC_FAIL;
     }
 
-    queue->port = port;
     for (size_t i = 0; i< MAX_BUFFERS; i++) {
         queue->buffers[i].frame = NULL_CAP;
     }
@@ -75,70 +83,52 @@ static bool flags_is_write(uint64_t flags) {
     return (flags & (1ULL << 63)) > 0;
 }
 
-void devq_interrupt_handler(void* q);
-void devq_interrupt_handler(void* q)
+void ahci_interrupt_handler(void* q)
 {
     if (q == NULL) {
         BLK_DEBUG("Ignored interrupt, device not yet initialized?\n");
         return;
     }
-    struct dev_queue *queue = q;
+    struct ahci_queue *queue = q;
     struct ahci_port *port = queue->port;
 
     assert(port->interrupt != NULL);
-    port->interrupt(port, queue);
-}
-
-errval_t devq_create(void* st, char *device_name, uint64_t flags, void **queue)
-{
-    errval_t err = SYS_ERR_OK;
-
-    struct ahci_port* port = NULL;
-    err = get_port(st, flags, &port);
-    if (err_is_fail(err)) {
-        return err;
-    }
-
-    struct dev_queue *dq;
-    err = init_queue(&dq, port);
-    if (err_is_fail(err)) {
-        return err;
-    }
-
-    *queue = dq;
-
-    return err;
+    port->interrupt(port, queue->requests, port->ncs);
 }
 
-errval_t devq_destroy(void *qp)
+errval_t ahci_destroy(struct ahci_queue *q)
 {
-    struct dev_queue *queue = qp;
-
     // TODO: Wait for stuff to finish...!
 
     // Clean-up memory:
     for (size_t i = 0; i< MAX_BUFFERS; i++) {
-        dma_mem_free(&queue->buffers[i]);
+        dma_mem_free(&q->buffers[i]);
     }
-    free(qp);
+    free(q);
     return SYS_ERR_OK;
 }
 
-errval_t devq_enqueue(void *q, regionid_t region_id, lpaddr_t base, size_t length, bufferid_t buffer_id, uint64_t flags)
+static errval_t ahci_enqueue(struct devq *q, 
+                             regionid_t region_id, 
+                             bufferid_t buffer_id, 
+                             lpaddr_t base, 
+                             size_t length, 
+                             uint64_t flags)
 {
-    struct dev_queue *queue = q;
-    assert(region_id < MAX_BUFFERS);
-    assert(is_valid_buffer(queue, region_id));
+    struct ahci_queue *queue = (struct ahci_queue*) q;
+    
+    assert(is_valid_buffer(queue, (region_id % MAX_BUFFERS)));
     assert(base != 0);
     assert(length >= 512);
 
-    struct dma_mem* mem = &queue->buffers[region_id];
+    struct dma_mem* mem = &queue->buffers[(region_id % MAX_BUFFERS)];
 
     if (!slice_is_in_range(mem, base, length)) {
         return DEV_ERR_INVALID_BUFFER_ARGS;
     }
 
     size_t slot = 0;
+    
     errval_t err = request_slot_alloc(queue, &slot);
     if (err_is_fail(err)) {
         return err;
@@ -149,36 +139,37 @@ errval_t devq_enqueue(void *q, regionid_t region_id, lpaddr_t base, size_t lengt
     dqr->buffer_id = buffer_id;
     dqr->base = base;
     dqr->length = length;
-    dqr->region_id = region_id;
+    dqr->region_id = region_id ;
     dqr->command_slot = slot;
 
     uint64_t block = flags_get_block(flags);
     bool write = flags_is_write(flags);
-    return blk_ahci_port_dma_async(queue->port, slot, block, base, length, write);
+
+    err = blk_ahci_port_dma_async(queue->port, slot, block, base, length, write);
+    return err;
 }
 
-errval_t devq_dequeue(void *q,
-                      regionid_t* region_id,
-                      lpaddr_t* base,
-                      size_t* length,
-                      bufferid_t* buffer_id)
+static errval_t ahci_dequeue(struct devq* q,
+                             regionid_t* region_id,
+                             bufferid_t* buffer_id,
+                             lpaddr_t* base,
+                             size_t* length,
+                             uint64_t* misc_flags)
 {
     assert(q != NULL);
     assert(region_id != NULL);
     assert(base != NULL);
     assert(length != NULL);
-    assert(length != NULL);
 
-    struct dev_queue *queue = q;
+    struct ahci_queue *queue = (struct ahci_queue*) q;
 
-    for (size_t i=0; i<queue->port->ncs; i++) {
+    for (size_t i=0; i < queue->port->ncs; i++) {
         struct dev_queue_request *dqr = &queue->requests[i];
         if (dqr->status == RequestStatus_Done) {
             *base = dqr->base;
             *length = dqr->length;
             *buffer_id = dqr->buffer_id;
             *region_id = dqr->region_id;
-
             dqr->status = RequestStatus_Unused;
             return dqr->error;
         }
@@ -187,53 +178,89 @@ errval_t devq_dequeue(void *q,
     return DEV_ERR_QUEUE_EMPTY;
 }
 
-errval_t devq_register(void *q,
-                       struct capref cap,
-                       regionid_t* region_id)
+static errval_t ahci_register(struct devq *q,
+                              struct capref cap,
+                              regionid_t region_id)
 {
+
     errval_t err = DEV_ERR_REGISTER_BUFFER;
     assert(!capref_is_null(cap));
-    struct dev_queue *queue = q;
+    struct ahci_queue *queue = (struct ahci_queue*) q;
 
     for (size_t i=0; i<MAX_BUFFERS; i++) {
-        if (is_valid_buffer(q, i)) {
+        uint16_t slot = ((region_id+i) % MAX_BUFFERS);
+
+        if (is_valid_buffer(queue, slot)) {
             printf("Don't overwrite existing buffer\n");
             continue;
         }
-
-        struct dma_mem* mem = &queue->buffers[i];
+        
+        queue->buffers[slot].frame = cap;
+        
+        struct dma_mem* mem = &queue->buffers[slot];
         err = dma_mem_from_capref(cap, mem);
         if (err_is_fail(err)) {
             DEBUG_ERR(err, "call failed");
             return err_push(err, DEV_ERR_REGISTER_BUFFER);
         }
-
-        *region_id = i;
         return SYS_ERR_OK;
     }
 
     return err;
 }
 
-errval_t devq_remove(void *q, regionid_t region_id)
+static errval_t ahci_deregister(struct devq *q, regionid_t region_id)
 {
-    assert(region_id < MAX_BUFFERS);
     assert(q != NULL);
-    struct dev_queue *queue = q;
+    struct ahci_queue *queue = (struct ahci_queue*) q;
 
-    struct dma_mem* mem = &queue->buffers[region_id];
+    struct dma_mem* mem = &queue->buffers[(region_id % MAX_BUFFERS)];
     assert(!capref_is_null(mem->frame));
 
     return dma_mem_free(mem);
 }
 
-errval_t devq_sync(void *q)
+static errval_t ahci_notify(struct devq *q)
 {
     return SYS_ERR_OK;
 }
 
-errval_t devq_control(void *q, uint64_t request, uint64_t value)
+static errval_t ahci_control(struct devq *q, uint64_t request, uint64_t value)
 {
     return SYS_ERR_OK;
 }
-#endif
+
+errval_t ahci_create(struct ahci_queue** q, void* st, uint64_t flags)
+{
+    errval_t err = SYS_ERR_OK;
+
+    struct ahci_port* port = NULL;
+    err = get_port(st, flags, &port);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    struct ahci_queue *dq;
+    err = init_queue(&dq);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    dq->port = port;
+
+    dq->q.f.enq = ahci_enqueue;
+    dq->q.f.deq = ahci_dequeue;
+    dq->q.f.reg = ahci_register;
+    dq->q.f.dereg = ahci_deregister;
+    dq->q.f.ctrl = ahci_control;
+    dq->q.f.notify = ahci_notify;
+
+    err = devq_init(&dq->q, false);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    *q = dq;
+
+    return err;
+}
index fe2070b..809fda5 100644 (file)
@@ -16,7 +16,7 @@
         mackerelDevices = [ "ata_identify", "ahci_port", "ahci_hba" ],
         cFiles = [ "ahcid.c", "test.c" ],
         addCFlags = ["-Wno-unused-variable", "-Wno-unused-function"],
-        addLibraries = [ "blk", "pci", "skb", "bench" ]
+        addLibraries = [ "blk", "pci", "skb", "bench", "devif" ]
     },
 
     build application {
@@ -24,6 +24,6 @@
         mackerelDevices = [ "ata_identify", "ahci_port", "ahci_hba" ],
         cFiles = [ "ahcid.c", "test.c" ],
         addCFlags = ["-DTESTING"],
-        addLibraries = [ "blk", "pci", "skb", "bench" ]
+        addLibraries = [ "blk", "pci", "skb", "bench" , "devif"]
     }
 ]
index 1c556b4..51f19ef 100644 (file)
@@ -7,6 +7,9 @@
  * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
  */
 
+
+#include <inttypes.h>
+#include <devif/backends/blk/ahci_devq.h>
 #include "ahcid.h"
 #include "test.h"
 
@@ -24,15 +27,14 @@ struct device_id {
     uint16_t device;
 };
 
-static void ahci_interrupt_handler(void *arg)
+static void interrupt_handler(void *arg)
 {
-//    void devq_interrupt_handler(void*);
-//    devq_interrupt_handler(dq);
+    ahci_interrupt_handler(dq);
 
 #ifdef DISABLE_INTERRUPTS
     assert(chan != NULL);
-//    assert(dq != NULL);
-    errval_t err = waitset_chan_register(&disk_ws, chan, MKCLOSURE(ahci_interrupt_handler, dq));
+    assert(dq != NULL);
+    errval_t err = waitset_chan_register(&disk_ws, chan, MKCLOSURE(interrupt_handler, dq));
     if (err_is_fail(err) && err_no(err) == LIB_ERR_CHAN_ALREADY_REGISTERED) {
         printf("Got actual interrupt?\n");
     }
@@ -44,6 +46,7 @@ static void ahci_interrupt_handler(void *arg)
         USER_PANIC_ERR(err, "trigger failed.");
     }
 #endif
+    
 }
 
 static void do_ahci_init(struct device_mem* bar_info, int nr_allocated_bars)
@@ -68,14 +71,22 @@ static void do_ahci_init(struct device_mem* bar_info, int nr_allocated_bars)
         USER_PANIC_ERR(err, "AHCI HBA init failed.");
     }
 
-#if DISABLE_INTERRUPTS
+    struct ahci_queue* q;
+    err = ahci_create(&q, ad, 0);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "ahci_queue create failed.");
+    }
+
+    dq = (struct devq*) q;
+
+#ifdef DISABLE_INTERRUPTS
     waitset_init(&disk_ws);
 
     // Hack: Why don't interrupts work?
     chan = malloc(sizeof(struct waitset_chanstate));
     waitset_chanstate_init(chan, CHANTYPE_AHCI);
 
-    err = waitset_chan_register(&disk_ws, chan, MKCLOSURE(ahci_interrupt_handler, dq));
+    err = waitset_chan_register(&disk_ws, chan, MKCLOSURE(interrupt_handler, dq));
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "waitset_chan_regster failed.");
     }
@@ -94,7 +105,7 @@ static void ahci_reregister_handler(void *arg)
     struct device_id *dev_id = arg;
     err = pci_reregister_irq_for_device(PCI_CLASS_MASS_STORAGE, PCI_SUB_SATA,
             PCI_DONT_CARE, dev_id->vendor, dev_id->device, PCI_DONT_CARE, PCI_DONT_CARE,
-            PCI_DONT_CARE, ahci_interrupt_handler, NULL,
+            PCI_DONT_CARE, interrupt_handler, NULL,
             ahci_reregister_handler, dev_id);
     if (err_is_fail(err)) {
         DEBUG_ERR(err, "pci_reregister_irq_for_device");
@@ -124,7 +135,7 @@ int main(int argc, char **argv)
         r = pci_register_driver_movable_irq(do_ahci_init, PCI_CLASS_MASS_STORAGE,
                 PCI_SUB_SATA, PCI_DONT_CARE, vendor_id, device_id,
                 PCI_DONT_CARE, PCI_DONT_CARE, PCI_DONT_CARE,
-                ahci_interrupt_handler, NULL,
+                interrupt_handler, NULL,
                 ahci_reregister_handler, dev_id);
         if (err_is_fail(r)) {
             printf("Couldn't register device %04"PRIx64":%04"PRIx64": %s\n", vendor_id,
index 3c0bf71..333bf08 100644 (file)
@@ -3,7 +3,10 @@
 
 #include <stdarg.h>
 #include <bench/bench.h>
-//#include <devif/queue.h>
+#include <devif/backends/blk/ahci_devq.h>
+#include <devif/queue_interface.h>
+
+static uint64_t finish_counter = 0;
 
 struct dma_mem {
     lvaddr_t vaddr;         ///< virtual address of the mapped region
@@ -15,7 +18,6 @@ struct dma_mem {
 
 void test_runner(int n, ...)
 {
-#if 0
     va_list arguments;
     va_start(arguments, n);
 
@@ -84,13 +86,10 @@ void test_runner(int n, ...)
     }
     // Harness line
     printf("AHCI testing completed.\n");
-#endif
-    // Harness line
-    printf("AHCI testing not implemented.\n");
 }
 
-#if 0
-static void frame_alloc_identify(size_t size, struct capref *frame, struct frame_identity *id)
+static void frame_alloc_identify(size_t size, struct capref *frame, 
+                                 struct frame_identity *id)
 {
     errval_t err;
     size_t retbytes;
@@ -123,29 +122,43 @@ void ahci_simple_test(void)
 
     // Allocate a buffer:
     struct dma_mem mem;
-    err = frame_alloc(&mem.frame, 4096, &mem.bytes);
+
+    struct capref frame;
+    struct frame_identity id;
+    //void* va;
+
+    err = frame_alloc(&frame, 4096, NULL);
     if (err_is_fail(err)) {
-        USER_PANIC_ERR(err, "frame_alloc");
+        USER_PANIC_ERR(err, "frame alloc");
     }
-    struct frame_identity id;
-    err = invoke_frame_identify(mem.frame, &id);
+
+    /*
+    err = vspace_map_one_frame_attr(&va, 4096, frame, VREGION_FLAGS_READ_WRITE,
+                                    NULL, NULL); 
     if (err_is_fail(err)) {
-        USER_PANIC_ERR(err, "invoke_frame_identify");
+        USER_PANIC_ERR(err, "map frame");
+    }
+    */
+    
+    err = invoke_frame_identify(frame, &id);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "frame identify");
     }
 
-    err = devq_register(dq, mem.frame, &region_id);
+    err = devq_register(dq, frame, &region_id);
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "devq register");
     }
 
     uint64_t flags = 0x0;
-    devq_enqueue(dq, region_id, id.base, 512, 0x123, flags);
+    bufferid_t bid;
+    devq_enqueue(dq, region_id, id.base, 512, flags, &bid);
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "devq enqueue");
     }
 
     do {
-        err = devq_dequeue(dq, &region_id, &base, &length, &buffer_id);
+        err = devq_dequeue(dq, &region_id, &base, &length, &buffer_id, &flags);
         if (err_is_ok(err)) {
             break;
         }
@@ -155,23 +168,24 @@ void ahci_simple_test(void)
         wait_for_interrupt();
     } while (err_no(err) == DEV_ERR_QUEUE_EMPTY);
 
-    assert (buffer_id == 0x123);
     assert (base == id.base);
     assert (length == 512);
 
-    err = devq_remove(dq, region_id);
+    err = devq_deregister(dq, region_id, &mem.frame);
     if (err_is_fail(err)) {
-        USER_PANIC_ERR(err, "devq_remove failed.");
+        USER_PANIC_ERR(err, "devq_deregister failed.");
     }
 
     printf("[%s]: DONE\n", __FUNCTION__);
 }
 
-static void blocking_dequeue(void* q, regionid_t* region_id, lpaddr_t* base, size_t* length, bufferid_t* buffer_id)
+static void blocking_dequeue(void* q, regionid_t* region_id, lpaddr_t* base, 
+                             size_t* length, bufferid_t* buffer_id)
 {
+    uint64_t flags;
     errval_t err;
     do {
-        err = devq_dequeue(q, region_id, base, length, buffer_id);
+        err = devq_dequeue(q, region_id, base, length, buffer_id, &flags);
         if (err_is_ok(err)) {
             break;
         }
@@ -191,14 +205,12 @@ static void receive_block(void)
     size_t len = 0;
     bufferid_t bid = 0;
     blocking_dequeue(dq, &rid, &base, &len, &bid);
-
-    bool* status = (bool*) bid;
-    assert (*status == false); // Only write region once
-    *status = true;
+    finish_counter++;
 }
 
 void ahci_perf_sequential(size_t buffer_size, size_t block_size, bool write)
 {
+    finish_counter = 0;
     bench_init();
     errval_t err;
     assert(buffer_size % block_size == 0);
@@ -216,12 +228,14 @@ void ahci_perf_sequential(size_t buffer_size, size_t block_size, bool write)
     }
 
     uint64_t write_flag = (write) ? (1ULL << 63) : 0;
-    volatile bool *received = calloc(1, sizeof(bool) * read_requests);
+    bufferid_t *received = calloc(1, sizeof(bufferid_t) * read_requests);
     cycles_t t1 = bench_tsc();
+
     for (size_t i=0; i < read_requests; i++) {
         uint64_t disk_block = write_flag | i;
         do {
-            err = devq_enqueue(dq, region_id, id.base + (i*block_size), block_size, (bufferid_t)&received[i], disk_block);
+            err = devq_enqueue(dq, region_id, id.base + (i*block_size), 
+                               block_size, disk_block, &received[i]);
             if (err_is_ok(err)) {
                 break;
             }
@@ -233,12 +247,12 @@ void ahci_perf_sequential(size_t buffer_size, size_t block_size, bool write)
             }
         } while (true);
     }
+
     // Make sure we have all requests:
-    for (size_t i=0; i<read_requests; i++) {
-        while (!received[i]) {
-            receive_block();
-        }
+    while (finish_counter < read_requests) {
+        receive_block();
     }
+
     cycles_t t2 = bench_tsc();
     cycles_t result = (t2 - t1 - bench_tscoverhead());
 
@@ -247,15 +261,18 @@ void ahci_perf_sequential(size_t buffer_size, size_t block_size, bool write)
     char* cmd = write ? "Write" : "Read";
     printf("[%s] %s sequential size %zu bs %zu: %.2f [MB/s]\n", __FUNCTION__, cmd, buffer_size, block_size, bw);
 
-    err = devq_remove(dq, region_id);
+    err = devq_deregister(dq, region_id, &frame);
     if (err_is_fail(err)) {
-        USER_PANIC_ERR(err, "devq_remove failed.");
+        USER_PANIC_ERR(err, "devq_deregister failed.");
     }
 
+    free(received);
+
     cap_destroy(frame);
 }
 void ahci_verify_sequential(size_t buffer_size, size_t block_size)
 {
+    finish_counter = 0;
     bench_init();
     errval_t err;
     assert(buffer_size % block_size == 0);
@@ -289,11 +306,12 @@ void ahci_verify_sequential(size_t buffer_size, size_t block_size)
     memset(retaddr, rbyte, buffer_size);
 
     uint64_t write_flag = (1ULL << 63);
-    bool *received = calloc(1, sizeof(bool) * requests);
+    bufferid_t *received = calloc(1, sizeof(bufferid_t) * requests);
     for (size_t i=0; i < requests; i++) {
         uint64_t disk_block = write_flag | i;
         do {
-            err = devq_enqueue(dq, region_id, id.base + (i*block_size), block_size, (bufferid_t)&received[i], disk_block);
+            err = devq_enqueue(dq, region_id, id.base + (i*block_size), block_size, 
+                               disk_block, &received[i]);
             if (err_is_ok(err)) {
                 break;
             }
@@ -306,21 +324,20 @@ void ahci_verify_sequential(size_t buffer_size, size_t block_size)
         } while (true);
     }
     // Make sure we have all requests:
-    for (size_t i=0; i<requests; i++) {
-        //printf("%s:%s:%d: i: %zu requests: %zu\n", __FILE__, __FUNCTION__, __LINE__, i, requests);
-        while (!received[i]) {
-            receive_block();
-        }
+    while (finish_counter < requests) {
+        receive_block();
     }
 
     memset(retaddr, 0x00, id.bytes);
-    memset((void*)received, 0x0, sizeof(bool)*requests);
+    memset((void*)received, 0x0, sizeof(bufferid_t)*requests);
+    finish_counter = 0;
 
     for (size_t i=0; i < requests; i++) {
         //printf("%s:%s:%d: i: %zu requests: %zu\n", __FILE__, __FUNCTION__, __LINE__, i, requests);
         uint64_t disk_block = i;
         do {
-            err = devq_enqueue(dq, region_id, id.base + (i*block_size), block_size, (bufferid_t)&received[i], disk_block);
+            err = devq_enqueue(dq, region_id, id.base + (i*block_size), 
+                               block_size, disk_block, &received[i]);
             if (err_is_ok(err)) {
                 break;
             }
@@ -332,12 +349,10 @@ void ahci_verify_sequential(size_t buffer_size, size_t block_size)
             }
         } while (true);
     }
+
     // Make sure we have all requests:
-    for (size_t i=0; i<requests; i++) {
-        while (!received[i]) {
-            //printf("%s:%s:%d: i: %zu requests: %zu\n", __FILE__, __FUNCTION__, __LINE__, i, requests);
-            receive_block();
-        }
+    while (finish_counter < requests) {
+        receive_block();
     }
 
     for (size_t i=0; i < buffer_size; i++) {
@@ -351,9 +366,8 @@ void ahci_verify_sequential(size_t buffer_size, size_t block_size)
     printf("[%s] SUCCESS (%zu %zu)\n", __FUNCTION__, buffer_size, block_size);
     cap_destroy(fcopy);
 
-    err = devq_remove(dq, region_id);
+    err = devq_deregister(dq, region_id, &frame);
     if (err_is_fail(err)) {
-        USER_PANIC_ERR(err, "devq_remove failed.");
+        USER_PANIC_ERR(err, "devq_deregister failed.");
     }
 }
-#endif