70 строки
1.4 KiB
C
70 строки
1.4 KiB
C
|
// SPDX-License-Identifier: GPL-2.0
|
||
|
/* Copyright (c) 2019 Mellanox Technologies. All rights reserved */
|
||
|
|
||
|
#include <linux/debugfs.h>
|
||
|
#include <linux/err.h>
|
||
|
#include <linux/kernel.h>
|
||
|
#include <linux/slab.h>
|
||
|
|
||
|
#include "netdevsim.h"
|
||
|
|
||
|
static struct dentry *nsim_sdev_ddir;
|
||
|
|
||
|
static u32 nsim_sdev_id;
|
||
|
|
||
|
struct netdevsim_shared_dev *nsim_sdev_get(struct netdevsim *joinns)
|
||
|
{
|
||
|
struct netdevsim_shared_dev *sdev;
|
||
|
char sdev_ddir_name[10];
|
||
|
int err;
|
||
|
|
||
|
if (joinns) {
|
||
|
if (WARN_ON(!joinns->sdev))
|
||
|
return ERR_PTR(-EINVAL);
|
||
|
sdev = joinns->sdev;
|
||
|
sdev->refcnt++;
|
||
|
return sdev;
|
||
|
}
|
||
|
|
||
|
sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
|
||
|
if (!sdev)
|
||
|
return ERR_PTR(-ENOMEM);
|
||
|
sdev->refcnt = 1;
|
||
|
sdev->switch_id = nsim_sdev_id++;
|
||
|
|
||
|
sprintf(sdev_ddir_name, "%u", sdev->switch_id);
|
||
|
sdev->ddir = debugfs_create_dir(sdev_ddir_name, nsim_sdev_ddir);
|
||
|
if (IS_ERR_OR_NULL(sdev->ddir)) {
|
||
|
err = PTR_ERR_OR_ZERO(sdev->ddir) ?: -EINVAL;
|
||
|
goto err_sdev_free;
|
||
|
}
|
||
|
|
||
|
return sdev;
|
||
|
|
||
|
err_sdev_free:
|
||
|
nsim_sdev_id--;
|
||
|
kfree(sdev);
|
||
|
return ERR_PTR(err);
|
||
|
}
|
||
|
|
||
|
void nsim_sdev_put(struct netdevsim_shared_dev *sdev)
|
||
|
{
|
||
|
if (--sdev->refcnt)
|
||
|
return;
|
||
|
debugfs_remove_recursive(sdev->ddir);
|
||
|
kfree(sdev);
|
||
|
}
|
||
|
|
||
|
int nsim_sdev_init(void)
|
||
|
{
|
||
|
nsim_sdev_ddir = debugfs_create_dir(DRV_NAME "_sdev", NULL);
|
||
|
if (IS_ERR_OR_NULL(nsim_sdev_ddir))
|
||
|
return -ENOMEM;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void nsim_sdev_exit(void)
|
||
|
{
|
||
|
debugfs_remove_recursive(nsim_sdev_ddir);
|
||
|
}
|