1 // SPDX-License-Identifier: GPL-2.0
3 * Shared Memory Communications Direct over loopback-ism device.
5 * Functions for loopback-ism device.
7 * Copyright (c) 2024, Alibaba Inc.
9 * Author: Wen Gu <guwen@linux.alibaba.com>
10 * Tony Lu <tonylu@linux.alibaba.com>
14 #include <linux/device.h>
15 #include <linux/types.h>
19 #include "smc_loopback.h"
21 static const char smc_lo_dev_name[] = "loopback-ism";
22 static struct smc_lo_dev *lo_dev;
24 static const struct smcd_ops lo_ops = {
25 .query_remote_gid = NULL,
27 .unregister_dmb = NULL,
30 .set_vlan_required = NULL,
31 .reset_vlan_required = NULL,
35 .get_local_gid = NULL,
40 static struct smcd_dev *smcd_lo_alloc_dev(const struct smcd_ops *ops,
43 struct smcd_dev *smcd;
45 smcd = kzalloc(sizeof(*smcd), GFP_KERNEL);
49 smcd->conn = kcalloc(max_dmbs, sizeof(struct smc_connection *),
56 spin_lock_init(&smcd->lock);
57 spin_lock_init(&smcd->lgr_lock);
58 INIT_LIST_HEAD(&smcd->vlan);
59 INIT_LIST_HEAD(&smcd->lgr_list);
60 init_waitqueue_head(&smcd->lgrs_deleted);
68 static int smcd_lo_register_dev(struct smc_lo_dev *ldev)
70 struct smcd_dev *smcd;
72 smcd = smcd_lo_alloc_dev(&lo_ops, SMC_LO_MAX_DMBS);
79 * register loopback-ism to smcd_dev list.
84 static void smcd_lo_unregister_dev(struct smc_lo_dev *ldev)
86 struct smcd_dev *smcd = ldev->smcd;
89 * unregister loopback-ism from smcd_dev list.
95 static int smc_lo_dev_init(struct smc_lo_dev *ldev)
97 return smcd_lo_register_dev(ldev);
100 static void smc_lo_dev_exit(struct smc_lo_dev *ldev)
102 smcd_lo_unregister_dev(ldev);
105 static void smc_lo_dev_release(struct device *dev)
107 struct smc_lo_dev *ldev =
108 container_of(dev, struct smc_lo_dev, dev);
113 static int smc_lo_dev_probe(void)
115 struct smc_lo_dev *ldev;
118 ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
122 ldev->dev.parent = NULL;
123 ldev->dev.release = smc_lo_dev_release;
124 device_initialize(&ldev->dev);
125 dev_set_name(&ldev->dev, smc_lo_dev_name);
127 ret = smc_lo_dev_init(ldev);
131 lo_dev = ldev; /* global loopback device */
135 put_device(&ldev->dev);
139 static void smc_lo_dev_remove(void)
144 smc_lo_dev_exit(lo_dev);
145 put_device(&lo_dev->dev); /* device_initialize in smc_lo_dev_probe */
148 int smc_loopback_init(void)
150 return smc_lo_dev_probe();
153 void smc_loopback_exit(void)