DeviceQueue: Restructering library parts intermediate commit
authorRoni Häcki <haeckir@student.ethz.ch>
Sun, 2 Oct 2016 08:30:47 +0000 (10:30 +0200)
committerRoni Häcki <haeckir@student.ethz.ch>
Sun, 2 Oct 2016 08:30:47 +0000 (10:30 +0200)
Signed-off-by: Roni Häcki <haeckir@student.ethz.ch>

30 files changed:
if/Hakefile
if/devif_ctrl.if [deleted file]
if/devif_data.if [deleted file]
include/devif/backends/loopback/loopback_device.h [moved from include/devif/loopback_device.h with 100% similarity]
include/devif/backends/net/sfn5122f_devif.h [new file with mode: 0644]
include/devif/queue_interface.h
include/devif/sfn5122f_devif.h [deleted file]
lib/devif/Hakefile
lib/devif/backends/idc/Hakefile [new file with mode: 0644]
lib/devif/backends/idc/desc_queue.c [moved from lib/devif/desc_queue.c with 77% similarity]
lib/devif/backends/idc/desc_queue.h [new file with mode: 0644]
lib/devif/backends/loopback/loopback_device.c [moved from lib/devif/loopback_device.c with 100% similarity]
lib/devif/backends/net/solarflare/Hakefile [new file with mode: 0644]
lib/devif/backends/net/solarflare/devif_backend_solarflare.c [new file with mode: 0644]
lib/devif/backends/net/solarflare/helper.c [new file with mode: 0644]
lib/devif/backends/net/solarflare/helper.h [new file with mode: 0644]
lib/devif/backends/net/solarflare/hw_queue.h [new file with mode: 0644]
lib/devif/desc_queue.h [deleted file]
lib/devif/queue_interface.c
lib/devif/queue_interface_internal.c [new file with mode: 0644]
lib/devif/queue_interface_internal.h [new file with mode: 0644]
usr/drivers/ahcid/ahcid.c
usr/drivers/ahcid/ahcid.h
usr/drivers/ahcid/test.c
usr/drivers/solarflare/Hakefile
usr/drivers/solarflare/sfn5122f_cdriver.c
usr/tests/devif/Hakefile
usr/tests/devif/forward_device.c [deleted file]
usr/tests/devif/loopback_device.c [deleted file]
usr/tests/devif/queue_interface.c

index 951c3bd..db25cd3 100644 (file)
@@ -89,8 +89,6 @@
                "xmplrpc",
                "xmplthc",
                "xomp",
-               "devif_ctrl",
-               "devif_data",
                "xomp_gateway",
                "sfn5122f",
                "sfn5122f_devif"
diff --git a/if/devif_ctrl.if b/if/devif_ctrl.if
deleted file mode 100644 (file)
index fd6419a..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/** \file
- *  \brief Device Queue message interface control plane
- */
-
-/*
- * Copyright (c) 2016, 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, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
- */
-
-interface devif_ctrl "Device Queue Interface Control Plane" {
-    /* Setup before we can create the queue on both sides */
-    // in coreid is the coreid of the client side
-    // 
-    rpc setup(in uint32 coreid, in uint64 flags, out uint64 features, 
-              out uint32 default_qsize, out uint32 default_bufsiz,      
-              out bool reconnect, out String reconnect_name[256]);
-
-    /* Create a device queue */
-    rpc create(in cap rx, in cap tx, in uint64 flags,
-               in uint64 size, out errval err);
-
-    
-    /* Destroy a device queue */
-    rpc destroy();
-    
-    /* Add a memory region to the device queue 
-       cann not use register as name since it will be a problem
-       with compiling it */
-    rpc reg(in cap mem, in uint32 region_id, out errval err);
-    rpc dereg(in uint32 region_id, out errval err);
-    /* Control messages to the other end */
-    rpc control(in uint64 cmd, in uint64 value, out errval err);    
-
-};
diff --git a/if/devif_data.if b/if/devif_data.if
deleted file mode 100644 (file)
index e2d0142..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/** \file
- *  \brief Device Queue message interface data plane
- */
-
-/*
- * Copyright (c) 2016, 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, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
- */
-
-interface devif_data "Device Queue Interface Data Plane" {
-
-    /* Notify other end of the queue about new entries */
-    message notify(uint8 num_slots);
-
-};
diff --git a/include/devif/backends/net/sfn5122f_devif.h b/include/devif/backends/net/sfn5122f_devif.h
new file mode 100644 (file)
index 0000000..a0facb9
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2016 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+#ifndef SFN5122F_DEVIF_H_
+#define SFN5122F_DEVIF_H_ 1
+
+struct sfn5122f_queue;
+
+errval_t sfn5122f_queue_create(struct sfn5122f_queue** q, bool userspace, bool interrupts);
+errval_t sfn5122f_queue_destroy(struct sfn5122f_queue* q);
+#endif
index 3d84879..bb1712b 100644 (file)
 
 #include <barrelfish/barrelfish.h>
 
-#define MAX_DEVICE_NAME 256
-
-#define ENDPOINT_TYPE_FORWARD 0x1
-#define ENDPOINT_TYPE_BLOCK 0x3
-#define ENDPOINT_TYPE_DEVICE 0x4
-#define ENDPOINT_TYPE_DIRECT 0x5
-
-// the user side of the queue
-#define ENDPOINT_TYPE_USER 0xF
-// only internal?
-#define ENDPOINT_TYPE_FORWARD_TX 0x11
-
-
 #define DEVQ_BUF_FLAG_TX 0x1
 #define DEVQ_BUF_FLAG_RX 0x2
 #define DEVQ_BUF_FLAG_TX_LAST 0x4
-#define DEVQ_SETUP_FLAGS_DIRECT 0x1
-
-#define DEVQ_FEATURE_DIRECT 0x1
 
 
 typedef uint32_t regionid_t;
 typedef uint32_t bufferid_t;
 
+
 struct devq;
+struct region_pool;
 
