18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * fs/hmdfs/comm/node_cb.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/list.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include "node_cb.h"
118c2ecf20Sopenharmony_ci#include "connection.h"
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_cistatic struct list_head cb_head[NODE_EVT_NR][NODE_EVT_TYPE_NR];
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistatic const char *evt_str_tbl[NODE_EVT_NR] = {
168c2ecf20Sopenharmony_ci	"add", "online", "offline", "del",
178c2ecf20Sopenharmony_ci};
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_cistatic inline bool hmdfs_is_valid_node_evt(int evt)
208c2ecf20Sopenharmony_ci{
218c2ecf20Sopenharmony_ci	return (evt >= 0 && evt < NODE_EVT_NR);
228c2ecf20Sopenharmony_ci}
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_cistatic const char *hmdfs_evt_str(int evt)
258c2ecf20Sopenharmony_ci{
268c2ecf20Sopenharmony_ci	if (!hmdfs_is_valid_node_evt(evt))
278c2ecf20Sopenharmony_ci		return "unknown";
288c2ecf20Sopenharmony_ci	return evt_str_tbl[evt];
298c2ecf20Sopenharmony_ci}
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_civoid hmdfs_node_evt_cb_init(void)
328c2ecf20Sopenharmony_ci{
338c2ecf20Sopenharmony_ci	int i;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(cb_head); i++) {
368c2ecf20Sopenharmony_ci		int j;
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci		for (j = 0; j < ARRAY_SIZE(cb_head[0]); j++)
398c2ecf20Sopenharmony_ci			INIT_LIST_HEAD(&cb_head[i][j]);
408c2ecf20Sopenharmony_ci	}
418c2ecf20Sopenharmony_ci}
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_civoid hmdfs_node_add_evt_cb(struct hmdfs_node_cb_desc *desc, int nr)
448c2ecf20Sopenharmony_ci{
458c2ecf20Sopenharmony_ci	int i;
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	for (i = 0; i < nr; i++) {
488c2ecf20Sopenharmony_ci		int evt = desc[i].evt;
498c2ecf20Sopenharmony_ci		bool sync = desc[i].sync;
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci		if (!hmdfs_is_valid_node_evt(evt))
528c2ecf20Sopenharmony_ci			continue;
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci		list_add_tail(&desc[i].list, &cb_head[evt][sync]);
558c2ecf20Sopenharmony_ci	}
568c2ecf20Sopenharmony_ci}
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_civoid hmdfs_node_call_evt_cb(struct hmdfs_peer *conn, int evt, bool sync,
598c2ecf20Sopenharmony_ci			    unsigned int seq)
608c2ecf20Sopenharmony_ci{
618c2ecf20Sopenharmony_ci	struct hmdfs_node_cb_desc *desc = NULL;
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	hmdfs_info("node 0x%x:0x%llx call %s %s cb seq %u",
648c2ecf20Sopenharmony_ci		   conn->owner, conn->device_id, hmdfs_evt_str(evt),
658c2ecf20Sopenharmony_ci		   sync ? "sync" : "async", seq);
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	if (!hmdfs_is_valid_node_evt(evt))
688c2ecf20Sopenharmony_ci		return;
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci	list_for_each_entry(desc, &cb_head[evt][sync], list) {
718c2ecf20Sopenharmony_ci		desc->fn(conn, evt, seq);
728c2ecf20Sopenharmony_ci	}
738c2ecf20Sopenharmony_ci}
74