Replace llist with metal_list for rpmsg channels
authorWendy Liang <jliang@xilinx.com>
Fri, 27 May 2016 22:48:32 +0000 (15:48 -0700)
committerWendy Liang <jliang@xilinx.com>
Thu, 13 Oct 2016 05:01:43 +0000 (22:01 -0700)
Use metal_list for rpmsg_channels.

Signed-off-by: Wendy Liang <jliang@xilinx.com>
lib/include/openamp/rpmsg.h
lib/include/openamp/rpmsg_core.h
lib/rpmsg/remote_device.c
lib/rpmsg/rpmsg_core.c

index fe937e2edb30d1893e345923b6016f693443b00d..8bd56d50ac9961ba176b3831bbcd282aa740cae2 100644 (file)
@@ -111,6 +111,7 @@ struct rpmsg_channel {
        struct remote_device *rdev;
        struct rpmsg_endpoint *rp_ept;
        unsigned int state;
+       struct metal_list node;
 };
 
 /**
index 26ff14f03ec5b4debaa0a5f3f643904ce0b65c32..d75ef27d0a5fa6d5f3d143a9ba27f17a6f9c4f72 100644 (file)
@@ -38,6 +38,7 @@
 #include "openamp/llist.h"
 #include "openamp/rpmsg.h"
 #include "metal/mutex.h"
+#include "metal/list.h"
 
 /* Configurable parameters */
 #define RPMSG_BUFFER_SIZE                       512