+// For convinience reason buffer descritpion in one struct
 struct devq_buf{
     regionid_t rid; // 4
     bufferid_t bid; // 8
@@ -51,66 +38,19 @@ struct devq_buf{
  * Backend function definitions
  * ===========================================================================
  */
+// Creation and Destruction of queues is device specific
 
-// These functions must be implemented by the driver which is using the library
-
- /**
-  * @brief Setup function called on the device side
-  *
-  * @param coreid           The core the client side is running on
-  * @param flags            Flags to prepare for create
-  * @param features         Return pointer to the features of the device
-  * @param default_qsize    Return pointer to the default hardware device 
-  *                         queue size
-  * @param default_bufsize  Return pointer to the default buffer size used by the
-  *                         device
-  * @param reconnect        Return pointer to a bool that inicates if the other 
-  *                         other endpoint has to reconnect to another serivce
-  *                         (i.e. reconnect from device_manager to queue_manager)
-  * @param name             String of the service to reconnect to
-  *
-  * @returns error on failure or SYS_ERR_OK on success
-  */
-typedef errval_t (*devq_setup_t)(uint32_t coreid, uint64_t flags,
-                                 uint64_t *features, uint32_t* default_qsize, 
-                                 uint32_t* default_bufsize, bool* reconnect, char* name);
-
- /**
-  * @brief Create function that initializes the queue on the device side, or 
-  *        for direct queues get all the necessary state so that direct function calls
-  *        to the hardware registers can be used. To set this state up, 
-  *        communication to other services might be necessary (e.g. device_manager).
-  *        The pointer to the device specific state can be aquired by devq_get_state()
-  *        
-  * @param q         The device queue to create the device state from
-  * @param flags     Flags that inidicate which features the queue should have
-  *                  enabled
-  *
-  * @returns error on failure or SYS_ERR_OK on success
-  */
-typedef errval_t (*devq_create_t)(struct devq *q, uint64_t flags);
- /**
-  * @brief Destroy function that cleans up all the resouces used by the queue.
-  *        Similar to create, for direct endpoint types further communication
-  *        is necessary in this function
-  *        
-  * @param q         The device queue to destroy
-  *
-  * @returns error on failure or SYS_ERR_OK on success
-  */
-typedef errval_t (*devq_destroy_t)(struct devq *q);
-   
  /**
   * @brief Notifies the device of new descriptors in the queue. 
-  *        On a notificaton, the device can dequeue num_slots descritpors
+  *        On a notificaton, the device can dequeue descritpors
   *        from the queue. NOTE: Does nothing for direct queues since there
   *        is no other endpoint to notify! (i.e. it is the same process)
   *        
-  * @param q         The device queue to destroy
+  * @param q         The device queue
   *
   * @returns error on failure or SYS_ERR_OK on success
   */
-typedef errval_t (*devq_notify_t) (struct devq *q, uint8_t num_slots);
+typedef errval_t (*devq_notify_t) (struct devq *q);
 
  /**
   * @brief Registers a memory region. For direct queues this function 
@@ -148,7 +88,8 @@ typedef errval_t (*devq_deregister_t)(struct devq *q, regionid_t region_id);
   *
   * @returns error on failure or SYS_ERR_OK on success
   */
-typedef errval_t (*devq_control_t)(struct devq *q, uint64_t request,
+typedef errval_t (*devq_control_t)(struct devq *q, 
+                                   uint64_t request,
                                    uint64_t value);
 
 
@@ -186,11 +127,13 @@ typedef errval_t (*devq_dequeue_t)(struct devq *q, regionid_t* region_id,
                                    bufferid_t* buffer_id, lpaddr_t* base, size_t* length,
                                    uint64_t* misc_flags);
 
+/**
+ * Represent the device queue itself
+ */
+
+
 // The functions that the device driver has to export
 struct devq_func_pointer {
-    devq_setup_t setup;
-    devq_create_t create;
-    devq_destroy_t destroy;
     devq_register_t reg;
     devq_deregister_t dereg;
     devq_control_t ctrl;
@@ -199,108 +142,14 @@ struct devq_func_pointer {
     devq_dequeue_t deq;
 };
 
-// The devif device state
-struct endpoint_state {
-    // device type
-    uint8_t endpoint_type;
-    // name of the endpoint
-    char device_name[MAX_DEVICE_NAME];
-    // features of the endpoint
-    uint64_t features;
-    // setup function pointer
-    struct devq_func_pointer f;
-    // bool to check export
-    bool export_done;
-    // binding
-    struct devif_ctrl_binding* ctrl;
-    struct devif_data_binding* data;
+struct devq {
+    // Region management
+    struct region_pool* pool;
+    // Funciton pointers
+    struct devq_func_pointer f;   
 };
 
- /*
- * ===========================================================================
- * Device queue interface export (for devices)
- * ===========================================================================
- */
- /**
-  * @brief exports the devq interface so others (client side) can connect
-  *
-  * @param s             An endpoint state containing all the information
-  *                      of a device including function pointers
-  *
-  * @returns error on failure or SYS_ERR_OK on success
-  */
-
-errval_t devq_driver_export(struct endpoint_state* s);
-
-/* ===========================================================================
- * Device queue creation and destruction
- * ===========================================================================
- */
-
- /**
-  * @brief creates a queue 
-  *
-  * @param q             Return pointer to the devq (handle)
-  * @param end           Endpoint state containing the function pointers
-  * @param device_name   Device name of the device to which this queue belongs
-  *                      (Driver itself is running in a separate process)
-  * @param device_type   The type of the device
-  * @param flags         Anything you can think of that makes sense for the device
-  *                      and its driver?
-  *
-  * @returns error on failure or SYS_ERR_OK on success
-  */
-
-errval_t devq_create(struct devq **q,
-                     struct endpoint_state* end,
-                     char* device_name,
-                     uint64_t flags);
-
- /**
-  * @brief destroys the device queue
-  *
-  * @param q           The queue state to free (and the device queue to be 
-                       shut down in the driver)
-  *
-  * @returns error on failure or SYS_ERR_OK on success
-  */
-errval_t devq_destroy(struct devq *q);
-
-
-/*
- * ===========================================================================
- * Device specific state
- * ===========================================================================
- */
-
-/**
- * @brief allocate device specific state of size bytes
- *
- * @param q           The device queue to allocate the state for
- * @param bytes       Size of the state to allocate
- *
- */
-void devq_allocate_state(struct devq *q, size_t bytes);
-
-/**
- * @brief get the device specific state for a queue
- *
- * @param q           The device queue to get the state for
- *
- * @returns void pointer to the defice specific state
- */
-void* devq_get_state(struct devq *q);
-
-
-/**
- * @brief set the device specific state for a queue
- *
- * @param q           The device queue to get the state for
- * @param state       The device specific state
- *
- */
-void devq_set_state(struct devq *q, void* state);
-
 /*
  * ===========================================================================
  * Datapath functions
@@ -423,6 +272,4 @@ errval_t devq_control(struct devq *q,
                       uint64_t request,
                       uint64_t value);
 
-
-errval_t devq_event_loop(struct endpoint_state* s);   
 #endif /* QUEUE_INTERFACE_H_ */
diff --git a/include/devif/sfn5122f_devif.h b/include/devif/sfn5122f_devif.h
deleted file mode 100644 (file)
index fa79b48..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2016 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
- */
-#ifndef SFN5122F_DEVIF_DIRECT_H_
-#define SFN5122F_DEVIF_DIRECT_H_ 1
-
-#include <devif/queue_interface.h>
-
-errval_t sfn5122f_create_direct(struct devq* q, uint64_t flags);
-errval_t sfn5122f_register_direct(struct devq* q, struct capref cap,
-                                  regionid_t rid);
-errval_t sfn5122f_deregister_direct(struct devq* q, regionid_t rid);
-errval_t sfn5122f_control_direct(struct devq* q, uint64_t cmd, uint64_t value);
-errval_t sfn5122f_destroy_direct(struct devq* q);
-errval_t sfn5122f_notify_direct(struct devq* q, uint8_t num_slots);
-errval_t sfn5122f_enqueue_direct(struct devq* q, regionid_t rid, bufferid_t bid, 
-                                 lpaddr_t base, size_t len, uint64_t flags);
-errval_t sfn5122f_dequeue_direct(struct devq* q, regionid_t* rid, bufferid_t* bid, 
-                                 lpaddr_t* base, size_t* len, uint64_t* flags);
-#endif
index 1c1fd4c..a332c7e 100644 (file)
     build library { 
         target = "devif",
         cFiles = ["queue_interface.c", "region_pool.c", 
-                  "region.c", "desc_queue.c", "loopback_device.c"],
-        addCFlags = [ "-DLIBRARY" ],
-        flounderBindings = [ "devif_ctrl", "devif_data" ],
-        flounderExtraBindings = [ ("devif_ctrl", ["rpcclient"]) ],
-        flounderDefs = [ "devif_ctrl", "devif_data" ],
-        flounderExtraDefs = [ ("devif_ctrl", ["rpcclient"]) ]
+                  "region.c"],
+        addCFlags = [ "-DLIBRARY" ]
+    },
+
+    build library { 
+        target = "devif_internal",
+        cFiles = ["queue_interface_internal.c", "region_pool.c", 
+                  "region.c"],
+        addCFlags = [ "-DLIBRARY" ]
     }
 ]
diff --git a/lib/devif/backends/idc/Hakefile b/lib/devif/backends/idc/Hakefile
new file mode 100644 (file)
index 0000000..76a4ea8
--- /dev/null
@@ -0,0 +1,22 @@
+--------------------------------------------------------------------------
+-- Copyright (c) 2016, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+--
+-- Hakefile for lib/device_interfaces
+-- 
+-- Provides a general interface for device drivers.
+--
+--------------------------------------------------------------------------
+
+[
+    build library { 
+        target = "devif_backend_idc",
+        cFiles = ["desc_queue.c"],
+        addCFlags = [ "-DLIBRARY" ],
+        addIncludes = [ "/lib/devif/" ]       
+    }
+]
similarity index 77%
rename from lib/devif/desc_queue.c
rename to lib/devif/backends/idc/desc_queue.c
index 8710c07..6983384 100644 (file)
@@ -11,6 +11,7 @@
 #include <devif/queue_interface.h>
 #include "desc_queue.h"
 #include "dqi_debug.h"
+#include "../../queue_interface_internal.h"
 
 
 struct __attribute__((aligned(DESCQ_ALIGNMENT))) desc {
@@ -27,92 +28,40 @@ union __attribute__((aligned(DESCQ_ALIGNMENT))) pointer {
     uint8_t pad[64];
 };
 
-struct descq {
-    // Shared memory of the queue
-    size_t slots;
-
-    size_t local_head;
-    size_t local_tail;
-    // Queue pointers
-    volatile union pointer* head;
-    volatile union pointer* tail;
-
-    // The queue itself
-    struct desc* descs;
-};
-
 
 /**
- * @brief initialized a descriptor queue
+ * @brief Check if the descriptor queue is full
  *
- * @param q                     Return pointer to the descriptor queue
- * @param shm                   Cap of the shared memory of the queue
- * @param slots                 Number of slots in the queue
+ * @param q                     The descriptor queue
  *
- * @returns error on failure or SYS_ERR_OK on success
+ * @returns true if the queue is full, otherwise false
  */
-errval_t descq_init(struct descq** q,
-                    struct capref shm,
-                    size_t slots)
+static bool descq_full(struct descq* q)
 {
-    errval_t err;
-    struct descq* tmp;
-    
-    // Init basic struct fields
-    tmp = malloc(sizeof(struct descq));
-    assert(tmp != NULL);
-
-    tmp->slots = slots-2;
-
-    struct frame_identity id;
-    // Check if the frame is big enough
-    err = invoke_frame_identify(shm, &id);
-    if (err_is_fail(err)) {
-        free(tmp);
-        return DEVQ_ERR_DESCQ_INIT;
-    } 
-
-    if (id.bytes < DESCQ_ALIGNMENT*slots) {
-        free(tmp);
-        return DEVQ_ERR_DESCQ_INIT;
-    }
-
-    // TODO what about the non cache coherent case?
-    err = vspace_map_one_frame_attr((void**) &(tmp->head),
-                                    slots*DESCQ_ALIGNMENT, shm, 
-                                    VREGION_FLAGS_READ_WRITE, NULL, NULL);
-    if (err_is_fail(err)) {
-        free(tmp);
-        return DEVQ_ERR_DESCQ_INIT;
+    size_t head = q->local_head;
+    size_t tail = q->tail->value;
+    if (head >= tail) {
+        return ((q->slots - (head - tail)) == 0);
+    } else {
+        return ((q->slots - (head + q->slots - tail)) == 0);
     }
-
-    tmp->tail = tmp->head + 1;
-    tmp->descs = (struct desc*) tmp->head + 2;
-    tmp->tail->value = 0;
-    tmp->head->value = 0;    
-    tmp->local_head = 0;
-    tmp->local_tail = 0;
-
-    DQI_DEBUG_QUEUE("Head=%p Tail=%p Descs=%p \n",
-                    tmp->head, tmp->tail, tmp->descs);
-
-    *q = tmp;
-    return SYS_ERR_OK;
 }
-
-
 /**
- * @brief Destroys a descriptor queue and frees its resources
+ * @brief Check if the descriptor queue is empty
  *
  * @param q                     The descriptor queue
  *
- * @returns error on failure or SYS_ERR_OK on success
+ * @returns true if the queue is empty, otherwise false
  */
-errval_t descq_destroy(struct descq* q)
-{   
-    free(q);
-
-    return SYS_ERR_OK;
+static bool descq_empty(struct descq* q)
+{
+    size_t head = q->head->value;
+    size_t tail = q->local_tail;
+    if (head >= tail) {
+        return ((head - tail) == 0);
+    } else {
+        return (((head + q->slots) - tail) == 0);
+    }
 }
 
 /**
@@ -128,13 +77,14 @@ errval_t descq_destroy(struct descq* q)
  *
  * @returns error if queue is full or SYS_ERR_OK on success
  */
-errval_t descq_enqueue(struct descq* q,
-                       regionid_t region_id,
-                       bufferid_t buffer_id,
-                       lpaddr_t base,
-                       size_t len,
-                       uint64_t misc_flags)
+static errval_t descq_enqueue(struct devq* queue,
+                              regionid_t region_id,
+                              bufferid_t buffer_id,
+                              lpaddr_t base,
+                              size_t len,
+                              uint64_t misc_flags)
 {
+    struct descq* q = (struct descq*) queue;
     if (descq_full(q)) {
         return DEVQ_ERR_TX_FULL;
     }
@@ -169,13 +119,14 @@ errval_t descq_enqueue(struct descq* q,
  *
  * @returns error if queue is empty or SYS_ERR_OK on success
  */
-errval_t descq_dequeue(struct descq* q,
-                       regionid_t* region_id,
-                       bufferid_t* buffer_id,
-                       lpaddr_t* base,
-                       size_t* len,
-                       uint64_t* misc_flags)
+static errval_t descq_dequeue(struct devq* queue,
+                              regionid_t* region_id,
+                              bufferid_t* buffer_id,
+                              lpaddr_t* base,
+                              size_t* len,
+                              uint64_t* misc_flags)
 {
+    struct descq* q = (struct descq*) queue;
     if (descq_empty(q)) {
         return DEVQ_ERR_RX_EMPTY;
     }
@@ -195,6 +146,29 @@ errval_t descq_dequeue(struct descq* q,
     return SYS_ERR_OK;
 }
 
+
+static errval_t descq_notify(struct devq* q)
+{
+    return SYS_ERR_OK;
+}
+
+static errval_t descq_control(struct devq* q, uint64_t cmd,
+                              uint64_t value)
+{
+    return SYS_ERR_OK;
+}
+
+static errval_t descq_register(struct devq* q, struct capref cap,
+                               regionid_t rid)
+{
+    return SYS_ERR_OK;
+}
+
+static errval_t descq_deregister(struct devq* q, regionid_t rid)
+{
+    return SYS_ERR_OK;
+}
+
 /**
  * @brief Writes the local head pointer into the shared memory
  *        making the state of the queue visible to the other end
@@ -202,12 +176,13 @@ errval_t descq_dequeue(struct descq* q,
  * @param q                     The descriptor queue
  *
  */
-void descq_writeout_head(struct descq* q)
+/*
+static void descq_writeout_head(struct descq* q)
 {
     q->head->value = q->local_head;
     DQI_DEBUG_QUEUE("Global_head=%lu \n", q->local_head);
 }
-
+*/
 /**
  * @brief Writes the local tail pointer into the shared memory
  *        making the state of the queue visible to the other end
@@ -215,60 +190,112 @@ void descq_writeout_head(struct descq* q)
  * @param q                     The descriptor queue
  *
  */
-void descq_writeout_tail(struct descq* q)
+/*
+static void descq_writeout_tail(struct descq* q)
 {
     q->tail->value = q->local_tail;
     DQI_DEBUG_QUEUE("Global_tail=%lu \n", q->local_tail);
 }
-
+*/
 /**
- * @brief Check if the descriptor queue is full
+ * @brief Returns the number of occupied slots in the queue
  *
  * @param q                     The descriptor queue
  *
- * @returns true if the queue is full, otherwise false
+ * @returns the number of occupied slots
  */
-bool descq_full(struct descq* q)
+/*
+static size_t descq_full_slots(struct descq* q)
 {
     size_t head = q->local_head;
-    size_t tail = q->tail->value;
+    size_t tail = q->head->value;
     if (head >= tail) {
-        return ((q->slots - (head - tail)) == 0);
+        return (head - tail);
     } else {
-        return ((q->slots - (head + q->slots - tail)) == 0);
+        return (head + q->slots) - tail;
     }
 }
+*/
+
+
 /**
- * @brief Check if the descriptor queue is empty
+ * @brief initialized a descriptor queue
  *
- * @param q                     The descriptor queue
+ * @param q                     Return pointer to the descriptor queue
+ * @param slots                 Number of slots in the queue
  *
- * @returns true if the queue is empty, otherwise false
+ * @returns error on failure or SYS_ERR_OK on success
  */
-bool descq_empty(struct descq* q)
+errval_t devif_descq_create(struct descq** q,
+                           size_t slots)
 {
-    size_t head = q->head->value;
-    size_t tail = q->local_tail;
-    if (head >= tail) {
-        return ((head - tail) == 0);
-    } else {
-        return (((head + q->slots) - tail) == 0);
+    // TODO init frames
+    errval_t err;
+    struct descq* tmp;
+    struct capref shm;    
+
+    // Init basic struct fields
+    tmp = malloc(sizeof(struct descq));
+    assert(tmp != NULL);
+
+    tmp->slots = slots-2;
+
+    struct frame_identity id;
+    // Check if the frame is big enough
+    err = invoke_frame_identify(shm, &id);
+    if (err_is_fail(err)) {
+        free(tmp);
+        return DEVQ_ERR_DESCQ_INIT;
+    } 
+
+    if (id.bytes < DESCQ_ALIGNMENT*slots) {
+        free(tmp);
+        return DEVQ_ERR_DESCQ_INIT;
     }
+
+    // TODO what about the non cache coherent case?
+    err = vspace_map_one_frame_attr((void**) &(tmp->head),
+                                    slots*DESCQ_ALIGNMENT, shm, 
+                                    VREGION_FLAGS_READ_WRITE, NULL, NULL);
+    if (err_is_fail(err)) {
+        free(tmp);
+        return DEVQ_ERR_DESCQ_INIT;
+    }
+
+    tmp->tail = tmp->head + 1;
+    tmp->descs = (struct desc*) tmp->head + 2;
+    tmp->tail->value = 0;
+    tmp->head->value = 0;    
+    tmp->local_head = 0;
+    tmp->local_tail = 0;
+
+   
+    devq_init(&tmp->q);
+
+    tmp->q.f.enq = descq_enqueue;
+    tmp->q.f.deq = descq_dequeue;
+    tmp->q.f.notify = descq_notify;
+    tmp->q.f.reg = descq_register;
+    tmp->q.f.dereg = descq_deregister;
+    tmp->q.f.ctrl = descq_control;
+
+    *q = tmp;
+
+
+    return SYS_ERR_OK;
 }
+
+
 /**
- * @brief Returns the number of occupied slots in the queue
+ * @brief Destroys a descriptor queue and frees its resources
  *
  * @param q                     The descriptor queue
  *
- * @returns the number of occupied slots
+ * @returns error on failure or SYS_ERR_OK on success
  */
-size_t descq_full_slots(struct descq* q)
-{
-    size_t head = q->local_head;
-    size_t tail = q->head->value;
-    if (head >= tail) {
-        return (head - tail);
-    } else {
-        return (head + q->slots) - tail;
-    }
+errval_t devif_descq_destroy(struct descq* q)
+{   
+    free(q);
+
+    return SYS_ERR_OK;
 }
diff --git a/lib/devif/backends/idc/desc_queue.h b/lib/devif/backends/idc/desc_queue.h
new file mode 100644 (file)
index 0000000..0572e9e
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+#ifndef DESCQ_H_
+#define DESCQ_H_ 1
+
+
+#include <barrelfish/barrelfish.h>
+#include <devif/queue_interface.h>
+
+#define DESCQ_DEFAULT_SIZE 64
+#define DESCQ_ALIGNMENT 64
+
+struct descq {
+    struct devq q;
+    // Shared memory of the queue
+    size_t slots;
+
+    size_t local_head;
+    size_t local_tail;
+    // Queue pointers
+    volatile union pointer* head;
+    volatile union pointer* tail;
+
+    // The queue itself
+    struct desc* descs;
+};
+/**
+ * @brief initialized a descriptor queue
+ *
+ * @param q                     Return pointer to the descriptor queue
+ * @param slots                 Number of slots in the queue
+ *
+ * @returns error on failure or SYS_ERR_OK on success
+ */
+errval_t devif_descq_create(struct descq** q,
+                            size_t slots);
+
+/**
+ * @brief Destroys a descriptor queue and frees its resources
+ *
+ * @param q                     The descriptor queue
+ *
+ * @returns error on failure or SYS_ERR_OK on success
+ */
+errval_t devif_descq_destroy(struct descq* q);
+
+
+#endif /* DESCQ_H_ */
diff --git a/lib/devif/backends/net/solarflare/Hakefile b/lib/devif/backends/net/solarflare/Hakefile
new file mode 100644 (file)
index 0000000..e458a8a
--- /dev/null
@@ -0,0 +1,28 @@
+--------------------------------------------------------------------------
+-- Copyright (c) 2016, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+--
+-- Hakefile for lib/device_interfaces
+-- 
+-- Solarflare backend implementation
+--
+--------------------------------------------------------------------------
+
+  [ 
+    build library { target = "devif_backend_solarflare",
+                      cFiles = [ "devif_backend_solarflare.c", "helper.c"],
+                      flounderBindings = [ "sfn5122f_devif"],
+                      flounderExtraBindings = [ ("sfn5122f_devif", ["rpcclient"])],
+                      flounderDefs = [ "sfn5122f_devif" ],
+                      flounderExtraDefs = [ ("sfn5122f_devif",["rpcclient"]) ],
+                      mackerelDevices = [ "sfn5122f", "sfn5122f_q"],
+                      addLibraries = libDeps ["pci", "skb", "devif_internal"],
+                      addIncludes = ["/lib/devif/"]
+                    }
+  ]
+
+
diff --git a/lib/devif/backends/net/solarflare/devif_backend_solarflare.c b/lib/devif/backends/net/solarflare/devif_backend_solarflare.c
new file mode 100644 (file)
index 0000000..8d27cd9
--- /dev/null
@@ -0,0 +1,461 @@
+/*
+ * Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 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.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/waitset.h>
+#include <barrelfish/nameservice_client.h>
+#include <devif/queue_interface.h>
+#include <if/sfn5122f_devif_defs.h>
+#include <if/sfn5122f_devif_rpcclient_defs.h>
+#include <devif/backends/net/sfn5122f_devif.h>
+#include "../../../queue_interface_internal.h"
+#include "hw_queue.h"
+#include "helper.h"
+
+#define DEBUG_SFN
+#ifdef DEBUG_SFN
+    #define DEBUG_QUEUE(x...) printf("sfn5122f_q : " x)
+#else
+    #define DEBUG_QUEUE(x...) do {} while (0)
+#endif
+
+
+// TX Queue
+#define TX_ENTRIES 2048
+#define RX_ENTRIES 2048
+// Event Queue
+#define EV_CODE_RX 0
+#define EV_CODE_TX 2
+#define EV_CODE_DRV 5
+#define EV_CODE_DRV_GEN 7
+#define EV_CODE_USER 8
+#define EV_CODE_MCDI 12
+#define EV_CODE_GLOBAL 6
+
+#define BUF_SIZE 4096
+
+/* for each TX/RX entry one entry plus an additonal 2 for mcdi completion
+and link state events */
+#define EV_ENTRIES 4096
+
+/**  Misc             */
+static errval_t update_rxtail(struct sfn5122f_queue* q, size_t tail)
+{
+    assert(q->device != NULL);
+    uint64_t reg = 0;
+
+    reg = sfn5122f_rx_desc_upd_reg_hi_rx_desc_wptr_insert(reg, tail);
+    /* don't want to push an additional rx descriptor with the write pointer */
+    reg = sfn5122f_rx_desc_upd_reg_hi_rx_desc_push_cmd_insert(reg, 0);
+    /* the lower register will be ignored   */
+    sfn5122f_rx_desc_upd_reg_lo_wr(q->device, q->id, 0);
+    sfn5122f_rx_desc_upd_reg_hi_wr(q->device, q->id, reg);
+
+    return SYS_ERR_OK;
+}
+
+static errval_t update_txtail(struct sfn5122f_queue* q, size_t tail)
+{
+    assert(q->device != NULL);
+    uint64_t reg = 0;
+    reg = sfn5122f_tx_desc_upd_reg_hi_tx_desc_wptr_insert(reg, tail);
+    /* don't want to push an additional tx descriptor with the write pointer */
+    reg = sfn5122f_tx_desc_upd_reg_hi_tx_desc_push_cmd_insert(reg, 0);
+    reg = sfn5122f_tx_desc_upd_reg_hi_tx_desc_insert(reg, 0);
+
+    /*  the lower register will be ignored  */
+    sfn5122f_tx_desc_upd_reg_lo_wr(q->device, q->id, 0);
+    sfn5122f_tx_desc_upd_reg_hi_wr(q->device, q->id, reg);
+    return SYS_ERR_OK;
+}
+
+static void bind_cb(void *st, errval_t err, struct sfn5122f_devif_binding *b)
+{
+    
+    struct sfn5122f_queue* queue = st;
+    b->st = queue;
+    // Initi RPC client
+    
+    queue->b = b;
+    queue->rpc = malloc(sizeof(struct sfn5122f_devif_rpc_client));
+    assert(queue->rpc != NULL);
+
+    err = sfn5122f_devif_rpc_client_init(queue->rpc, b);
+    if (err_is_fail(err)) {
+       free(queue->rpc);
+    }   
+    queue->bound = true;   
+}
+
+
+static errval_t sfn5122f_register(struct devq* q, struct capref cap,
+                                  regionid_t rid) 
+{
+    uint64_t buftbl_idx = 0;
+    errval_t err, err2;
+    struct frame_identity id;
+
+    struct sfn5122f_queue* queue = (struct sfn5122f_queue*) q;
+    err = queue->rpc->vtbl.register_region(queue->rpc, queue->id, cap, 
+                                           &buftbl_idx, &err2);
+    if (err_is_fail(err) || err_is_fail(err2)) {
+        err = err_is_fail(err) ? err: err2;
+        return err;
+    }
+
+    err = invoke_frame_identify(cap, &id);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    // Setup datastructure for translating region ID to buffer table entry id
+    // Currently only a linked list
+    struct region_entry* entry = malloc(sizeof(struct region_entry));
+    entry->rid = rid;
+    entry->phys = id.base;
+    entry->size = id.bytes;
+    entry->cap = cap;
+    entry->buftbl_idx = buftbl_idx;
+    entry->next = NULL;
+    
+    struct region_entry* cur = queue->regions;
+
+    if (cur == NULL) {
+        queue->regions = entry;
+        return SYS_ERR_OK;
+    }
+
+    while (cur->next != NULL) {
+        cur = cur->next;
+    }  
+    
+    cur->next = entry;
+    
+    return SYS_ERR_OK;
+}
+
+static errval_t sfn5122f_deregister(struct devq* q, regionid_t rid) 
+{
+    errval_t err, err2;
+    
+    struct sfn5122f_queue* queue = (struct sfn5122f_queue*) q;
+
+    // find region and translate to buftlb entry 
+    struct region_entry* cur = queue->regions;
+
+    if (cur == NULL) {
+        return SFN_ERR_DEREGISTER_REGION;
+    }
+
+    while (cur->next != NULL && cur->rid != rid) {
+        cur = cur->next;
+    }  
+   
+    // do rpc do inform carddriver to remove buftbl entries
+    err = queue->rpc->vtbl.deregister_region(queue->rpc, cur->buftbl_idx, cur->size,
+                                             &err2);
+    if (err_is_fail(err) || err_is_fail(err2)) {
+        err = err_is_fail(err) ? err: err2;
+        return err;
+    }
+
+    return SYS_ERR_OK;
+}
+
+
+static errval_t sfn5122f_control(struct devq* q, uint64_t cmd, uint64_t value)
+{
+    return SYS_ERR_OK;
+}
+
+
+static errval_t sfn5122f_notify(struct devq* q)
+{
+    return SYS_ERR_OK;
+}
+
+static errval_t enqueue_rx_buf(struct sfn5122f_queue* q, regionid_t rid,
+                               bufferid_t bid, lpaddr_t base, size_t len, 
+                               uint64_t flags)
+{
+
+    DEBUG_QUEUE("Enqueueing RX buf \n");
+    // check if there is space
+    if (sfn5122f_queue_free_rxslots(q) == 0) {
+        printf("SFN5122F_%d: Not enough space in RX ring, not adding buffer\n", 
+                q->id);
+        return SFN_ERR_ENQUEUE;
+    }
+
+    // find region
+    struct region_entry* entry = q->regions;
+    
+    while((entry->next != NULL) && (entry->rid != rid)) {
+        entry = entry->next;
+    }
+    
+    if (entry == NULL) {
+        return SFN_ERR_ENQUEUE;
+    }
+    
+    // compute buffer table entry of the rx buffer and the within it offset
+    uint64_t buftbl_idx = entry->buftbl_idx + (bid/BUF_SIZE);
+    uint16_t offset = bid & 0x00000FFF;    
+
+    
+    DEBUG_QUEUE("RX_BUF tbl_idx=%lu offset=%d flags=%lu \n", 
+                buftbl_idx, offset, flags);
+    sfn5122f_queue_add_user_rxbuf_devif(q, buftbl_idx, offset,
+                                        rid, bid, base, len, flags);
+    sfn5122f_queue_bump_rxtail(q);
+    return SYS_ERR_OK;
+}
+
+
+static errval_t enqueue_tx_buf(struct sfn5122f_queue* q, regionid_t rid,
+                               bufferid_t bid, lpaddr_t base, size_t len, 
+                               uint64_t flags)
+{
+    DEBUG_QUEUE("Enqueueing TX buf \n");
+    // check if there is space
+    if (sfn5122f_queue_free_txslots(q) == 0) {
+        printf("SFN5122F_%d: Not enough space in TX ring, not adding buffer\n", 
+                q->id);
+        return SFN_ERR_ENQUEUE;
+    }
+
+    // find region
+    struct region_entry* entry = q->regions;
+    
+    while((entry->next != NULL) && (entry->rid != rid)) {
+        entry = entry->next;
+    }
+    
+    if (entry == NULL) {
+        return SFN_ERR_ENQUEUE;
+    }
+    
+    // compute buffer table entry of the rx buffer and the within it offset
+    uint64_t buftbl_idx = entry->buftbl_idx + (bid/BUF_SIZE);
+    uint16_t offset = bid & 0x00000FFF;    
+
+    DEBUG_QUEUE("TX_BUF tbl_idx=%lu offset=%d flags=%lu \n", buftbl_idx, offset,
+                flags);
+    sfn5122f_queue_add_user_txbuf_devif(q, buftbl_idx, offset,
+                                        rid, bid, base, len, flags);
+    sfn5122f_queue_bump_txtail(q);
+    return SYS_ERR_OK;
+}
+
+
+static errval_t sfn5122f_enqueue(struct devq* q, regionid_t rid, bufferid_t bid, 
+                                 lpaddr_t base, size_t len, uint64_t flags)
+{
+    errval_t err;
+
+    struct sfn5122f_queue* queue = (struct sfn5122f_queue*) q;
+    if (flags & DEVQ_BUF_FLAG_RX) {
+        err = enqueue_rx_buf(queue, rid, bid, base, len, flags);
+        if (err_is_fail(err)) {
+            return err;
+        }      
+    } else if (flags & DEVQ_BUF_FLAG_TX) {
+        err = enqueue_tx_buf(queue, rid, bid, base, len, flags);
+        if (err_is_fail(err)) {
+            return err;
+        }      
+    }
+
+    return SYS_ERR_OK;
+}
+
+static errval_t sfn5122f_dequeue(struct devq* q, regionid_t* rid, bufferid_t* bid, 
+                                 lpaddr_t* base, size_t* len, uint64_t* flags)
+{
+    uint8_t ev_code;
+    bool exit = false;
+    errval_t err;    
+    
+    struct sfn5122f_queue* queue = (struct sfn5122f_queue*) q;
+
+    while(!exit) {
+        ev_code = sfn5122f_get_event_code(queue);
+        switch(ev_code){
+        case EV_CODE_RX:
+            // TODO multiple packets
+            err = sfn5122f_queue_handle_rx_ev_devif(queue, rid, bid, base,
+                                                    len, flags);
+            exit = true;  
+            if (err_is_ok(err)) {
+                DEBUG_QUEUE(" RX_EV Q_ID: %d len %ld \n", queue->id, *len);
+            }
+            sfn5122f_queue_bump_evhead(queue);
+            break;
+        case EV_CODE_TX:
+            err = sfn5122f_queue_handle_tx_ev_devif(queue, rid, bid, base, 
+                                                    len, flags);
+            if (err_is_ok(err)) {
+                DEBUG_QUEUE("TX EVENT OK %d \n", queue->id);               
+            } else {
+                DEBUG_QUEUE("TX EVENT ERR %d \n", queue->id);
+            }
+
+            exit = true;
+            sfn5122f_queue_bump_evhead(queue);
+            break;
+        case EV_CODE_DRV:
+            //DEBUG_QUEUE("DRIVER EVENT %d\n", qi);
+            sfn5122f_handle_drv_ev(queue, queue->id);
+            sfn5122f_queue_bump_evhead(queue);
+            break;
+        case EV_CODE_DRV_GEN:
+            DEBUG_QUEUE("DRIVER GENERATED EVENT \n");
+            sfn5122f_queue_bump_evhead(queue);
+            break;
+        case EV_CODE_USER:
+            DEBUG_QUEUE("USER EVENT \n");
+            sfn5122f_queue_bump_evhead(queue);
+            break;
+        case EV_CODE_MCDI:
+            //DEBUG_QUEUE("MCDI EVENT \n");
+            sfn5122f_queue_handle_mcdi_event(queue);
+            sfn5122f_queue_bump_evhead(queue);
+            break;
+        case EV_CODE_GLOBAL:
+            DEBUG_QUEUE("GLOBAL EVENT \n");
+            sfn5122f_queue_bump_evhead(queue);
+            break;
+        }
+        sfn5122f_evq_rptr_reg_wr(queue->device, queue->id, 
+                                 queue->ev_head);
+    }
+
+    return err;
+}
+
+/**
+ * Public functions
+ *
+ */
+
+errval_t sfn5122f_queue_create(struct sfn5122f_queue** q, bool userlevel, 
+                               bool interrupts)
+{
+
+    errval_t err;
+    struct capref tx_frame, rx_frame, ev_frame;
+    size_t tx_size, rx_size, ev_size;
+    void *tx_virt, *rx_virt, *ev_virt;
+    struct sfn5122f_queue* queue;
+    struct frame_identity id;
+
+    struct sfn5122f_queue_ops ops = {
+        .update_txtail = update_txtail,
+        .update_rxtail = update_rxtail
+     };
+   
+    /* Allocate memory for descriptor rings  
+       No difference for userspace networking*/
+    tx_size = sfn5122f_q_tx_ker_desc_size * TX_ENTRIES;
+    tx_virt = alloc_map_frame(VREGION_FLAGS_READ_WRITE, tx_size, &tx_frame);
+    if (tx_virt == NULL) {
+        return SFN_ERR_ALLOC_QUEUE;
+    }
+
+    rx_size = sfn5122f_q_rx_user_desc_size * RX_ENTRIES;
+    rx_virt = alloc_map_frame(VREGION_FLAGS_READ_WRITE, rx_size, &rx_frame);
+    if (rx_virt == NULL) {
+        return SFN_ERR_ALLOC_QUEUE;
+    }
+
+    ev_size = sfn5122f_q_event_entry_size * EV_ENTRIES;
+    ev_virt = alloc_map_frame(VREGION_FLAGS_READ_WRITE, ev_size, &ev_frame);
+    if (ev_virt == NULL) {
+        return SFN_ERR_ALLOC_QUEUE;
+    }
+
+    // Init queue
+    queue = sfn5122f_queue_init(tx_virt, TX_ENTRIES, rx_virt, RX_ENTRIES,
+                                ev_virt, EV_ENTRIES, &ops,  NULL, true);
+
+    queue->bound = false;
+
+    iref_t iref;
+    const char *name = "sfn5122f_sfn5122fmng_devif";
+
+    // Connect to solarflare card driver
+    err = nameservice_blocking_lookup(name, &iref);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    err = sfn5122f_devif_bind(iref, bind_cb, q, get_default_waitset(),
+                              1);
+
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    // wait until bound
+    while(!queue->bound) {
+        event_dispatch(get_default_waitset());
+    }
+
+    errval_t err2;
+    struct capref regs;
+    // Inform card driver about new queue and get the registers/queue id
+    err = queue->rpc->vtbl.create_queue(queue->rpc, true, rx_frame, tx_frame, ev_frame,
+                                        &queue->id, &regs, &err2);
+    if (err_is_fail(err) || err_is_fail(err2)) {
+        err = err_is_fail(err) ? err: err2;
+        return err;
+    }
+
+    void* va;
+
+    err = invoke_frame_identify(regs, &id);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    err = vspace_map_one_frame_attr(&va, id.bytes, regs, 
+                                    VREGION_FLAGS_READ_WRITE, NULL, NULL);
+    if (err_is_fail(err)) {
+        return err;
+    }
+  
+    queue->device = malloc(sizeof(sfn5122f_t));
+    sfn5122f_initialize(queue->device, va);
+
+    err = devq_init(&queue->q);
+    if (err_is_fail(err)) {
+        return err;
+    }
+    
+    queue->q.f.enq = sfn5122f_enqueue;
+    queue->q.f.deq = sfn5122f_dequeue;
+    queue->q.f.reg = sfn5122f_register;
+    queue->q.f.dereg = sfn5122f_deregister;
+    queue->q.f.ctrl = sfn5122f_control;
+    queue->q.f.notify = sfn5122f_notify;
+    
+    *q = queue;
+
+    return SYS_ERR_OK;
+}
+
+errval_t sfn5122f_queue_destroy(struct sfn5122f_queue* q)
+{
+    USER_PANIC("NIY\n");
+    return SYS_ERR_OK;
+}
+
diff --git a/lib/devif/backends/net/solarflare/helper.c b/lib/devif/backends/net/solarflare/helper.c
new file mode 100644 (file)
index 0000000..9f3bd1b
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2007-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.
+ */
+
+#include "helper.h"
+
+#include <skb/skb.h>
+#include <stdio.h>
+#include <stdint.h>
+
+
+/* allocate a single frame, mapping it into our vspace with given attributes */
+void* alloc_map_frame(vregion_flags_t attr, size_t size, struct capref *retcap)
+{
+    struct capref frame;
+    errval_t r;
+
+    r = frame_alloc(&frame, size, NULL);
+    assert(err_is_ok(r));
+    void *va;
+    r = vspace_map_one_frame_attr(&va, size, frame, attr,
+                                  NULL, NULL);
+    if (err_is_fail(r)) {
+        DEBUG_ERR(r, "vspace_map_one_frame failed");
+        return NULL;
+    }
+
+    if (retcap != NULL) {
+        *retcap = frame;
+    }
+
+    return va;
+}
+
+/* Get APIC id for specified core */
+errval_t get_apicid_from_core(coreid_t cid, uint8_t *apicid)
+{
+    static bool connected = false;
+    errval_t err;
+    unsigned int i;
+
+    if (!connected) {
+        err = skb_client_connect();
+        if (err_is_fail(err)) {
+            return err;
+        }
+        connected = true;
+    }
+
+    err = skb_execute_query("corename(%d,_,apic(ApicID)),write(ApicID).",
+                            cid);
+    if (err_is_fail(err)) {
+        return err;
+    }
+    err = skb_read_output("%u.", &i);
+    *apicid = i;
+    return err;
+}
+
+
+/*****************************************************************************/
+/* Bitmap based allocator */
+
+
+/** Init allocator for n objects. */
+bool bmallocator_init(struct bmallocator *alloc, size_t n)
+{
+    alloc->count = n;
+    alloc->bitmap = calloc((n + BMALLOCATOR_BITS - 1) / BMALLOCATOR_BITS,
+                           BMALLOCATOR_BITS / 8);
+    return alloc->bitmap != NULL;
+}
+
+/** Release memory associated with allocator. */
+void bmallocator_destroy(struct bmallocator *alloc)
+{
+    free(alloc->bitmap);
+    alloc->bitmap = NULL;
+}
+
+/** Allocate object, return index in *n if successful (return true). */
+bool bmallocator_alloc(struct bmallocator *alloc, size_t *n)
+{
+    size_t i;
+    BMALLOCATOR_TYPE bit;
+    size_t idx;
+
+    // This could be improved
+    for (i = 0; i < alloc->count; i++) {
+        bit = 1 << (i % BMALLOCATOR_BITS);
+        idx = i / BMALLOCATOR_BITS;
+
+        if (!(alloc->bitmap[idx] & bit)) {
+            alloc->bitmap[idx] |= bit;
+            *n = i;
+            return true;
+        }
+    }
+    return false;
+}
+
+/** Free object n, return value indicates if it was allocated before. */
+bool bmallocator_free(struct bmallocator *alloc, size_t n)
+{
+    bool result;
+    BMALLOCATOR_TYPE bit;
+    size_t idx;
+
+    if (n >= alloc->count) {
+        return false;
+    }
+
+    bit = (1 << (n % BMALLOCATOR_BITS));
+    idx = n / BMALLOCATOR_BITS;
+
+    result = alloc->bitmap[idx] & bit;
+    alloc->bitmap[idx] &= ~bit;
+
+    return result;
+}
diff --git a/lib/devif/backends/net/solarflare/helper.h b/lib/devif/backends/net/solarflare/helper.h
new file mode 100644 (file)
index 0000000..be8f6c7
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2007-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 HELPER_H_
+#define HELPER_H_
+
+#include <errors/errno.h>
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/vregion.h>
+
+void* alloc_map_frame(vregion_flags_t attr, size_t size, struct capref *retcap);
+
+errval_t get_apicid_from_core(coreid_t cid, uint8_t *apicid);
+
+/* Simple bitmap-based allocator */
+#define BMALLOCATOR_BITS 8
+#define BMALLOCATOR_TYPE uint8_t
+struct bmallocator {
+    BMALLOCATOR_TYPE *bitmap;
+    size_t count;
+};
+
+/** Init allocator for n objects. */
+bool bmallocator_init(struct bmallocator *alloc, size_t n);
+/** Release memory associated with allocator. */
+void bmallocator_destroy(struct bmallocator *alloc);
+/** Allocate object, return index in *n if successful (return true). */
+bool bmallocator_alloc(struct bmallocator *alloc, size_t *n);
+/** Free object n, return value indicates if it was allocated before. */
+bool bmallocator_free(struct bmallocator *alloc, size_t n);
+
+#endif // ndef HELPER_H_
diff --git a/lib/devif/backends/net/solarflare/hw_queue.h b/lib/devif/backends/net/solarflare/hw_queue.h
new file mode 100644 (file)
index 0000000..e798776
--- /dev/null
@@ -0,0 +1,474 @@
+/*
+ *Copyright (c) 2007-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 SFN5122F_CHANNEL_H_
+#define SFN5122F_CHANNEL_H_
+
+
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <devif/queue_interface.h>
+#include <dev/sfn5122f_q_dev.h>
+#include <dev/sfn5122f_dev.h>
+#include "helper.h"
+
+#define MTU_MAX 2048
+
+struct sfn5122f_devif_binding;
+struct sfn5122f_devif_rpc_client;
+struct sfn5122f_queue;
+
+struct sfn5122f_queue_ops {
+    errval_t (*update_txtail)(struct sfn5122f_queue*, size_t);
+    errval_t (*update_rxtail)(struct sfn5122f_queue*, size_t);
+};
+
+struct region_entry {
+    uint32_t rid;
+    lpaddr_t phys;
+    size_t size;
+    uint64_t buftbl_idx;
+    struct capref cap;
+    struct region_entry* next;
+};
+
+struct sfn5122f_queue {
+    struct devq q;
+    union {
+        sfn5122f_q_tx_user_desc_array_t* user;
+        sfn5122f_q_tx_ker_desc_array_t* ker;
+    } tx_ring;
+    struct devq_buf*                tx_bufs;
+    uint16_t                        tx_head;
+    uint16_t                        tx_tail;
+    size_t                          tx_size;
+
+    union {
+        sfn5122f_q_rx_user_desc_array_t* user;
+        sfn5122f_q_rx_ker_desc_array_t* ker;
+    } rx_ring;
+    struct devq_buf*                rx_bufs;
+    uint16_t                        rx_head;
+    uint16_t                        rx_tail;
+    uint16_t                        rx_size;
+
+    sfn5122f_q_event_entry_array_t* ev_ring;
+    uint32_t                        ev_head;
+    uint32_t                        ev_tail;
+    size_t                          ev_size;
+
+    struct sfn5122f_queue_ops       ops;
+    void*                           opaque;
+    bool                            userspace;
+
+    // state for devif interface
+    struct sfn5122f_devif_binding* b;
+    struct sfn5122f_devif_rpc_client* rpc;
+    bool bound;
+
+    // Direct interface fields
+    uint16_t id;
+    sfn5122f_t *device;
+    struct region_entry* regions;
+};
+
+typedef struct sfn5122f_queue sfn5122f_queue_t;
+
+static inline sfn5122f_queue_t* sfn5122f_queue_init(void* tx, 
+                                                    size_t tx_size,
+                                                    void* rx, 
+                                                    size_t rx_size, 
+                                                    void* ev, 
+                                                    size_t ev_size,
+                                                    struct sfn5122f_queue_ops* ops, 
+                                                    void* opaque, bool userspace)
+{
+
+    sfn5122f_queue_t* q = malloc(sizeof(*q));
+
+    if (userspace) {
+        q->tx_ring.user = tx;
+    } else {
+        q->tx_ring.ker = tx;
+    }
+    q->tx_bufs = malloc(sizeof(struct devq_buf) * tx_size);
+    q->tx_head = 0;
+    q->tx_tail = 0;
+    q->tx_size = tx_size;
+
+    if (userspace) {
+        q->rx_ring.user = rx;
+    } else {
+        q->rx_ring.ker = rx;
+    }
+    q->rx_bufs = malloc(sizeof(struct devq_buf) * rx_size);
+    q->rx_head = 0;
+    q->rx_tail = 0;
+    q->rx_size = rx_size;
+  
+    q->ev_ring = ev;
+    q->ev_head = 0;
+    q->ev_tail = 0;
+    q->ev_size = ev_size;
+    q->userspace = userspace; 
+
+    q -> ops = *ops;
+    if(!userspace) {
+        q->opaque = opaque;
+    }
+
+    // Initialize ring memory with 0xff
+    if(!userspace){
+       memset(tx, 0xff, tx_size * sfn5122f_q_tx_ker_desc_size);
+       memset(rx, 0xff, rx_size * sfn5122f_q_rx_ker_desc_size);
+    }else{
+       memset(tx, 0xff, tx_size * sfn5122f_q_tx_user_desc_size);
+       memset(rx, 0xff, rx_size * sfn5122f_q_rx_user_desc_size);
+    }
+    /* all 0 is potential valid event */
+    memset(ev, 0xff, ev_size * sfn5122f_q_event_entry_size);
+    return q;
+}
+
+static inline uint8_t sfn5122f_get_event_code(sfn5122f_queue_t* queue)
+{             
+       sfn5122f_q_event_entry_t ev;
+       ev = queue->ev_ring[queue->ev_head];
+       return sfn5122f_q_event_entry_ev_code_extract(ev);
+}
+
+
+static inline errval_t sfn5122f_queue_bump_txtail(sfn5122f_queue_t* q)
+{
+    return q->ops.update_txtail(q, q->tx_tail);
+}
+
+
+static inline errval_t sfn5122f_queue_bump_rxtail(sfn5122f_queue_t* q)
+{
+    return q->ops.update_rxtail(q, q->rx_tail);
+}
+
+
+static inline errval_t sfn5122f_handle_drv_ev(sfn5122f_queue_t* q, uint16_t n)
+{   
+    size_t ev_head = q->ev_head;
+
+    sfn5122f_q_event_entry_t code;
+    code = q->ev_ring[ev_head]; 
+
+    if (sfn5122f_q_driver_ev_driver_ev_subcode_extract(code) == 2) {
+        printf("Event queue init done %d \n", n);
+    }
+
+    if (sfn5122f_q_driver_ev_driver_ev_subcode_extract(code) == 9) {
+        printf("Packet neither TCP nor UPD %d \n", n);
+    }
+    
+    if (sfn5122f_q_driver_ev_driver_ev_subcode_extract(code) == 14) {
+        printf("RX error %d \n", n);
+        return SFN_ERR_RX_PKT;
+    }
+
+    if (sfn5122f_q_driver_ev_driver_ev_subcode_extract(code) == 15) {
+        printf("TX error %d \n", n);
+        return SFN_ERR_TX_PKT;
+    }
+
+    memset(code, 0xff, sfn5122f_q_event_entry_size);
+    return SYS_ERR_OK;
+
+}
+
+
+
+static inline errval_t sfn5122f_queue_handle_mcdi_event(sfn5122f_queue_t* q)
+{
+    // TODO handle different events    
+    size_t ev_head = q->ev_head;
+    sfn5122f_q_event_entry_t ev;
+    uint64_t reg;
+    ev = q->ev_ring[ev_head]; 
+    reg = sfn5122f_q_event_entry_ev_data_extract(ev);
+    memset(ev, 0xff, sfn5122f_q_event_entry_size);
+
+    return SYS_ERR_OK;
+
+}
+
+/*    RX      */
+static inline int sfn5122f_queue_add_user_rxbuf_devif(sfn5122f_queue_t* q, 
+                                                      uint32_t buf_id,
+                                                      uint16_t offset,
+                                                      regionid_t rid,
+                                                      bufferid_t devq_bid,
+                                                      lpaddr_t base,
+                                                      size_t len,
+                                                      uint64_t flags)
+{
+    struct devq_buf* buf;
+    sfn5122f_q_rx_user_desc_t d;
+    size_t tail = q->rx_tail;
+
+    d = q->rx_ring.user[tail];
+    buf = &q->rx_bufs[tail];
+
+    buf->rid = rid;
+    buf->bid = devq_bid;
+    buf->addr = base;
+    buf->len = len;
+    buf->flags = flags;
+    sfn5122f_q_rx_user_desc_rx_user_buf_id_insert(d, buf_id);
+    sfn5122f_q_rx_user_desc_rx_user_2byte_offset_insert(d, offset >> 1);
+    q->rx_tail = (tail + 1) % q->rx_size;
+    return 0;
+}
+
+static inline int sfn5122f_queue_add_rxbuf_devif(sfn5122f_queue_t* q, 
+                                                 regionid_t rid,
+                                                 bufferid_t bid,
+                                                 lpaddr_t addr,
+                                                 size_t len,
+                                                 uint64_t flags)
+{
+    struct devq_buf* buf;
+    sfn5122f_q_rx_ker_desc_t d;
+    size_t tail = q->rx_tail;
+
+    d = q->rx_ring.ker[tail];
+
+    buf = &q->rx_bufs[tail];
+
+    buf->rid = rid;
+    buf->bid = bid;
+    buf->addr = addr;
+    buf->len = len;
+    buf->flags = flags;
+
+    sfn5122f_q_rx_ker_desc_rx_ker_buf_addr_insert(d, addr);
+    sfn5122f_q_rx_ker_desc_rx_ker_buf_region_insert(d, 0);
+    // TODO: Check size
+    sfn5122f_q_rx_ker_desc_rx_ker_buf_size_insert(d, len);
+    q->rx_tail = (tail + 1) % q->rx_size;
+    return 0;
+}
+
+static inline errval_t sfn5122f_queue_handle_rx_ev_devif(sfn5122f_queue_t* q, 
+                                                         regionid_t* rid,
+                                                         bufferid_t* bid,
+                                                         lpaddr_t* base,
+                                                         size_t* len,
+                                                         uint64_t* flags)
+{   
+    /*  Only one event is generated even if there is more than one
+        descriptor per packet  */
+    struct devq_buf* buf;
+    size_t ev_head = q->ev_head;
+    size_t rx_head;
+    sfn5122f_q_rx_ev_t ev;
+    sfn5122f_q_rx_user_desc_t d_user = 0;
+
+    ev = q->ev_ring[ev_head];
+    rx_head = sfn5122f_q_rx_ev_rx_ev_desc_ptr_extract(ev);
+
+    buf = &q->rx_bufs[rx_head];
+
+    *rid = buf->rid;
+    *bid = buf->bid;
+    *base = buf->addr;
+    *flags = buf->flags;
+
+    if(!sfn5122f_q_rx_ev_rx_ev_pkt_ok_extract(ev)) {   
+         // TODO error handling
+         q->rx_head = (rx_head + 1) % q->rx_size;
+         if (sfn5122f_q_rx_ev_rx_ev_tobe_disc_extract(ev)) {
+            // packet discared by softare -> ok
+            return SFN_ERR_RX_DISCARD;
+         }
+
+         printf("Packet not ok \n");
+         if (sfn5122f_q_rx_ev_rx_ev_buf_owner_id_extract(ev)) {
+             printf("Wrong owner \n");
+         }
+         return SFN_ERR_RX_PKT;
+    }
+
+    *len = sfn5122f_q_rx_ev_rx_ev_byte_ctn_extract(ev);
+    /* Length of 0 is treated as 16384 bytes */
+    if (*len == 0) {
+        *len = 16384;
+    }
+
+    rx_head = sfn5122f_q_rx_ev_rx_ev_desc_ptr_extract(ev);
+    d_user = q->rx_ring.user[rx_head];  
+
+    buf = &q->rx_bufs[rx_head];
+
+    *rid = buf->rid;
+    *bid = buf->bid;
+    *base = buf->addr;
+    *flags = buf->flags;
+
+    memset(ev, 0xff, sfn5122f_q_event_entry_size);
+    memset(d_user, 0 , sfn5122f_q_rx_user_desc_size);
+
+    q->rx_head = (rx_head + 1) % q->rx_size;
+    return SYS_ERR_OK;
+}
+
+static inline void sfn5122f_queue_bump_evhead(sfn5122f_queue_t* q)
+{     
+     q->ev_head = (q->ev_head +1) % q->ev_size;
+}
+
+static inline size_t sfn5122f_queue_free_rxslots(sfn5122f_queue_t* q)
+{
+    size_t head = q->rx_head;
+    size_t tail = q->rx_tail;
+    size_t size = q->rx_size;
+
+    if (tail >= head) {
+        return size - (tail - head) -1; 
+    } else {
+        return size - (tail + size - head) -1; 
+    }
+}
+
+
+/*   TX       */
+static inline size_t sfn5122f_queue_free_txslots(sfn5122f_queue_t* q)
+{
+    size_t head = q->tx_head;
+    size_t tail = q->tx_tail;
+    size_t size = q->tx_size;
+
+    if (tail >= head) {
+        return size - (tail - head) - 1; 
+    } else {
+        return size - (tail + size - head) - 1; 
+    }
+
+}
+
+static inline errval_t sfn5122f_queue_handle_tx_ev_devif(sfn5122f_queue_t* q, 
+                                                         regionid_t* rid,
+                                                         bufferid_t* bid,
+                                                         lpaddr_t* base,
+                                                         size_t* len,
+                                                         uint64_t* flags)
+{
+    /*  Only one event is generated even if there is more than one
+        descriptor per packet  */
+    size_t ev_head = q->ev_head;
+    size_t tx_head;
+    struct devq_buf* buf;
+    sfn5122f_q_tx_ev_t ev;
+    sfn5122f_q_tx_user_desc_t d_user= 0;
+   
+    ev = q->ev_ring[ev_head];
+    tx_head = sfn5122f_q_tx_ev_tx_ev_desc_ptr_extract(ev);
+    
+
+    buf = &q->tx_bufs[tx_head];
+
+    *rid = buf->rid;
+    *bid = buf->bid;
+    *base = buf->addr;
+    *flags = buf->flags;
+
+    if (sfn5122f_q_tx_ev_tx_ev_pkt_err_extract(ev)){     
+        q->tx_head = (tx_head +1) % q->tx_size;
+        return SFN_ERR_TX_PKT;
+    }
+
+    if (sfn5122f_q_tx_ev_tx_ev_comp_extract(ev) == 1){  
+        d_user = q->tx_ring.user[tx_head];  
+
+        // reset entry event in queue
+        memset(ev, 0xff, sfn5122f_q_event_entry_size);
+        memset(d_user, 0 , sfn5122f_q_tx_user_desc_size);
+        q->tx_head = (tx_head +1) % q->tx_size;
+    }
+
+    return SYS_ERR_OK;
+}
+
+static inline int sfn5122f_queue_add_txbuf_devif(sfn5122f_queue_t* q, 
+                                                 regionid_t rid,
+                                                 bufferid_t bid,
+                                                 lpaddr_t base,
+                                                 size_t len,
+                                                 uint64_t flags)
+{
+    struct devq_buf* buf;
+    sfn5122f_q_tx_ker_desc_t d;
+    size_t tail = q->tx_tail;
+
+    d = q->tx_ring.ker[tail];
+    buf = &q->tx_bufs[tail];
+   
+    bool last = flags & DEVQ_BUF_FLAG_TX_LAST;    
+    buf->rid = rid;
+    buf->bid = bid;
+    buf->addr = base;
+    buf->len = len;
+    buf->flags = flags;
+
+    sfn5122f_q_tx_ker_desc_tx_ker_buf_addr_insert(d, base);
+    sfn5122f_q_tx_ker_desc_tx_ker_byte_count_insert(d, len);
+    sfn5122f_q_tx_ker_desc_tx_ker_cont_insert(d, !last);
+    sfn5122f_q_tx_ker_desc_tx_ker_buf_region_insert(d, 0);
+
+    __sync_synchronize();
+    q->tx_tail = (tail + 1) % q->tx_size;
+    return 0;
+}
+
+
+static inline int sfn5122f_queue_add_user_txbuf_devif(sfn5122f_queue_t* q, 
+                                                      uint64_t buftbl_idx, 
+                                                      uint64_t offset,
+                                                      regionid_t rid,
+                                                      bufferid_t devq_bid,
+                                                      lpaddr_t base,
+                                                      size_t len,
+                                                      uint64_t flags)
+{
+    sfn5122f_q_tx_user_desc_t d;
+    struct devq_buf* buf;
+    size_t tail = q->tx_tail;
+
+    d = q->tx_ring.ker[tail];
+    buf = &q->tx_bufs[tail];
+   
+    bool last = flags & DEVQ_BUF_FLAG_TX_LAST;    
+    buf->rid = rid;
+    buf->bid = devq_bid;
+    buf->addr = base;
+    buf->len = len;
+    buf->flags = flags;
+
+    sfn5122f_q_tx_user_desc_tx_user_sw_ev_en_insert(d, 0);
+    sfn5122f_q_tx_user_desc_tx_user_cont_insert(d, !last);
+    sfn5122f_q_tx_user_desc_tx_user_byte_cnt_insert(d, len);
+    sfn5122f_q_tx_user_desc_tx_user_buf_id_insert(d, buftbl_idx);
+    sfn5122f_q_tx_user_desc_tx_user_byte_ofs_insert(d, offset);
+
+    __sync_synchronize();
+    q->tx_tail = (tail + 1) % q->tx_size;
+    return 0;
+}
+
+#endif //ndef SFN5122F_CHANNEL_H_
+
diff --git a/lib/devif/desc_queue.h b/lib/devif/desc_queue.h
deleted file mode 100644 (file)
index ffb4595..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2016 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
- */
-#ifndef DESCQ_H_
-#define DESCQ_H_ 1
-
-
-#include <barrelfish/barrelfish.h>
-#include <devif/queue_interface.h>
-
-#define DESCQ_DEFAULT_SIZE 64
-#define DESCQ_ALIGNMENT 64
-
-struct descq;
-/**
- * @brief initialized a descriptor queue
- *
- * @param q                     Return pointer to the descriptor queue
- * @param shm                   Cap to the the shared memory of the queue
- * @param slots                 Number of slots in the queue
- *
- * @returns error on failure or SYS_ERR_OK on success
- */
-errval_t descq_init(struct descq** q,
-                    struct capref shm,
-                    size_t slots);
-
-/**
- * @brief Destroys a descriptor queue and frees its resources
- *
- * @param q                     The descriptor queue
- *
- * @returns error on failure or SYS_ERR_OK on success
- */
-errval_t descq_destroy(struct descq* q);
-
-/**
- * @brief Enqueue a descriptor (as seperate fields) 
- *        into the descriptor queue
- *
- * @param q                     The descriptor queue
- * @param region_id             Region id of the enqueued buffer
- * @param buffer_id             Buffer id of the buffer
- * @param base                  Physical address of hte buffer
- * @param len                   Lenght of the buffer
- * @param misc_flags            Miscellaneous flags
- *
- * @returns error if queue is full or SYS_ERR_OK on success
- */
-errval_t descq_enqueue(struct descq* q,
-                       regionid_t region_id,
-                       bufferid_t buffer_id,
-                       lpaddr_t base,
-                       size_t len,
-                       uint64_t misc_flags);
-
-/**
- * @brief Dequeue a descriptor (as seperate fields) 
- *        from the descriptor queue
- *
- * @param q                     The descriptor queue
- * @param region_id             Return pointer to the region id of 
- *                              the denqueued buffer
- * @param buffer_id             Return pointer to the buffer id of the buffer
- * @param base                  Return pointer to the physical address 
- *                              of the buffer
- * @param len                   Return pointer to the lenght of the buffer
- * @param misc_flags            Return pointer to miscellaneous flags
- *
- * @returns error if queue is empty or SYS_ERR_OK on success
- */
-errval_t descq_dequeue(struct descq* q,
-                       regionid_t* region_id,
-                       bufferid_t* buffer_id,
-                       lpaddr_t* base,
-                       size_t* len,
-                       uint64_t* misc_flags);
-
-/**
- * @brief Writes the local head pointer into the shared memory
- *        making the state of the queue visible to the other end
- *
- * @param q                     The descriptor queue
- *
- */
-void descq_writeout_head(struct descq* q);
-/**
- * @brief Writes the local tail pointer into the shared memory
- *        making the state of the queue visible to the other end
- *
- * @param q                     The descriptor queue
- *
- */
-void descq_writeout_tail(struct descq* q);
-
-/**
- * @brief Check if the descriptor queue is full
- *
- * @param q                     The descriptor queue
- *
- * @returns true if the queue is full, otherwise false
- */
-bool descq_full(struct descq* q);
-
-/**
- * @brief Check if the descriptor queue is empty
- *
- * @param q                     The descriptor queue
- *
- * @returns true if the queue is empty, otherwise false
- */
-bool descq_empty(struct descq* q);
-
-/**
- * @brief Returns the number of occupied slots in the queue
- *
- * @param q                     The descriptor queue
- *
- * @returns the number of occupied slots
- */
-size_t descq_full_slots(struct descq* q);
-
-#endif /* DESCQ_H_ */
index c52409d..18a88f3 100644 (file)
 #include <barrelfish/deferred.h>
 #include <barrelfish/nameservice_client.h>
 #include <devif/queue_interface.h>
-#include <if/devif_ctrl_defs.h>
-#include <if/devif_ctrl_rpcclient_defs.h>
-#include <if/devif_data_defs.h>
 
 #include "region_pool.h"
-#include "desc_queue.h"
 #include "dqi_debug.h"
 
-#define FORWARD_PREFIX_LEN 8
-
-enum devq_state {
-    DEVQ_STATE_UNINITIALIZED,
-    DEVQ_STATE_BINDING_CTRL,
-    DEVQ_STATE_BINDING_DATA,
-    DEVQ_STATE_CONNECTED,
-    DEVQ_STATE_RECONNECTING,
-    DEVQ_STATE_READY,
-};
-
-/**
- * Represent the device queue itself
- */
-struct devq {
-    // Endpoint state
-    struct endpoint_state* end;
-    // The name of the endpoint on the other side
-    char endpoint_name[MAX_DEVICE_NAME];
-    // Region management
-    struct region_pool* pool;
-
-    // queues
-    struct capref rx_cap;
-    struct capref tx_cap;
-
-    struct descq* rx;
-    struct descq* tx;
-
-    // out of band communication to endpoint
-    struct devif_ctrl_binding* ctrl;       
-    struct devif_ctrl_rpc_client* ctrl_rpc; 
-    struct devif_data_binding* data;       
-  
-    // state of the queue
-    enum devq_state state;
-    // pointer to queue specific state
-    void* q;
-    
-    // setup 
-    bool reconnect;
-    char reconnect_name[MAX_DEVICE_NAME];
-    // rpc error
-    errval_t err;
-
-    // default device state (mostly for direct interface)
-    uint32_t q_size;
-    uint32_t buf_size;
-    
-    //TODO Other state needed ...
-};
-
-
-// Prototypes
-// Init functions
-static errval_t devq_init_forward(struct devq *q, uint64_t flags);
-static errval_t devq_init_user(struct devq *q, uint64_t flags);
-static errval_t devq_init_direct(struct devq *q, uint64_t flags);
-
-static errval_t devq_init_descqs(struct devq *q, struct capref rx, 
-                                 struct capref tx, size_t slots);
-
-// Message Passing functions
-// ...
-
-static void mp_setup_request(struct devif_ctrl_binding* b, uint32_t coreid,
-                             uint64_t flags)
-{
-    DQI_DEBUG("setup_request coreid=%d flags=%lu\n", coreid, flags);
-    errval_t err;
-    uint64_t features;
-    uint32_t default_qsize, default_bufsize;
-    char reconnect_name[MAX_DEVICE_NAME];
-    bool reconnect = false;
-
-    struct endpoint_state* state = (struct endpoint_state*) b->st;
-
-    // Call setup function on local device
-    if (state->endpoint_type == ENDPOINT_TYPE_FORWARD) {
-        // TODO forward default size etc. 
-        reconnect = false;
-    } else {
-
-        err = state->f.setup(coreid, flags, &features, &default_qsize, 
-                             &default_bufsize, &reconnect, reconnect_name);
-        assert(err_is_ok(err));    
-    }
-
-
-    err = b->tx_vtbl.setup_response(b, NOP_CONT, features, default_qsize,
-                                    default_bufsize, reconnect, reconnect_name);
-    assert(err_is_ok(err));
-
-}
-
-
-static void mp_create(struct devif_ctrl_binding* b, struct capref rx, 
-                      struct capref tx, uint64_t flags, uint64_t size)
-{
-    errval_t err;
-    struct endpoint_state* state = (struct endpoint_state* ) b->st;
-        
-    struct devq* q;    
-    
-    // Create the device queue
-    // TODO we might need to know the name of the 
-    // endpoint that connected to the device
-
-    if (state->endpoint_type != ENDPOINT_TYPE_FORWARD) {
-        err = devq_create(&q, state, "", 0);
-        if (err_is_fail(err)) {   
-            err = b->tx_vtbl.create_response(b, NOP_CONT, err);
-            assert(err_is_ok(err));
-        }
-    } else {
-
-        struct devq* q2;    
-        state->endpoint_type = ENDPOINT_TYPE_DEVICE;
-        err = devq_create(&q, state, "", 0);
-        if (err_is_fail(err)) {   
-            err = b->tx_vtbl.create_response(b, NOP_CONT, err);
-            assert(err_is_ok(err));
-        }
-
-        state->endpoint_type = ENDPOINT_TYPE_USER;
-        err = devq_create(&q2, state, state->device_name+FORWARD_PREFIX_LEN, 0);
-        if (err_is_fail(err)) {   
-            err = b->tx_vtbl.create_response(b, NOP_CONT, err);
-            assert(err_is_ok(err));
-        }
-        state->endpoint_type = ENDPOINT_TYPE_FORWARD;
-        q->q = q2;
-    }
-    
-    q->end = state;
-
-    // Init queues (tx/rx are switched)
-    err = devq_init_descqs(q, tx, rx, size);
-    if (err_is_fail(err)) {   
-        // TODO deallocate queues
-        err = b->tx_vtbl.create_response(b, NOP_CONT, err);
-        assert(err_is_ok(err));
-    }
-
-    // Call create on device
-    err = q->end->f.create(q, flags);    
-    if (err_is_fail(err)) {   
-        err = b->tx_vtbl.create_response(b, NOP_CONT, err);
-        assert(err_is_ok(err));
-    }
-
-    DQI_DEBUG("create_request %p \n", q);
-    // Send response
-    err = b->tx_vtbl.create_response(b, NOP_CONT, err);
-    assert(err_is_ok(err));
-    b->st = q;
-    q->data->st = q;
-}
-
-static void mp_register(struct devif_ctrl_binding* b, struct capref mem, 
-                        regionid_t region_id)
-{
-    errval_t err;
-    struct devq* q = (struct devq*) b->st;
-   
-    if (q->end->endpoint_type == ENDPOINT_TYPE_FORWARD) {
-        // forward directly
-        assert(!capcmp(mem, NULL_CAP));
-        struct devq* tx = (struct devq*) q->q;
-
-        DQI_DEBUG("Register top_q q=%p tx_q=%p Rid=%d \n", q, tx, region_id);
-        err = tx->ctrl_rpc->vtbl.reg(tx->ctrl_rpc, mem, region_id, &tx->err);
-        if (err_is_fail(tx->err) || err_is_fail(err)) {
-            err = err_is_fail(err) ? err: tx->err;
-            err = b->tx_vtbl.reg_response(b, NOP_CONT, err);
-            assert(err_is_ok(err));
-        }
-        
-        if (tx->q == NULL) {
-            tx->q = q;
-        }
-
-    } else {
-
-        DQI_DEBUG("Register q=%p Rid=%d \n", q, region_id);
-        err = region_pool_add_region_with_id(q->pool, mem, region_id);
-        if (err_is_fail(err)) {
-            err = b->tx_vtbl.reg_response(b, NOP_CONT, err);
-            assert(err_is_ok(err));
-        }
-
-    }
-
-    err = q->end->f.reg(q, mem, region_id); 
-    if (err_is_fail(err)) {
-        err = b->tx_vtbl.reg_response(b, NOP_CONT, err);
-        assert(err_is_ok(err));
-    }
-
-    err = b->tx_vtbl.reg_response(b, NOP_CONT, err);
-    assert(err_is_ok(err));
-}
-
-static void mp_deregister(struct devif_ctrl_binding* b, regionid_t region_id)
-{
-    errval_t err;
-    DQI_DEBUG("Deregister Rid=%d\n", region_id);
-    struct devq* q = (struct devq*) b->st;
-    struct capref* cap = NULL; 
-
-    if (q->end->endpoint_type == ENDPOINT_TYPE_FORWARD) {
-        // forward directly
-        struct devq* tx = (struct devq*) q->q;
-
-        err = tx->ctrl_rpc->vtbl.dereg(tx->ctrl_rpc, region_id, &tx->err);
-        if (err_is_fail(tx->err) || err_is_fail(err)) {
-            err = err_is_fail(err) ? err: tx->err;
-            err = b->tx_vtbl.dereg_response(b, NOP_CONT, err);
-            assert(err_is_ok(err));
-        }
-    
-    } else {
-        err = region_pool_remove_region(q->pool, region_id, cap);
-        if (err_is_fail(err)) {
-            err = b->tx_vtbl.dereg_response(b, NOP_CONT, err);
-            assert(err_is_ok(err));
-        }
-
-    }
-
-    err = q->end->f.dereg(q, region_id); 
-    if (err_is_fail(err)) {
-        err = b->tx_vtbl.dereg_response(b, NOP_CONT, err);
-        assert(err_is_ok(err));
-    }
-
-    err = b->tx_vtbl.dereg_response(b, NOP_CONT, SYS_ERR_OK);
-    assert(err_is_ok(err));
-}
-
-static void mp_control(struct devif_ctrl_binding* b, uint64_t cmd,
-                       uint64_t value)
-{
-    errval_t err;
-    struct devq* q = (struct devq*) b->st;
-
-    DQI_DEBUG("Control cmd=%lu value=%lu \n", cmd, value);
-    if (q->end->endpoint_type == ENDPOINT_TYPE_FORWARD) {
-        struct devq* tx = (struct devq*) q->q;
-        err = tx->ctrl_rpc->vtbl.control(tx->ctrl_rpc, cmd, value, &tx->err);
-        if (err_is_fail(err) || err_is_fail(tx->err)) {
-            err = err_is_fail(err) ? err: tx->err;
-            err = b->tx_vtbl.control_response(b, NOP_CONT, err);
-            assert(err_is_ok(err));
-        }
-
-    }
-
-    err = q->end->f.ctrl(q, cmd, value);
-    if (err_is_fail(err)) {
-        err = b->tx_vtbl.control_response(b, NOP_CONT, err);
-        assert(err_is_ok(err));
-    }   
-
-    err = b->tx_vtbl.control_response(b, NOP_CONT, SYS_ERR_OK);
-    assert(err_is_ok(err));
-}
-
-static void mp_notify(struct devif_data_binding* b, uint8_t num_slots)
-{
-    errval_t err;
-    struct devq* q = (struct devq*) b->st;
-    // Sending notification
-
-    regionid_t region_id;
-    bufferid_t buffer_id;
-    lpaddr_t base;
-    size_t len;
-    uint64_t misc_flags;
-
-    DQI_DEBUG("notify q=%p slots=%d endpoint %p \n", q, num_slots, q->end);
-    
-    if (q->end->endpoint_type == ENDPOINT_TYPE_FORWARD) {
-        // forward user -> device:
-        struct devq* tx = (struct devq*) q->q;
-
-        if (tx->q == NULL) {
-            tx->q = q;
-        }
-
-        DQI_DEBUG("notify forward q=%p slots=%d \n", tx, num_slots);
-        for (int i = 0; i < num_slots; i++) {
-
-            err = descq_dequeue(q->rx, &region_id, &buffer_id,
-                                &base, &len, &misc_flags);
-            assert(err_is_ok(err));
-
-            // local function call
-            err = q->end->f.enq(q, region_id, buffer_id, base, len , misc_flags);
-            assert(err_is_ok(err));
-            DQI_DEBUG("Dequeue q=%p rid=%d, bid=%d \n", q, region_id, buffer_id);
-            // TODO call function locally to inform point (dequeue)
-            err = descq_enqueue(tx->tx, region_id, buffer_id,
-                                base, len, misc_flags);
-            DQI_DEBUG("Enqueue q=%p rid=%d, bid=%d \n", tx, region_id, buffer_id);
-            assert(err_is_ok(err));
-        }
-
-        descq_writeout_head(tx->tx);
-        err = tx->data->tx_vtbl.notify(tx->data, NOP_CONT, num_slots);
-        assert(err_is_ok(err));
-    
-        err = tx->end->f.notify(q, num_slots);
-    } else if (q->end->endpoint_type == ENDPOINT_TYPE_FORWARD_TX) {
-        // forward device -> user
-        struct devq* tx = (struct devq*) q->q;
-        DQI_DEBUG("notify forward_tx q=%p slots=%d \n", tx, num_slots);
-        for (int i = 0; i < num_slots; i++) {
-            err = descq_dequeue(q->rx, &region_id, &buffer_id,
-                                &base, &len, &misc_flags);
-            assert(err_is_ok(err));
-            DQI_DEBUG("Dequeue q=%p rid=%d, bid=%d \n", q, region_id, buffer_id);
-
-            // local function call // TODO only enqueue makes sense ? use flags?
-            err = q->end->f.enq(q, region_id, buffer_id, base, len , misc_flags);
-            assert(err_is_ok(err));
-
-            err = descq_enqueue(tx->tx, region_id, buffer_id,
-                                base, len, misc_flags);
-            DQI_DEBUG("Enqueue q=%p rid=%d, bid=%d \n", tx, region_id, buffer_id);
-            assert(err_is_ok(err));
-        }
-
-        descq_writeout_head(tx->tx);
-        err = tx->data->tx_vtbl.notify(tx->data, NOP_CONT, num_slots);
-        assert(err_is_ok(err));
-   
-        err = q->end->f.notify(q, num_slots);
-    } else {
-        err = q->end->f.notify(q, num_slots); 
-        assert(err_is_ok(err));
-        
-        descq_writeout_tail(q->rx);
-    }
-}
-
-static struct devif_ctrl_rx_vtbl rx_vtbl_ctrl = {
-    .setup_call = mp_setup_request,
-    .create_call= mp_create,
-    .reg_call = mp_register,
-    .dereg_call = mp_deregister,
-    .control_call = mp_control,
-};
-
-
-static struct devif_data_rx_vtbl rx_vtbl_data = {
-    .notify = mp_notify,
-};
-
-static void bind_cb_ctrl(void *st, errval_t err, struct devif_ctrl_binding *b)
-{
-    struct devq* q = (struct devq*) st;
-    assert(err_is_ok(err));
-    
-    b->rx_vtbl = rx_vtbl_ctrl;
-    b->st = q;
-    q->ctrl = b;
-    // Initi RPC client
-    
-    q->ctrl_rpc = malloc(sizeof(struct devif_ctrl_rpc_client));
-    assert(q->ctrl_rpc != NULL);
-
-    err = devif_ctrl_rpc_client_init(q->ctrl_rpc, b);
-    if (err_is_fail(err)) {
-       free(q->ctrl_rpc);
-    }   
-    
-    q->state = DEVQ_STATE_BINDING_CTRL;
-    DQI_DEBUG("Bound to interface \n");
-}
-
-static void bind_cb_data(void *st, errval_t err, struct devif_data_binding *b)
-{
-    struct devq* q = (struct devq*) st;
-    assert(err_is_ok(err));
-    
-    b->rx_vtbl = rx_vtbl_data;
-    b->st = q;
-    q->data = b;
-    // Initi RPC client
-    
-    q->state = DEVQ_STATE_BINDING_DATA;
-    DQI_DEBUG("Bound to interface \n");
-}
-
-static void export_cb_ctrl(void *st, errval_t err, iref_t iref) 
-{
-    assert(err_is_ok(err));
-    struct endpoint_state* state = (struct endpoint_state*) st;
-    const char *suffix = "_devif_ctrl";
-
-    char name[strlen(state->device_name) + strlen(suffix) + 1];
-    sprintf(name, "%s%s", state->device_name, suffix);
-
-    err = nameservice_register(name, iref);
-    assert(err_is_ok(err));
-
-    DQI_DEBUG("Interface %s exported \n", name);
-}
-
-// TODO try to not duplicate this?
-static void export_cb_data(void *st, errval_t err, iref_t iref) 
-{
-    assert(err_is_ok(err));
-    struct endpoint_state* state = (struct endpoint_state*) st;
-    const char *suffix = "_devif_data";
-
-    char name[strlen(state->device_name) + strlen(suffix) + 1];
-    sprintf(name, "%s%s", state->device_name, suffix);
-
-    err = nameservice_register(name, iref);
-    assert(err_is_ok(err));
-
-    DQI_DEBUG("Interface %s exported \n", name);
-    state->export_done = true;
-}
-
-static errval_t connect_cb_ctrl(void *st, struct devif_ctrl_binding* b) 
-{
-    DQI_DEBUG("New connection on interface \n");
-    struct endpoint_state* end = (struct endpoint_state*) st;    
-
-    b->rx_vtbl = rx_vtbl_ctrl;
-    b->st = st;
-    // Set binding for bidirectional communication
-    end->ctrl = b;
-    return SYS_ERR_OK;
-}
-
-
-static errval_t connect_cb_data(void *st, struct devif_data_binding* b) 
-{
-    DQI_DEBUG("New connection on interface \n");
-    struct endpoint_state* end = (struct endpoint_state*) st;    
-
-    b->rx_vtbl = rx_vtbl_data;
-    b->st = st;
-    // Set binding for bidirectional communication
-    end->data = b;
-    return SYS_ERR_OK;
-}
-
- /*
- * ===========================================================================
- * Device queue interface export (for devices)
- * ===========================================================================
- */
- /**
-  * @brief exports the devq interface so others (client side) can connect
-  *
-  * @param device_name   Device name that is exported to the other endpoints.
-  *                      Required by the "user" side to connect to
-  * @param features      The features the driver exports
-  *
-  * @returns error on failure or SYS_ERR_OK on success
-  */
-
-errval_t devq_driver_export(struct endpoint_state* s)
-{
-    DQI_DEBUG("Driver export with endpoint %p \n", s);   
-    errval_t err;
-    
-    err = devif_ctrl_export(s, export_cb_ctrl, connect_cb_ctrl, get_default_waitset(),
-                            1);
-    if (err_is_fail(err)) {
-        DQI_DEBUG("Exporting devif interface failed \n");   
-        return err;
-    }
-
-    err = devif_data_export(s, export_cb_data, connect_cb_data, get_default_waitset(),
-                            IDC_BIND_FLAGS_DEFAULT);
-    if (err_is_fail(err)) {
-        DQI_DEBUG("Exporting devif interface failed \n");   
-        return err;
-    }
-
-    while (!s->export_done) {
-        event_dispatch(get_default_waitset());
-    }
-
-    return SYS_ERR_OK;
-}
-
- /*
- * ===========================================================================
- * Device queue creation and destruction
- * ===========================================================================
- */
- /**
-  * @brief creates a queue 
-  *
-  * @param q             Return pointer to the devq (handle)
-  * @param end           Endpoint state containing require function pointers and
-  *                      some other info
-  * @param endpoint_name Device name of the device to which this queue belongs
-  *                      (Driver itself is running in a separate process)
-  * @param flags         Anything you can think of that makes sense for the device
-  *                      and its driver?
-  *
-  * @returns error on failure or SYS_ERR_OK on success
-  */
-
-errval_t devq_create(struct devq **q,
-                     struct endpoint_state* end,
-                     char* endpoint_name,
-                     uint64_t flags)
-{
-    
-    errval_t err;
-
-    struct devq* tmp = malloc(sizeof(struct devq));
-    tmp->end = end;
-
-    DQI_DEBUG("start create %p\n", tmp);
-    strncpy(tmp->endpoint_name, endpoint_name, MAX_DEVICE_NAME);
-
-    err = region_pool_init(&(tmp->pool));
-    if (err_is_fail(err)) {
-        free(tmp);
-        return err;
-    }
-    
-    tmp->end = end;
-    tmp->state = DEVQ_STATE_UNINITIALIZED;
-
-    switch (tmp->end->endpoint_type) {
-        case ENDPOINT_TYPE_FORWARD:
-            err = devq_init_forward(tmp, flags);
-            if (err_is_fail(err)) {
-                return err;
-            }
-            break;
-        case ENDPOINT_TYPE_DEVICE:
-            // set bindings for communication back
-            tmp->ctrl = tmp->end->ctrl;
-            tmp->data = tmp->end->data;
-            break;
-        case ENDPOINT_TYPE_DIRECT:
-            flags = flags | DEVQ_SETUP_FLAGS_DIRECT;
-            err = devq_init_direct(tmp, flags);
-            if (err_is_fail(err)) {
-                return err;
-            }
-            break;
-        case ENDPOINT_TYPE_USER:
-            err = devq_init_user(tmp, flags);
-            if (err_is_fail(err)) {
-                return err;
-            }
-            break;
-        default:
-            USER_PANIC("Devq: unknown device type \n");
-
-    }
-    
-    tmp->state = DEVQ_STATE_READY;
-    *q = tmp;
-    DQI_DEBUG("end create %p\n", tmp);
-    return SYS_ERR_OK;
-}
-
-
- /**
-  * @brief destroys the device queue
-  *
-  * @param q           The queue state to free (and the device queue to be 
-                       shut down in the driver)
-  *
-  * @returns error on failure or SYS_ERR_OK on success
-  */
-errval_t devq_destroy(struct devq *q)
-{
-    errval_t err;
-
-    err = descq_destroy(q->rx);
-    if (err_is_fail(err)) {
-        return err;
-    }
-
-    err = descq_destroy(q->tx);
-    if (err_is_fail(err)) {
-        return err;
-    }
-
-    err = region_pool_destroy(q->pool);
-    if (err_is_fail(err)) {
-        return err;
-    }
-
-    free(q);
-    return SYS_ERR_OK;
-}
-
-/**
- * @brief allocate device specific state of size bytes
- *
- * @param q           The device queue to allocate the state for
- * @param bytes       Size of the state to allocate
- *
- */
-void devq_allocate_state(struct devq *q, size_t bytes)
-{   
-    q->q = calloc(1, bytes);
-}
-/**
- * @brief get the device specific state for a queue
- *
- * @param q           The device queue to get the state for
- *
- * @returns void pointer to the defice specific state
- */
-void* devq_get_state(struct devq *q) 
-{
-    return q->q;
-}
-
-void devq_set_state(struct devq *q, void* state) 
-{
-    q->q = state;
-}
-
-static errval_t connect_to_if(struct devq *q, char* if_name, bool data)
-{
-    enum devq_state state;
-    errval_t err;
-    iref_t iref;
-
-    char* suffix;
-    if (data) {
-        suffix = "_devif_data";
-    } else {
-        suffix = "_devif_ctrl";
-    }
-
-    char name[strlen(if_name) + strlen(suffix)+1];
-    sprintf(name, "%s%s", if_name, suffix);
-    DQI_DEBUG("connecting to %s \n", name);
-
-    err = nameservice_blocking_lookup(name, &iref);
-    if (err_is_fail(err)) {
-        return err;
-    }
-    
-    // Bind to driver interface
-    if (data) {
-        err = devif_data_bind(iref, bind_cb_data, q, get_default_waitset(),
-                              IDC_BIND_FLAGS_DEFAULT);
-        if (err_is_fail(err)) {
-            return err;
-        }
-        state = DEVQ_STATE_BINDING_DATA;
-    } else {
-        err = devif_ctrl_bind(iref, bind_cb_ctrl, q, get_default_waitset(),
-                              IDC_BIND_FLAGS_DEFAULT);
-        if (err_is_fail(err)) {
-            return err;
-        }
-        state = DEVQ_STATE_BINDING_CTRL;
-    }
-
-    // wiat until bound
-    while (q->state != state) {
-        event_dispatch(get_default_waitset());  
-    }
-
-    return SYS_ERR_OK;
-}
-
-static errval_t devq_init_descqs(struct devq *q,
-                                 struct capref rx,
-                                 struct capref tx,
-                                 size_t slots)
-{
-    errval_t err;
-    q->rx_cap = rx;
-    q->tx_cap = tx;
-
-    err = descq_init(&q->rx, rx, slots);
-    if (err_is_fail(err)) {
-        // TODO cleanup mapped frame
-        return DEVQ_ERR_DESCQ_INIT;
-    }
-
-    err = descq_init(&q->tx, tx, slots);
-    if (err_is_fail(err)) {
-        // TODO cleanup mapped frame
-        return DEVQ_ERR_DESCQ_INIT;
-    }
-
-    
-    DQI_DEBUG("RX/TX queue mapped and initaialized, successfully" 
-             " q %p tx %p rx %p \n", q, q->tx, q->rx);
-    return SYS_ERR_OK;
-}
-
-static errval_t devq_init_forward(struct devq *q,
-                                  uint64_t flags)
-{
-    errval_t err;
-    
-    char* end_name = malloc(MAX_DEVICE_NAME);
-    
-    sprintf(end_name, "%s_%s", "forward", q->endpoint_name);
-    strncpy(q->end->device_name, end_name, MAX_DEVICE_NAME);
-
-    // export interface
-    err = devif_ctrl_export(q->end, export_cb_ctrl, connect_cb_ctrl, get_default_waitset(),
-                            IDC_BIND_FLAGS_DEFAULT);
-    if (err_is_fail(err)) {
-        DQI_DEBUG("Exporting devif interface failed \n");   
-        return err;
-    }
-
-    err = devif_data_export(q->end, export_cb_data, connect_cb_data, get_default_waitset(),
-                            IDC_BIND_FLAGS_DEFAULT);
-    if (err_is_fail(err)) {
-        DQI_DEBUG("Exporting devif interface failed \n");   
-        return err;
-    }
-
-    DQI_DEBUG("Waiting for export done\n");   
-    while (!q->end->export_done) {
-        event_dispatch(get_default_waitset());
-    }
-
-    DQI_DEBUG("Export done\n");   
-
-    return SYS_ERR_OK;
-}
-
-static errval_t devq_init_user(struct devq *q,
-                               uint64_t flags)
-{
-    errval_t err;
-    struct capref rx;
-    struct capref tx;
-
-    // Allocate shared memory
-    err = frame_alloc(&rx, DESCQ_DEFAULT_SIZE*DESCQ_ALIGNMENT, NULL); 
-    if (err_is_fail(err)) {
-        return err;
-    }   
-
-    err = frame_alloc(&tx, DESCQ_DEFAULT_SIZE*DESCQ_ALIGNMENT, NULL); 
-    if (err_is_fail(err)) {
-        return err;
-    }   
-
-    err = devq_init_descqs(q, rx, tx, DESCQ_DEFAULT_SIZE);
-    if (err_is_fail(err)) {
-        return err;
-    }
-    
-    err = connect_to_if(q, q->endpoint_name, false);
-    if (err_is_fail(err)) {
-        return err;
-    }
-
-    err = q->ctrl_rpc->vtbl.setup(q->ctrl_rpc, disp_get_core_id(), flags,
-                                  &q->end->features, &q->q_size, 
-                                  &q->buf_size, &q->reconnect, q->reconnect_name);
-    if (err_is_fail(err)) {
-        return err;
-    }
-
-    // Do setup
-    // might have to connect again to different process
-    if (q->reconnect) {    
-        DQI_DEBUG("Reconnecting \n");
-        q->state = DEVQ_STATE_RECONNECTING;
-        err = connect_to_if(q, q->reconnect_name, false);
-        if (err_is_fail(err)) {
-            return err;
-        }
-        
-        err = connect_to_if(q, q->reconnect_name, true);
-        if (err_is_fail(err)) {
-            return err;
-        }
-        
-    } else {
-        err = connect_to_if(q, q->endpoint_name, true);
-        if (err_is_fail(err)) {
-            return err;
-        }
-    }
-
-    err = q->ctrl_rpc->vtbl.create(q->ctrl_rpc, rx, tx, flags, 
-                                   DESCQ_DEFAULT_SIZE, &q->err);
-    if (err_is_fail(err) || err_is_fail(q->err)) {
-        return err_is_fail(err) ? err: q->err;
-    }
-
-    q->state = DEVQ_STATE_CONNECTED;
-
-    return SYS_ERR_OK;
-}
-
-static errval_t devq_init_direct(struct devq *q,
-                                 uint64_t flags)
-{
-    errval_t err;
-    struct capref rx;
-    struct capref tx;
-
-    // Allocate shared memory
-    err = frame_alloc(&rx, DESCQ_DEFAULT_SIZE*DESCQ_ALIGNMENT, NULL); 
-    if (err_is_fail(err)) {
-        return err;
-    }   
-
-    err = frame_alloc(&tx, DESCQ_DEFAULT_SIZE*DESCQ_ALIGNMENT, NULL); 
-    if (err_is_fail(err)) {
-        return err;
-    }   
-
-    err = devq_init_descqs(q, rx, tx, DESCQ_DEFAULT_SIZE);
-    if (err_is_fail(err)) {
-        return err;
-    }
-
-    // need to get some stuff from the device itself
-    err = connect_to_if(q, q->endpoint_name, false);
-    if (err_is_fail(err)) {
-        return err;
-    }
-
-    err = q->ctrl_rpc->vtbl.setup(q->ctrl_rpc, disp_get_core_id(),
-                                  flags, &q->end->features, &q->q_size, 
-                                  &q->buf_size, &q->reconnect, q->reconnect_name);
-    if (err_is_fail(err)) {
-        return err;
-    }
-    err = q->end->f.create(q, flags);
-    
-    return err;
-}
 /*
  * ===========================================================================
  * Datapath functions
@@ -904,29 +52,15 @@ errval_t devq_enqueue(struct devq *q,
        access. In the device case, we keep track of the buffers the device
        actually has access to.
     */
-    if (q->end->endpoint_type == ENDPOINT_TYPE_USER || 
-        q->end->endpoint_type == ENDPOINT_TYPE_DIRECT) {
-        err = region_pool_get_buffer_id_from_region(q->pool, region_id, base,
-                                                    buffer_id);
-        if (err_is_fail(err)) {
-            return err;
-        }
-    } else {
-        err = region_pool_return_buffer_to_region(q->pool, region_id,
-                                                  base);
-        if (err_is_fail(err)) {
-            return err;
-        }
-    }
-    // Enqueue into queue
-    if (q->end->endpoint_type == ENDPOINT_TYPE_DIRECT) {
-        err = q->end->f.enq(q, region_id, *buffer_id, base, length, 
-                            misc_flags);
-    } else {
-        err = descq_enqueue(q->tx, region_id, *buffer_id,
-                            base, length, misc_flags);
+    err = region_pool_get_buffer_id_from_region(q->pool, region_id, base,
+                                                buffer_id);
+    if (err_is_fail(err)) {
+        return err;
     }
 
+    err = q->f.enq(q, region_id, *buffer_id, base, length, 
+                   misc_flags);
+
     DQI_DEBUG("Enqueue q=%p rid=%d, bid=%d \n", q, region_id, *buffer_id);
 
     return err;
@@ -957,21 +91,10 @@ errval_t devq_dequeue(struct devq *q,
 {
     errval_t err;
 
-    // Directly queue 
-    if (q->end->endpoint_type == ENDPOINT_TYPE_DIRECT) {
-        err = q->end->f.deq(q, region_id, buffer_id, base, length, 
-                            misc_flags);
-        if (err_is_fail(err)) {
-            return err;
-        }
-    } else {
-
-        // Dequeue descriptor from descriptor queue
-        err = descq_dequeue(q->rx, region_id, buffer_id,
-                            base, length, misc_flags);
-        if (err_is_fail(err)) {
-            return err;
-        }
+    err = q->f.deq(q, region_id, buffer_id, base, length, 
+                        misc_flags);
+    if (err_is_fail(err)) {
+        return err;
     }
 
     /* In the user case we keep track of the buffers the user should not
@@ -979,20 +102,11 @@ errval_t devq_dequeue(struct devq *q,
        actually has access to.
     */
     // Add buffer to free ones
-    if (q->end->endpoint_type == ENDPOINT_TYPE_USER ||
-        q->end->endpoint_type == ENDPOINT_TYPE_DIRECT) {
-        err = region_pool_return_buffer_id_to_region(q->pool, *region_id,
-                                                     *buffer_id);
+    err = region_pool_return_buffer_id_to_region(q->pool, *region_id,
+                                                 *buffer_id);
 
-        if (err_is_fail(err)) {
-            return err;
-        }
-    } else {
-        err = region_pool_set_buffer_id_from_region(q->pool, *region_id, *base,
-                                                    *buffer_id);
-        if (err_is_fail(err)) {
-            return DEVQ_ERR_BUFFER_ID;
-        }
+    if (err_is_fail(err)) {
+        return err;
     }
 
     DQI_DEBUG("Dequeue q=%p rid=%d, bid=%d \n", q, *region_id, *buffer_id);
@@ -1031,18 +145,8 @@ errval_t devq_register(struct devq *q,
     DQI_DEBUG("register q=%p, cap=%p, regionid=%d \n", (void*) q, 
               (void*) &cap, *region_id);
 
-    if (q->end->endpoint_type == ENDPOINT_TYPE_DIRECT) {
-        /* Directly call it, if communication to the device
-           driver is necessary it is most likely device specific
-           and can not be handled in the devq library
-        */
-        err = q->end->f.reg(q, cap, *region_id);   
-    } else {
-        err = q->ctrl_rpc->vtbl.reg(q->ctrl_rpc, cap, *region_id, &q->err);
-        if (err_is_fail(q->err)) {
-            return q->err;
-        }
-    }
+    err = q->f.reg(q, cap, *region_id);   
+
     return err;
 }
 
@@ -1070,40 +174,11 @@ errval_t devq_deregister(struct devq *q,
     DQI_DEBUG("deregister q=%p, cap=%p, regionid=%d \n", (void*) q, 
               (void*) cap, region_id);
     
-    if (q->end->endpoint_type == ENDPOINT_TYPE_DIRECT) {
-        err = q->end->f.dereg(q, region_id);   
-    } else {
-        err = q->ctrl_rpc->vtbl.dereg(q->ctrl_rpc, region_id, &q->err);
-        if (err_is_fail(q->err)) {
-            return q->err;
-        }
-    }
+   err = q->f.dereg(q, region_id);   
 
     return err;
 }
 
-// Notify helper
-struct pending_reply {
-    uint8_t num_slots;
-    struct devif_data_binding* b;
-};
-
-static void resend_notify(void* a)
-{
-    errval_t err;
-    struct pending_reply* r = (struct pending_reply*) a;
-
-    err = r->b->tx_vtbl.notify(r->b, NOP_CONT, r->num_slots);
-    if (err_is_fail(err)) {
-        err = r->b->register_send(r->b, get_default_waitset(),
-                                  MKCONT(resend_notify, r));
-        assert(err_is_ok(err));
-    } else {
-        free(r);
-    }   
-
-}
-
 /**
  * @brief Send a notification about new buffers on the queue
  *        Does nothing for direct queues.
@@ -1117,39 +192,9 @@ errval_t devq_notify(struct devq *q)
 {
     errval_t err;
   
-    if (q->end->endpoint_type == ENDPOINT_TYPE_DIRECT) {
-        return SYS_ERR_OK;
-    } else {
-        // get number of full slots
-        uint8_t num_slots = descq_full_slots(q->tx);
-        DQI_DEBUG("notify called q=%p slots=%d \n",q, num_slots);
-        descq_writeout_head(q->tx);
-
-        err = q->data->tx_vtbl.notify(q->data, NOP_CONT, num_slots);
-        // send notification
-        if (err == FLOUNDER_ERR_TX_BUSY) {
-            struct pending_reply* r = malloc(sizeof(struct pending_reply));
-            r->num_slots = num_slots;
-            r->b = q->data;
+    err = q->f.notify(q);
 
-            err = q->data->register_send(q->data, get_default_waitset(),
-                                      MKCONT(resend_notify, r));
-            // If registering fails, dispatch event to get further with 
-            // state and retry
-            if (err_is_fail(err)) {
-                while (true) {
-                    err = r->b->register_send(r->b, get_default_waitset(),
-                                              MKCONT(resend_notify, r));
-                    if (err_is_ok(err)) {
-                        break;
-                    } else {
-                        event_dispatch(get_default_waitset());
-                    }
-                }
-            }
-        } 
-    }
-    return SYS_ERR_OK;
+    return err;
 }
 
 /**
@@ -1182,26 +227,10 @@ errval_t devq_control(struct devq *q,
                       uint64_t value)
 {
     errval_t err;
-    
-    DQI_DEBUG("control request=%lu, value=%lu \n", request, value);
-    if (q->end->endpoint_type == ENDPOINT_TYPE_DIRECT) {
-        err = q->end->f.ctrl(q, request, value);
-        return err;
-    } else {
-        err = q->ctrl_rpc->vtbl.control(q->ctrl_rpc, request, value, &q->err);
-        if (err_is_fail(err) || err_is_fail(q->err)) {
-            err = err_is_fail(err) ? err : q->err;
-            return err;
-        }
-    }
 
-    return q->err;
-}
+    err = q->f.ctrl(q, request, value);
 
+    return err;
 
-errval_t devq_event_loop(struct endpoint_state* s)
-{   
-    while(true) {
-        event_dispatch(get_default_waitset());
-    }
 }
+
diff --git a/lib/devif/queue_interface_internal.c b/lib/devif/queue_interface_internal.c
new file mode 100644 (file)
index 0000000..aaec672
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <barrelfish/barrelfish.h>
+#include <devif/queue_interface.h>
+
+
+#include "region_pool.h"
+#include "queue_interface_internal.h"
+
+ /*
+ * ===========================================================================
+ * Device queue creation and destruction (General devif initalisation)
+ * ===========================================================================
+ */
+ /**
+  * @brief creates a queue 
+  *
+  * @param q             Return pointer to the devq (handle)
+  *
+  * @returns error on failure or SYS_ERR_OK on success
+  */
+
+errval_t devq_init(struct devq *q)
+{
+    
+    errval_t err;
+
+    err = region_pool_init(&(q->pool));
+    if (err_is_fail(err)) {
+        return err;
+    }
+    
+    return SYS_ERR_OK;
+}
+
+
+ /**
+  * @brief destroys the device queue
+  *
+  * @param q           The queue state to free (and the device queue to be 
+                       shut down in the driver)
+  *
+  * @returns error on failure or SYS_ERR_OK on success
+  */
+errval_t devq_destroy(struct devq *q)
+{
+    errval_t err;
+
+    err = region_pool_destroy(q->pool);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    return SYS_ERR_OK;
+}
+
diff --git a/lib/devif/queue_interface_internal.h b/lib/devif/queue_interface_internal.h
new file mode 100644 (file)
index 0000000..9b7f33a
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2016 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+#ifndef QUEUE_INTERFACE_INTERNAL_H_
+#define QUEUE_INTERFACE_INTERNAL_H_ 1
+
+#include <devif/queue_interface.h>
+
+errval_t devq_init(struct devq *q);
+errval_t devq_destroy(struct devq *q);
+
+
+#endif /* QUEUE_INTERFACE_INTERNAL_H_ */
index 8f2cff8..e6f0e94 100644 (file)
@@ -68,11 +68,6 @@ static void do_ahci_init(struct device_mem* bar_info, int nr_allocated_bars)
         USER_PANIC_ERR(err, "AHCI HBA init failed.");
     }
 
-    err = devq_create(ad, "", 0, &dq);
-    if (err_is_fail(err)) {
-        USER_PANIC_ERR(err, "devq create failed.");
-    }
-
 #if DISABLE_INTERRUPTS
     waitset_init(&disk_ws);
 
index 041dfce..e1f73ad 100644 (file)
@@ -20,7 +20,6 @@
 #include <pci/pci.h>
 #include <skb/skb.h>
 #include <blk/ahci.h>
-#include <devif/queue.h>
 
 #define DISABLE_INTERRUPTS 1
 
index c540c09..4dcfb42 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <stdarg.h>
 #include <bench/bench.h>
+#include <devif/queue.h>
 
 struct dma_mem {
     lvaddr_t vaddr;         ///< virtual address of the mapped region
index 17d5306..259b85a 100644 (file)
                                             "skb"]
                   },
 
-  build application { target = "sfn5122f_devif_queue",
-                    cFiles = ["sfn5122f_devif_qdriver.c", "helper.c" ],
-                    flounderBindings = [ "sfn5122f_devif" ],
-                    flounderExtraBindings = [ ("sfn5122f_devif", ["rpcclient"]) ],
-                    flounderDefs = [ "sfn5122f_devif" ],
-                    flounderExtraDefs = [ ("sfn5122f_devif",["rpcclient"]) ],
-                    mackerelDevices = ["sfn5122f", "sfn5122f_q"],
-                    addLibraries = libDeps ["devif", "skb"]
-                  },
-
   build application { target = "sfn5122f",
                       cFiles = [ "sfn5122f_cdriver.c", "mcdi_rpc.c", "helper.c", 
                                  "buffer_tbl.c"],
                       flounderDefs = [ "sfn5122f", "sfn5122f_devif" ],
                       flounderExtraDefs = [ ("sfn5122f_devif",["rpcclient"]) ],
                       mackerelDevices = [ "sfn5122f"],
-                      addLibraries = libDeps["netQmng", "pci", "contmng", "devif",
+                      addLibraries = libDeps["netQmng", "pci", "contmng", 
                                              "net_device_manager", "bench", "trace", "skb",
                                              "spawndomain" ]
-                    }, 
-
-  build library { target = "sfn5122f_devif_direct",
-                      cFiles = [ "sfn5122f_devif_direct.c", "helper.c"],
-                      flounderBindings = [ "sfn5122f_devif"],
-                      flounderExtraBindings = [ ("sfn5122f_devif", ["rpcclient"])],
-                      flounderDefs = [ "sfn5122f_devif" ],
-                      flounderExtraDefs = [ ("sfn5122f_devif",["rpcclient"]) ],
-                      mackerelDevices = [ "sfn5122f", "sfn5122f_q"],
-                      addLibraries = libDeps ["netQmng", "pci", "net_device_manager",
-                                              "skb"]
                     }
   ]
 
index 9b65de5..1bb4008 100644 (file)
@@ -22,8 +22,6 @@
 #include <if/sfn5122f_devif_rpcclient_defs.h>
 #include <if/net_ARP_rpcclient_defs.h>
 #include <if/net_ARP_defs.h>
-#include <devif/loopback_device.h>
-#include <devif/queue_interface.h>
 
 
 #include "sfn5122f.h"
@@ -1534,57 +1532,6 @@ static errval_t connect_devif_cb(void *st, struct sfn5122f_devif_binding *b)
     return SYS_ERR_OK;
 }
 
-static errval_t sfn5122f_setup(uint32_t coreid, uint64_t flag,
-                               uint64_t *features, uint32_t* default_qsize, 
-                               uint32_t* default_bufsize, bool* reconnect, 
-                               char* name)
-{ 
-    errval_t err;
-
-    DEBUG("Setup called\n");
-
-    *features = DEVQ_FEATURE_DIRECT;
-    *default_qsize = TX_ENTRIES;
-    *default_bufsize = MTU_MAX;
-    // If it is not direct, start new queue driver
-    if (!(flag & DEVQ_SETUP_FLAGS_DIRECT)) {
-       // TODO find better name for qdrivers
-        sprintf(name, "sfn5122f_devif_qdriver_%d", coreid);
-        DEBUG("sprintf called\n");
-        *reconnect = true;
-        char** args = (char**) malloc(sizeof(char*)*4);
-        char* string = malloc(256);
-        args[0] = "/x86_64/sbin/sfn5122f_devif_queue";
-        // TODO find exact size
-        DEBUG("sprintf2 called\n");
-        sprintf(string, "core=%d", coreid);
-        args[1] = string;
-        args[2] = NULL;
-
-        DEBUG("spawn called\n");
-        err = spawn_program(coreid, "/x86_64/sbin/sfn5122f_devif_queue", 
-                            args, NULL, SPAWN_FLAGS_DEFAULT, 
-                            NULL);
-        if (err_is_fail(err)) {
-            return SFN_ERR_QDRIVER;
-        }   
-
-        DEBUG("free called\n");
-        free(string);
-        free(args);
-    } else {
-        *reconnect = false;
-        name = "";
-    }
-    return SYS_ERR_OK;
-}
-
-
-static struct devq_func_pointer devif_f = {
-    .setup = sfn5122f_setup,
-};
-
-static struct endpoint_state devif_state;
 /**
  * Initialize management interface for queue drivers.
  * This has to be done _after_ the hardware is initialized.
@@ -1600,13 +1547,6 @@ static void initialize_mngif(void)
                               get_default_waitset(), 1);
     assert(err_is_ok(r));
 
-    devif_state.f = devif_f;
-    devif_state.features = 0;
-    devif_state.endpoint_type = ENDPOINT_TYPE_DIRECT;
-    strncpy(devif_state.device_name, service_name, strlen(service_name));
-
-    r = devq_driver_export(&devif_state);
-    assert(err_is_ok(r));
 }
 
 /*****************************************************************************/
index 6faac02..f301207 100644 (file)
 
 [ build application { target = "devif_test", 
                       cFiles = [ "queue_interface.c" ],
-                      addLibraries = [ "devif" , "sfn5122f_devif_direct"] },
-
-  build application { target = "devif_loopback_device", 
-                      cFiles = [ "loopback_device.c" ],
-                      addLibraries = [ "devif" ] },
-
-  build application { target = "devif_forward_device", 
-                      cFiles = [ "forward_device.c" ],
-                      addLibraries = [ "devif" ] }
+                      addLibraries = [ "devif" , "devif_backend_solarflare",
+                                       "devif_backend_idc"] }
 ]
diff --git a/usr/tests/devif/forward_device.c b/usr/tests/devif/forward_device.c
deleted file mode 100644 (file)
index 71aa845..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 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.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <barrelfish/barrelfish.h>
-#include <barrelfish/waitset.h>
-#include <barrelfish/deferred.h>
-#include <devif/queue_interface.h>
-
-static struct devq_func_pointer f;
-
-errval_t create_forward(struct devq* q, uint64_t flags);
-errval_t register_forward(struct devq* q, struct capref cap,
-                         regionid_t rid);
-errval_t deregister_forward(struct devq* q, regionid_t rid);
-errval_t control_forward(struct devq* q, uint64_t cmd, uint64_t value);
-errval_t destroy_forward(struct devq* q);
-errval_t notify_forward(struct devq* q, uint8_t num_slots);
-errval_t enqueue_forward(struct devq* q, regionid_t rid, bufferid_t bid, lpaddr_t base,
-                         size_t len, uint64_t flags);
-
-
-errval_t create_forward(struct devq* q, uint64_t flags)
-{
-    return SYS_ERR_OK;
-}
-
-errval_t register_forward(struct devq* q, struct capref cap,
-                         regionid_t rid) 
-{
-    return SYS_ERR_OK;
-}
-
-
-errval_t deregister_forward(struct devq* q, regionid_t rid) 
-{
-    return SYS_ERR_OK;
-}
-
-
-errval_t control_forward(struct devq* q, uint64_t cmd, uint64_t value)
-{
-    return SYS_ERR_OK;
-}
-
-
-errval_t notify_forward(struct devq* q, uint8_t num_slots)
-{
-    return SYS_ERR_OK;
-}
-
-errval_t destroy_forward(struct devq* q)
-{
-    return SYS_ERR_OK;
-}
-
-
-errval_t enqueue_forward(struct devq* q, regionid_t rid, bufferid_t bid, lpaddr_t base,
-                         size_t len, uint64_t flags)
-{
-    return SYS_ERR_OK;
-}
-
-int main(int argc, char *argv[])
-{
-
-    errval_t err;
-    struct devq* q;   
-    f.create = create_forward;
-    f.reg = register_forward;
-    f.dereg = deregister_forward;
-    f.notify = notify_forward;
-    f.destroy = destroy_forward;
-    f.ctrl = control_forward;   
-    f.enq = enqueue_forward;
-
-    struct endpoint_state my_state = {
-        .endpoint_type = ENDPOINT_TYPE_FORWARD,
-        .device_name = "", // name will be assigned 
-        .features = 0,
-        .f = f,
-    };
-
-    printf("Forward queue created\n");
-    err = devq_create(&q, &my_state, "loopback", 1);
-    if (err_is_fail(err)){
-        printf("%s \n", err_getstring(err));
-        USER_PANIC("Allocating devq failed \n");
-    }    
-
-    devq_event_loop(&my_state);
-    //messages_handler_loop();
-}
-
diff --git a/usr/tests/devif/loopback_device.c b/usr/tests/devif/loopback_device.c
deleted file mode 100644 (file)
index dad217f..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 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.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <barrelfish/barrelfish.h>
-#include <barrelfish/waitset.h>
-#include <barrelfish/deferred.h>
-#include <devif/queue_interface.h>
-#include <devif/loopback_device.h>
-
-static struct endpoint_state* state;
-
-// Prototypes
-int main(int argc, char *argv[])
-{
-    errval_t err;
-    struct devq_func_pointer f = {
-        .setup = devq_loopback_setup,
-        .create = devq_loopback_create,
-        .reg = devq_loopback_register,
-        .notify = devq_loopback_notify,
-        .dereg = devq_loopback_deregister,
-        .ctrl = devq_loopback_control,
-    };
-
-    struct endpoint_state my_state = {
-        .endpoint_type = ENDPOINT_TYPE_DEVICE,
-        .device_name = "loopback",
-        .features = 0,
-        .f = f,
-    };
-    
-    state = &my_state;
-    
-    err = devq_driver_export(&my_state);
-    if (err_is_fail(err)){  
-        abort();
-    }
-
-    devq_event_loop(&my_state);
-}
-
index 5652102..63194d0 100644 (file)
@@ -14,7 +14,7 @@
 #include <barrelfish/waitset.h>
 #include <barrelfish/deferred.h>
 #include <devif/queue_interface.h>
-#include <devif/sfn5122f_devif.h>
+#include <devif/backends/net/sfn5122f_devif.h>
 
 
 //#define TEST_FORWARD
@@ -31,7 +31,6 @@ static regionid_t regid_tx;
 static struct frame_identity id;
 static lpaddr_t phys_rx;
 static lpaddr_t phys_tx;
-static uint32_t num_dequeue = 0;
 
 static void* va_rx;
 static void* va_tx;
@@ -72,290 +71,21 @@ static void print_buffer(size_t len, bufferid_t bid)
 */
 }
 
-static errval_t create_direct(struct devq* q, uint64_t flags)
-{
-    devq_allocate_state(q, sizeof(struct direct_state));
-
-    return SYS_ERR_OK;
-}
-
-static errval_t enqueue_direct(struct devq* q, regionid_t rid,
-                        bufferid_t bid, lpaddr_t addr, size_t len,
-                        uint64_t flags)
-{
-    struct direct_state* s = (struct direct_state*) devq_get_state(q);
-    struct list_ele* ele;
-
-    ele = (struct list_ele*) malloc(sizeof(struct list_ele));
-    ele->rid = rid;
-    ele->bid = bid;
-    ele->addr = addr;
-    ele->len = len;
-    ele->flags = flags;
-    ele->next = NULL;
-
-    if (s->first == NULL) {
-        s->first = ele;
-        s->last = ele;
-    } else {
-        s->last->next = ele;
-        s->last = ele;
-    }
-    return SYS_ERR_OK;
-}
-
-static errval_t dequeue_direct(struct devq* q, regionid_t* rid,
-                        bufferid_t* bid, lpaddr_t* addr, size_t* len,
-                        uint64_t* flags)
-{
-
-    struct direct_state* s = (struct direct_state*) devq_get_state(q);
-    struct list_ele* ele;
-
-    if (s->first == NULL) {
-        return DEVQ_ERR_RX_EMPTY;
-    } else {
-        *rid = s->first->rid;
-        *bid = s->first->bid;
-        *addr = s->first->addr;
-        *len = s->first->len;
-        *flags = s->first->flags;
-        ele = s->first;
-        s->first = s->first->next;
-        free(ele);
-    }
-    return SYS_ERR_OK;
-}
-
-static errval_t register_direct(struct devq* q, struct capref cap,
-                         regionid_t rid) 
-{
-    return SYS_ERR_OK;
-}
-
-
-static errval_t deregister_direct(struct devq* q, regionid_t rid) 
-{
-    return SYS_ERR_OK;
-}
-
-
-static errval_t control_direct(struct devq* q, uint64_t cmd, uint64_t value)
-{
-    return SYS_ERR_OK;
-}
-
-static errval_t notify_normal(struct devq* q, uint8_t num_slots)
-{
-    errval_t err;
-    struct devq_buf* bufs = malloc(sizeof(struct devq_buf)*num_slots);
-    for (int i = 0; i < num_slots; i++) {
-        err = devq_dequeue(q, &(bufs[i].rid), &(bufs[i].addr),
-                           &(bufs[i].len), &(bufs[i].bid), &(bufs[i].flags));
-        if (err_is_fail(err)) {
-            return err;
-        }
-    }
-    return SYS_ERR_OK;
-}
-
-
-static errval_t notify_sfn5122f(struct devq* q, uint8_t num_slots)
-{
-    if (num_dequeue >= 64) {
-        return SYS_ERR_OK;
-    }
-
-    errval_t err;
-    struct devq_buf* buf = malloc(sizeof(struct devq_buf));
-    for (int i = 0; i < num_slots; i++) {
-        err = devq_dequeue(q, &(buf->rid), &(buf->addr),
-                           &(buf->len), &(buf->bid), &(buf->flags));
-        if (err_is_fail(err)) {
-            return err;
-        }
-
-        switch(buf->flags) {
-            case DEVQ_BUF_FLAG_TX:
-                printf("TX buffer returned \n");
-                break;
-            case (DEVQ_BUF_FLAG_TX & DEVQ_BUF_FLAG_TX_LAST):
-                printf("TX buffer returned \n");
-                break;
-            case DEVQ_BUF_FLAG_RX:
-                print_buffer(buf->len, buf->bid);
-                break;
-            default:
-                printf("Unknown flags %ld \n", buf->flags);
-        }
-        num_dequeue++;
-    }
-    return SYS_ERR_OK;
-}
-
-static void test_normal_device(void) 
-{
-
-    errval_t err;
-    struct devq* q;   
-
-    struct devq_func_pointer f = {
-        .notify = notify_normal,
-    };
-
-    struct endpoint_state my_state = {
-        .endpoint_type = ENDPOINT_TYPE_USER,
-        .device_name = "my_queue",
-        .features = 0,
-        .f = f,
-    };
-
-    printf("Normal device test started \n");
-    err = devq_create(&q, &my_state, "loopback", 1);
-    if (err_is_fail(err)){
-        USER_PANIC("Allocating devq failed \n");
-    }    
-
-    err = devq_register(q, memory_rx, &regid_rx);
-    if (err_is_fail(err)){
-        USER_PANIC("Registering memory to devq failed \n");
-    }
-    
-    bufferid_t ids[NUM_ENQ];
-    for (int j = 0; j < NUM_ROUNDS; j++) {
-        for (int i = 0; i < NUM_ENQ; i++) {
-            lpaddr_t addr = phys_rx+(j*NUM_ENQ*2048+i*2048);
-            err = devq_enqueue(q, regid_rx, addr, 2048, 
-                               1, &ids[i]);
-            if (err_is_fail(err)){
-                USER_PANIC("Devq enqueue failed \n");
-            }    
-        }
-        
-        err = devq_notify(q);
-        if (err_is_fail(err)) {
-            printf("%s",err_getstring(err));
-        }
-        event_dispatch(get_default_waitset());
-    }
-    
-    err = devq_control(q, 1, 1);
-    if (err_is_fail(err)){
-        USER_PANIC("Devq deregister failed \n");
-    }
-
-    err = devq_deregister(q, regid_rx, &memory_rx);
-    if (err_is_fail(err)){
-        USER_PANIC("Devq deregister failed \n");
-    }
-
-    err = devq_destroy(q);
-
-    printf("Normal device test ended\n");
-}
-
-static void test_direct_device(void) 
-{
-
-    errval_t err;
-    struct devq* q;   
-
-    struct devq_func_pointer f = {
-        .create = create_direct,
-        .enq = enqueue_direct,
-        .deq = dequeue_direct,
-        .reg = register_direct,
-        .dereg = deregister_direct,
-        .ctrl = control_direct,
-    };
-
-    struct endpoint_state my_state = {
-        .endpoint_type = ENDPOINT_TYPE_DIRECT,
-        .device_name = "my_queue",
-        .features = 0,
-        .f = f,
-    };
-
-    printf("Direct device test started \n");
-    err = devq_create(&q, &my_state, "loopback", 1);
-    if (err_is_fail(err)){
-        USER_PANIC("Allocating devq failed \n");
-    }    
-
-    err = devq_register(q, memory_rx, &regid_rx);
-    if (err_is_fail(err)){
-        USER_PANIC("Registering memory to devq failed \n");
-    }
-    
-    regionid_t rid;
-    bufferid_t ids[NUM_ENQ];
-    lpaddr_t addr;
-    size_t len;
-    uint64_t flags;
-    for (int j = 0; j < NUM_ROUNDS; j++) {
-        for (int i = 0; i < NUM_ENQ; i++) {
-            addr = phys_rx+(j*NUM_ENQ*2048+i*2048);
-            err = devq_enqueue(q, regid_rx, addr, 2048, 
-                               1, &ids[i]);
-            if (err_is_fail(err)){
-                USER_PANIC("Devq enqueue failed \n");
-            }    
-        }
-     
-        for (int i = 0; i < NUM_ENQ; i++) {
-            err = devq_dequeue(q, &rid, &addr, &len, &ids[i], &flags);
-            if (err_is_fail(err)){
-                USER_PANIC("Devq dequeue failed \n");
-            }    
-        }
-    }
-    
-    err = devq_control(q, 1, 1);
-    if (err_is_fail(err)){
-        printf("%s \n", err_getstring(err));
-        USER_PANIC("Devq control failed \n");
-    }
-
-    err = devq_deregister(q, regid_rx, &memory_rx);
-    if (err_is_fail(err)){
-        printf("%s \n", err_getstring(err));
-        USER_PANIC("Devq deregister failed \n");
-    }
-
-    err = devq_destroy(q);
-
-    printf("Direct device test ended\n");
-}
 
-
-#ifdef SFN_TEST_DIRECT
 static void test_sfn5122f_device_direct(void) 
 {
 
     errval_t err;
     struct devq* q;   
-
-    struct devq_func_pointer f = {
-        .create = sfn5122f_create_direct,
-        .enq = sfn5122f_enqueue_direct,
-        .deq = sfn5122f_dequeue_direct,
-        .reg = sfn5122f_register_direct,
-        .dereg = sfn5122f_deregister_direct,
-        .ctrl = sfn5122f_control_direct,
-    };
-
-    struct endpoint_state my_state = {
-        .endpoint_type = ENDPOINT_TYPE_DIRECT,
-        .device_name = "my_queue",
-        .features = 0,
-        .f = f,
-    };
+    struct sfn5122f_queue* queue;
 
     printf("SFN5122F direct device test started \n");
-    err = devq_create(&q, &my_state, "sfn5122f", 1);
+    err = sfn5122f_queue_create(&queue, true, false);
     if (err_is_fail(err)){
         USER_PANIC("Allocating devq failed \n");
     }    
+    
+    q = (struct devq*) queue;    
 
     err = devq_register(q, memory_rx, &regid_rx);
     if (err_is_fail(err)){
@@ -457,190 +187,11 @@ static void test_sfn5122f_device_direct(void)
         USER_PANIC("Devq deregister tx failed \n");
     }
 
-    err = devq_destroy(q);
+    err = sfn5122f_queue_destroy((struct sfn5122f_queue*) q);
 
     printf("SFN5122F direct device test ended\n");
 }
 
-#else
-
-static void test_sfn5122f_device(void) 
-{
-
-    errval_t err;
-    struct devq* q;   
-
-    struct devq_func_pointer f = {
-        .create = sfn5122f_create_direct,
-        .notify = notify_sfn5122f,
-    };
-
-    struct endpoint_state my_state = {
-        .endpoint_type = ENDPOINT_TYPE_USER,
-        .device_name = "my_queue",
-        .features = 0,
-        .f = f,
-    };
-
-    printf("SFN5122F device test started \n");
-    err = devq_create(&q, &my_state, "sfn5122f", 0);
-    if (err_is_fail(err)){
-        USER_PANIC("Allocating devq failed \n");
-    }    
-    err = devq_register(q, memory_rx, &regid_rx);
-    if (err_is_fail(err)){
-        USER_PANIC("Registering memory to devq failed \n");
-    }
-  
-    err = devq_register(q, memory_tx, &regid_tx);
-    if (err_is_fail(err)){
-        USER_PANIC("Registering memory to devq failed \n");
-    }
-
-    bufferid_t ids[NUM_RX_BUF];
-    lpaddr_t addr;
-
-    // Enqueue RX buffers to receive into
-    for (int i = 0; i < NUM_ROUNDS; i++){
-        addr = phys_rx+(i*2048);
-        err = devq_enqueue(q, regid_rx, addr, 2048, 
-                           DEVQ_BUF_FLAG_RX, &ids[i]);
-        if (err_is_fail(err)){
-            USER_PANIC("Devq enqueue failed: %s\n", err_getstring(err));
-        }    
-    }
-
-    err = devq_notify(q);
-    if (err_is_fail(err)){
-        USER_PANIC("Devq notify failed: %s\n", err_getstring(err));
-    }
-
-    // Wait until we removed all receive buffers   
-    while (num_dequeue < 32) {
-        event_dispatch(get_default_waitset());
-    };
-
-    // Send something
-    char* write = NULL;
-    for (int i = 0; i < NUM_ROUNDS; i++) {
-        for (int z = 0; z < NUM_ENQ; z++) {
-            addr = phys_tx+(i*NUM_ENQ*2048)+z*2048;
-            write = va_tx + (i*NUM_ENQ*2048)+z*2048;
-            for (int j = 0; j < 8; j++) {
-                write[j] = udp_header[j];
-            }
-            for (int j = 8; j < 128; j++) {
-                write[j] = 'a';
-            }
-
-            err = devq_enqueue(q, regid_tx, addr, 2048, 
-                               DEVQ_BUF_FLAG_TX | DEVQ_BUF_FLAG_TX_LAST, &ids[i]);
-            if (err_is_fail(err)){
-                USER_PANIC("Devq enqueue failed: %s \n", err_getstring(err));
-            }    
-        }
-
-        err = devq_notify(q);
-        if (err_is_fail(err)){
-            USER_PANIC("Devq notify failed \n");
-        }   
-        
-    }
-
-    // Dequeue TX buffers
-    while (num_dequeue < 64) {
-        event_dispatch(get_default_waitset());
-    };
-
-    err = devq_control(q, 1, 1);
-    if (err_is_fail(err)){
-        printf("%s \n", err_getstring(err));
-        USER_PANIC("Devq control failed \n");
-    }
-
-    err = devq_deregister(q, regid_rx, &memory_rx);
-    if (err_is_fail(err)){
-        printf("%s \n", err_getstring(err));
-        USER_PANIC("Devq deregister rx failed \n");
-    }
-
-    err = devq_deregister(q, regid_tx, &memory_tx);
-    if (err_is_fail(err)){
-        printf("%s \n", err_getstring(err));
-        USER_PANIC("Devq deregister tx failed \n");
-    }
-
-    err = devq_destroy(q);
-    printf("SFN5122F device test ended\n");
-}
-
-#endif
-
-#ifdef TEST_FORWARD
-static void test_forward_device(void) 
-{
-
-    errval_t err;
-    struct devq* q;   
-
-    struct devq_func_pointer f = {
-        .notify = notify_normal,
-    };
-
-    struct endpoint_state my_state = {
-        .endpoint_type = ENDPOINT_TYPE_USER,
-        .features = 0,
-        .f = f,
-    };
-
-    printf("Forward device test started \n");
-    err = devq_create(&q, &my_state, "forward_loopback", 1);
-    if (err_is_fail(err)){
-        USER_PANIC("Allocating devq failed \n");
-    }    
-
-    err = devq_register(q, memory_rx, &regid_rx);
-    if (err_is_fail(err)){
-        USER_PANIC("Registering memory to devq failed \n");
-    }
-    
-    bufferid_t ids[NUM_ENQ];
-    lpaddr_t addr;
-    for (int j = 0; j < NUM_ROUNDS; j++) {
-        for (int i = 0; i < NUM_ENQ; i++) {
-            addr = phys_rx+(j*NUM_ENQ*2048+i*2048);
-            err = devq_enqueue(q, regid_rx, addr, 2048, 
-                               1, &ids[i]);
-            if (err_is_fail(err)){
-                USER_PANIC("Devq enqueue failed \n");
-            }    
-        }
-     
-        err = devq_notify(q);
-        if (err_is_fail(err)) {
-            printf("%s",err_getstring(err));
-        }
-        event_dispatch(get_default_waitset());
-    }
-    
-    err = devq_control(q, 1, 1);
-    if (err_is_fail(err)){
-        printf("%s \n", err_getstring(err));
-        USER_PANIC("Devq control failed \n");
-    }
-
-    err = devq_deregister(q, regid_rx, &memory_rx);
-    if (err_is_fail(err)){
-        printf("%s \n", err_getstring(err));
-        USER_PANIC("Devq deregister failed \n");
-    }
-
-    err = devq_destroy(q);
-
-    printf("Forward device test ended\n");
-}
-#endif
-
 int main(int argc, char *argv[])
 {
     //barrelfish_usleep(1000*1000*5);
@@ -683,20 +234,7 @@ int main(int argc, char *argv[])
     }
 
     phys_tx = id.base;
-
-#ifdef TEST_FORWARD
-    test_forward_device();
-    barrelfish_usleep(1000*1000*5);
-#endif
-#ifdef SFN_TEST_DIRECT
     test_sfn5122f_device_direct();
     barrelfish_usleep(1000*1000*5);
-#else
-    test_sfn5122f_device();
-    barrelfish_usleep(1000*1000*5);
-#endif
-    test_normal_device();
-    barrelfish_usleep(1000*1000*5);
-    test_direct_device();
 }