aboutsummaryrefslogtreecommitdiff
path: root/kernel/ethosu_network_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/ethosu_network_info.c')
-rw-r--r--kernel/ethosu_network_info.c61
1 files changed, 39 insertions, 22 deletions
diff --git a/kernel/ethosu_network_info.c b/kernel/ethosu_network_info.c
index 24be677..c2b6caa 100644
--- a/kernel/ethosu_network_info.c
+++ b/kernel/ethosu_network_info.c
@@ -40,7 +40,7 @@ static void ethosu_network_info_destroy(struct kref *kref)
dev_info(info->edev->dev, "Network info destroy. handle=0x%pK\n", info);
- list_del(&info->list);
+ list_del(&info->msg.list);
ethosu_network_put(info->net);
@@ -59,8 +59,35 @@ static int ethosu_network_info_send(struct ethosu_network_info *info)
if (ret)
return ret;
- /* Increase reference count for the pending network info response */
- ethosu_network_info_get(info);
+ return 0;
+}
+
+static void ethosu_network_info_fail(struct ethosu_mailbox_msg *msg)
+{
+ struct ethosu_network_info *info =
+ container_of(msg, typeof(*info), msg);
+
+ if (completion_done(&info->done))
+ return;
+
+ info->errno = -EFAULT;
+ complete(&info->done);
+}
+
+static int ethosu_network_info_resend(struct ethosu_mailbox_msg *msg)
+{
+ struct ethosu_network_info *info =
+ container_of(msg, typeof(*info), msg);
+ int ret;
+
+ /* Don't resend request if response has already been received */
+ if (completion_done(&info->done))
+ return 0;
+
+ /* Resend request */
+ ret = ethosu_network_info_send(info);
+ if (ret)
+ return ret;
return 0;
}
@@ -82,9 +109,11 @@ struct ethosu_network_info *ethosu_network_info_create(
info->uapi = uapi;
kref_init(&info->kref);
init_completion(&info->done);
+ info->msg.fail = ethosu_network_info_fail;
+ info->msg.resend = ethosu_network_info_resend;
/* Insert network info to network info list */
- list_add(&info->list, &edev->network_info_list);
+ list_add(&info->msg.list, &edev->mailbox.pending_list);
/* Get reference to network */
ethosu_network_get(net);
@@ -103,27 +132,14 @@ put_info:
return ERR_PTR(ret);
}
-static int ethosu_network_info_find(struct ethosu_network_info *info,
- struct list_head *network_info_list)
-{
- struct ethosu_network_info *cur;
-
- list_for_each_entry(cur, network_info_list, list) {
- if (cur == info)
- return 0;
- }
-
- return -EINVAL;
-}
-
void ethosu_network_info_get(struct ethosu_network_info *info)
{
kref_get(&info->kref);
}
-void ethosu_network_info_put(struct ethosu_network_info *info)
+int ethosu_network_info_put(struct ethosu_network_info *info)
{
- kref_put(&info->kref, ethosu_network_info_destroy);
+ return kref_put(&info->kref, ethosu_network_info_destroy);
}
int ethosu_network_info_wait(struct ethosu_network_info *info,
@@ -152,7 +168,7 @@ void ethosu_network_info_rsp(struct ethosu_device *edev,
uint32_t i;
int ret;
- ret = ethosu_network_info_find(info, &edev->network_info_list);
+ ret = ethosu_mailbox_find(&edev->mailbox, &info->msg);
if (0 != ret) {
dev_warn(edev->dev,
"Handle not found in network info list. handle=0x%p\n",
@@ -161,6 +177,9 @@ void ethosu_network_info_rsp(struct ethosu_device *edev,
return;
}
+ if (completion_done(&info->done))
+ return;
+
info->errno = 0;
if (rsp->status != ETHOSU_CORE_STATUS_OK) {
@@ -185,6 +204,4 @@ void ethosu_network_info_rsp(struct ethosu_device *edev,
signal_complete:
complete(&info->done);
-
- ethosu_network_info_put(info);
}