@@ -118,7 +119,7 @@ struct remote_device {
        struct virtqueue *rvq;
        struct virtqueue *tvq;
        struct hil_proc *proc;
-       struct llist *rp_channels;
+       struct metal_list rp_channels;
        struct llist *rp_endpoints;
        struct sh_mem_pool *mem_pool;
        unsigned long bitmap[RPMSG_ADDR_BMP_SIZE];
@@ -167,7 +168,7 @@ int rpmsg_rdev_init(struct remote_device **rdev, int dev_id, int role,
                    rpmsg_chnl_cb_t channel_destroyed,
                    rpmsg_rx_cb_t default_cb);
 void rpmsg_rdev_deinit(struct remote_device *rdev);
-struct llist *rpmsg_rdev_get_chnl_node_from_id(struct remote_device *rdev,
+struct rpmsg_channel *rpmsg_rdev_get_chnl_from_id(struct remote_device *rdev,
                                               char *rp_chnl_id);
 struct llist *rpmsg_rdev_get_endpoint_from_addr(struct remote_device *rdev,
                                                unsigned long addr);
index 5152b19a97c4de6b70fd8899fe887c919225beab..d808db0f5da03a940644b2d557cc9d772f8e07ca 100644 (file)
@@ -48,6 +48,7 @@
 
 #include <string.h>
 #include "openamp/rpmsg.h"
+#include "metal/utilities.h"
 
 /* Macro to initialize vring HW info */
 #define INIT_VRING_ALLOC_INFO(ring_info,vring_hw)                             \
@@ -173,15 +174,14 @@ int rpmsg_rdev_init(struct remote_device **rdev, int dev_id, int role,
  */
 void rpmsg_rdev_deinit(struct remote_device *rdev)
 {
-       struct llist *rp_chnl_head, *rp_chnl_temp, *node;
+       struct llist *node;
+       struct metal_list *chnode;
        struct rpmsg_channel *rp_chnl;
 
-       rp_chnl_head = rdev->rp_channels;
 
-       while (rp_chnl_head != RPMSG_NULL) {
-
-               rp_chnl_temp = rp_chnl_head->next;
-               rp_chnl = (struct rpmsg_channel *)rp_chnl_head->data;
+       while(!metal_list_is_empty(&rdev->rp_channels)) {
+               chnode = rdev->rp_channels.next;
+               rp_chnl = metal_container_of(chnode, struct rpmsg_channel, node);
 
                if (rdev->channel_destroyed) {
                        rdev->channel_destroyed(rp_chnl);
@@ -197,7 +197,6 @@ void rpmsg_rdev_deinit(struct remote_device *rdev)
                }
 
                _rpmsg_delete_channel(rp_chnl);
-               rp_chnl_head = rp_chnl_temp;
        }
 
        /* Delete name service endpoint */
@@ -228,7 +227,7 @@ void rpmsg_rdev_deinit(struct remote_device *rdev)
 }
 
 /**
- * rpmsg_rdev_get_chnl_node_from_id
+ * rpmsg_rdev_get_chnl_from_id
  *
  * This function returns channel node based on channel name. It must be called
  * with mutex locked.
@@ -236,24 +235,22 @@ void rpmsg_rdev_deinit(struct remote_device *rdev)
  * @param stack      - pointer to remote device
  * @param rp_chnl_id - rpmsg channel name
  *
- * @return - channel node
+ * @return - rpmsg channel
  *
  */
-struct llist *rpmsg_rdev_get_chnl_node_from_id(struct remote_device *rdev,
+struct rpmsg_channel *rpmsg_rdev_get_chnl_from_id(struct remote_device *rdev,
                                               char *rp_chnl_id)
 {
        struct rpmsg_channel *rp_chnl;
-       struct llist *rp_chnl_head;
-
-       rp_chnl_head = rdev->rp_channels;
+       struct metal_list *node;
 
-       while (rp_chnl_head) {
-               rp_chnl = (struct rpmsg_channel *)rp_chnl_head->data;
-               if (strncmp(rp_chnl->name, rp_chnl_id, sizeof(rp_chnl->name))
+       metal_list_for_each(&rdev->rp_channels, node) {
+               rp_chnl = metal_container_of(node, struct rpmsg_channel, node);
+               if (strncmp
+                   (rp_chnl->name, rp_chnl_id, sizeof(rp_chnl->name))
                    == 0) {
-                       return rp_chnl_head;
+                       return rp_chnl;
                }
-               rp_chnl_head = rp_chnl_head->next;
        }
 
        return RPMSG_NULL;
@@ -343,6 +340,7 @@ int rpmsg_rdev_init_channels(struct remote_device *rdev)
        struct proc_chnl *chnl_info;
        int num_chnls, idx;
 
+       metal_list_init(&rdev->rp_channels);
        if (rdev->role == RPMSG_MASTER) {
 
                chnl_info = hil_get_chnl_info(rdev->proc, &num_chnls);
index dd8125eb736907cc0a9fec445cee50c59c6c22de..6456382d466aeeb5853b8a046f1cb2482a7f8da3 100644 (file)
@@ -48,6 +48,7 @@
  **************************************************************************/
 #include <string.h>
 #include "openamp/rpmsg.h"
+#include "metal/utilities.h"
 
 /* Internal functions */
 static void rpmsg_rx_callback(struct virtqueue *vq);
@@ -152,7 +153,6 @@ struct rpmsg_channel *_rpmsg_create_channel(struct remote_device *rdev,
                                            unsigned long dst)
 {
        struct rpmsg_channel *rp_chnl;
-       struct llist *node;
 
        rp_chnl = env_allocate_memory(sizeof(struct rpmsg_channel));
        if (rp_chnl) {
@@ -162,14 +162,8 @@ struct rpmsg_channel *_rpmsg_create_channel(struct remote_device *rdev,
                rp_chnl->dst = dst;
                rp_chnl->rdev = rdev;
                /* Place channel on channels list */
-               node = env_allocate_memory(sizeof(struct llist));
-               if (!node) {
-                       env_free_memory(rp_chnl);
-                       return RPMSG_NULL;
-               }
-               node->data = rp_chnl;
                metal_mutex_acquire(&rdev->lock);
-               add_to_list(&rdev->rp_channels, node);
+               metal_list_add_tail(&rdev->rp_channels, &rp_chnl->node);
                metal_mutex_release(&rdev->lock);
        }
 
@@ -187,21 +181,11 @@ struct rpmsg_channel *_rpmsg_create_channel(struct remote_device *rdev,
  */
 void _rpmsg_delete_channel(struct rpmsg_channel *rp_chnl)
 {
-       struct llist *node;
        if (rp_chnl) {
                metal_mutex_acquire(&rp_chnl->rdev->lock);
-               node =
-                   rpmsg_rdev_get_chnl_node_from_id(rp_chnl->rdev,
-                                                    rp_chnl->name);
-               if (node) {
-                       remove_from_list(&rp_chnl->rdev->rp_channels, node);
-                       metal_mutex_release(&rp_chnl->rdev->lock);
-                       /* free node and rp_chnl */
-                       env_free_memory(node);
-                       env_free_memory(rp_chnl);
-               } else {
-                       metal_mutex_release(&rp_chnl->rdev->lock);
-               }
+               metal_list_del(&rp_chnl->node);
+               metal_mutex_release(&rp_chnl->rdev->lock);
+               env_free_memory(rp_chnl);
        }
 }
 
@@ -505,11 +489,10 @@ static void rpmsg_tx_callback(struct virtqueue *vq)
        struct remote_device *rdev;
        struct virtio_device *vdev;
        struct rpmsg_channel *rp_chnl;
-       struct llist *chnl_hd;
+       struct metal_list *node;
 
        vdev = (struct virtio_device *)vq->vq_dev;
        rdev = (struct remote_device *)vdev;
-       chnl_hd = rdev->rp_channels;
 
        /* Check if the remote device is master. */
        if (rdev->role == RPMSG_MASTER) {
@@ -522,8 +505,9 @@ static void rpmsg_tx_callback(struct virtqueue *vq)
                 * b. It will update the channel state to active so that further communication
                 *    can take place.
                 */
-               while (chnl_hd != RPMSG_NULL) {
-                       rp_chnl = (struct rpmsg_channel *)chnl_hd->data;
+               metal_list_for_each(&rdev->rp_channels, node) {
+                       rp_chnl = metal_container_of(node,
+                               struct rpmsg_channel, node);
 
                        if (rp_chnl->state == RPMSG_CHNL_STATE_IDLE) {
 
@@ -540,7 +524,6 @@ static void rpmsg_tx_callback(struct virtqueue *vq)
                                }
                        }
 
-                       chnl_hd = chnl_hd->next;
                }
        }
 }
@@ -561,25 +544,27 @@ void rpmsg_rx_callback(struct virtqueue *vq)
        struct rpmsg_endpoint *rp_ept;
        struct rpmsg_hdr *rp_hdr;
        struct llist *node;
+       struct metal_list *chnode;
        unsigned long len;
        unsigned short idx;
-       struct llist *chnl_hd;
 
        vdev = (struct virtio_device *)vq->vq_dev;
        rdev = (struct remote_device *)vdev;
 
-       chnl_hd = rdev->rp_channels;
-       if ((chnl_hd != RPMSG_NULL) && (rdev->role == RPMSG_MASTER)) {
-               rp_chnl = (struct rpmsg_channel *)chnl_hd->data;
-               if (rp_chnl->state == RPMSG_CHNL_STATE_IDLE) {
-                       if (rdev->support_ns) {
-                               rp_chnl->state = RPMSG_CHNL_STATE_NS;
-                               rpmsg_send_ns_message(rdev, rp_chnl,
+       if (rdev->role == RPMSG_MASTER) {
+               metal_list_for_each(&rdev->rp_channels, chnode) {
+                       rp_chnl = metal_container_of(chnode,
+                               struct rpmsg_channel, node);
+                       if (rp_chnl->state == RPMSG_CHNL_STATE_IDLE) {
+                               if (rdev->support_ns) {
+                                       rp_chnl->state = RPMSG_CHNL_STATE_NS;
+                                       rpmsg_send_ns_message(rdev, rp_chnl,
                                                      RPMSG_NS_CREATE);
-                       } else {
-                               rp_chnl->state = RPMSG_CHNL_STATE_ACTIVE;
+                               } else {
+                                       rp_chnl->state = RPMSG_CHNL_STATE_ACTIVE;
+                               }
+                               return;
                        }
-                       return;
                }
        }
 
@@ -651,7 +636,6 @@ void rpmsg_ns_callback(struct rpmsg_channel *server_chnl, void *data, int len,
        struct remote_device *rdev;
        struct rpmsg_channel *rp_chnl;
        struct rpmsg_ns_msg *ns_msg;
-       struct llist *node;
 
        (void)server_chnl;
        (void)src;
@@ -667,10 +651,9 @@ void rpmsg_ns_callback(struct rpmsg_channel *server_chnl, void *data, int len,
 
        if (ns_msg->flags & RPMSG_NS_DESTROY) {
                metal_mutex_acquire(&rdev->lock);
-               node = rpmsg_rdev_get_chnl_node_from_id(rdev, ns_msg->name);
+               rp_chnl = rpmsg_rdev_get_chnl_from_id(rdev, ns_msg->name);
                metal_mutex_release(&rdev->lock);
-               if (node) {
-                       rp_chnl = (struct rpmsg_channel *)node->data;
+               if (rp_chnl) {
                        if (rdev->channel_destroyed) {
                                rdev->channel_destroyed(rp_chnl);
                        }