Linux-libre 5.4.48-gnu
[librecmc/linux-libre.git] / drivers / net / netdevsim / sdev.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2019 Mellanox Technologies. All rights reserved */
3
4 #include <linux/debugfs.h>
5 #include <linux/err.h>
6 #include <linux/kernel.h>
7 #include <linux/slab.h>
8
9 #include "netdevsim.h"
10
11 static struct dentry *nsim_sdev_ddir;
12
13 static u32 nsim_sdev_id;
14
15 struct netdevsim_shared_dev *nsim_sdev_get(struct netdevsim *joinns)
16 {
17         struct netdevsim_shared_dev *sdev;
18         char sdev_ddir_name[10];
19         int err;
20
21         if (joinns) {
22                 if (WARN_ON(!joinns->sdev))
23                         return ERR_PTR(-EINVAL);
24                 sdev = joinns->sdev;
25                 sdev->refcnt++;
26                 return sdev;
27         }
28
29         sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
30         if (!sdev)
31                 return ERR_PTR(-ENOMEM);
32         sdev->refcnt = 1;
33         sdev->switch_id = nsim_sdev_id++;
34
35         sprintf(sdev_ddir_name, "%u", sdev->switch_id);
36         sdev->ddir = debugfs_create_dir(sdev_ddir_name, nsim_sdev_ddir);
37         if (IS_ERR_OR_NULL(sdev->ddir)) {
38                 err = PTR_ERR_OR_ZERO(sdev->ddir) ?: -EINVAL;
39                 goto err_sdev_free;
40         }
41
42         return sdev;
43
44 err_sdev_free:
45         nsim_sdev_id--;
46         kfree(sdev);
47         return ERR_PTR(err);
48 }
49
50 void nsim_sdev_put(struct netdevsim_shared_dev *sdev)
51 {
52         if (--sdev->refcnt)
53                 return;
54         debugfs_remove_recursive(sdev->ddir);
55         kfree(sdev);
56 }
57
58 int nsim_sdev_init(void)
59 {
60         nsim_sdev_ddir = debugfs_create_dir(DRV_NAME "_sdev", NULL);
61         if (IS_ERR_OR_NULL(nsim_sdev_ddir))
62                 return -ENOMEM;
63         return 0;
64 }
65
66 void nsim_sdev_exit(void)
67 {
68         debugfs_remove_recursive(nsim_sdev_ddir);
69 }