btdev虚拟设备代合入

Signed-off-by: yangyanjun <yangyanjun@huawei.com>
This commit is contained in:
yangyanjun
2023-03-14 10:58:02 +08:00
parent 29c936c097
commit 76b602810a
3 changed files with 981 additions and 986 deletions
File diff suppressed because it is too large Load Diff
+135 -130
View File
@@ -1,3 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*/
#ifndef _BTDEV_H_
#define _BTDEV_H_
@@ -31,14 +36,14 @@
/* must include btdev_user.h first before any macro definition */
#include "btdev_user.h"
#define BT_DEV_MAJOR 125
#define BT_DEV_MINOR 0
#define BT_RING_BUFFER_SIZE 4096
#define STRTOLL_BASE 10
#define BT_DEV_ID_OFFSET (sizeof(BT_DEV_PATH_PREFIX) - 1)
#define BT_STATISTIC_KTIME_MAX ULONG_MAX
#define BT_DEV_MAJOR 125
#define BT_DEV_MINOR 0
#define BT_RING_BUFFER_SIZE 4096
#define STRTOLL_BASE 10
#define BT_DEV_ID_OFFSET (sizeof(BT_DEV_PATH_PREFIX) - 1)
#define BT_STATISTIC_KTIME_MAX ULONG_MAX
/*
/**
* for debug
*/
#define DEBUG
@@ -46,198 +51,198 @@
/**
* ring buffer
*/
typedef struct bt_ring {
u32 head;
u32 tail;
u32 size;
void **data;
} bt_ring_t;
struct bt_ring {
u32 head;
u32 tail;
u32 size;
void **data;
};
/**
* one char device
*/
typedef struct bt_cdev {
struct cdev *cdev;
struct class *bt_class;
char dev_filename[BT_PATHNAME_MAX];
} bt_cdev_t;
struct bt_cdev {
struct cdev *cdev;
struct class *bt_class;
char dev_filename[BT_PATHNAME_MAX];
};
typedef struct bt_mng_file {
bt_cdev_t *bt_cdev;
atomic_t open_limit;
} bt_mng_file_t;
struct bt_mng_file {
struct bt_cdev *bt_cdev;
atomic_t open_limit;
};
typedef struct bt_io_file {
bt_cdev_t *bt_cdev;
atomic_t read_open_limit;
atomic_t write_open_limit;
} bt_io_file_t;
struct bt_io_file {
struct bt_cdev *bt_cdev;
atomic_t read_open_limit;
atomic_t write_open_limit;
};
/**
* virnet list
*/
typedef struct bt_table {
struct list_head head;
struct mutex tbl_lock;
uint32_t num;
} bt_table_t;
struct bt_table {
struct list_head head;
struct mutex tbl_lock; // lock for table
u32 num;
};
/**
* bt virnet state
*/
enum bt_virnet_state {
BT_VIRNET_STATE_CREATED,
BT_VIRNET_STATE_CONNECTED,
BT_VIRNET_STATE_DISCONNECTED,
BT_VIRNET_STATE_DISABLED,
BT_VIRNET_STATE_DELETED,
BT_VIRNET_STAET_NUM
BT_VIRNET_STATE_CREATED,
BT_VIRNET_STATE_CONNECTED,
BT_VIRNET_STATE_DISCONNECTED,
BT_VIRNET_STATE_DISABLED,
BT_VIRNET_STATE_DELETED,
BT_VIRNET_STAET_NUM
};
/**
* one virnet device
*/
typedef struct bt_virnet {
bt_ring_t *tx_ring;
bt_io_file_t *io_file;
struct net_device *ndev;
struct list_head virnet_entry;
bt_table_t *bt_table_head;
enum bt_virnet_state state;
struct semaphore sem;
wait_queue_head_t rx_queue, tx_queue;
} bt_virnet_t;
struct bt_virnet {
struct bt_ring *tx_ring;
struct bt_io_file *io_file;
struct net_device *ndev;
struct list_head virnet_entry;
struct bt_table *bt_table_head;
enum bt_virnet_state state;
struct semaphore sem;
wait_queue_head_t rx_queue, tx_queue;
};
/**
* instance of the module
*/
typedef struct bt_drv {
bt_table_t *devices_table;
bt_mng_file_t *mng_file;
bt_io_file_t **io_files;
uint32_t bitmap;
struct mutex bitmap_lock;
struct class *bt_class;
} bt_drv_t;
struct bt_drv {
struct bt_table *devices_table;
struct bt_mng_file *mng_file;
struct bt_io_file **io_files;
u32 bitmap;
struct mutex bitmap_lock; // lock for bitmap
struct class *bt_class;
};
/**
* state to string
*/
static const char* bt_virnet_state_rep[BT_VIRNET_STAET_NUM] = {
"CREATED",
"CONNECTED",
"DISCONNECTED",
"DISABLED",
"ENABLED"
};
static const char *bt_virnet_state_rep[BT_VIRNET_STAET_NUM] = {
"CREATED",
"CONNECTED",
"DISCONNECTED",
"DISABLED",
"ENABLED"};
/**
* inline functions
*/
static inline int bt_get_unused_id(const uint32_t *bitmap)
static inline int bt_get_unused_id(const u32 *bitmap)
{
int i;
BUG_ON(!bitmap);
for (i=0; i<BT_VIRNET_MAX_NUM+1; ++i) {
if (!(*bitmap & (1 << i))) return i;
}
return -1; // all used
int i;
WARN_ON(!bitmap);
for (i = 0; i < BT_VIRNET_MAX_NUM + 1; ++i) {
if (!(*bitmap & (1 << i)))
return i;
}
return -1; // all used
}
static inline void bt_set_bit(uint32_t *bitmap, uint32_t idx)
static inline void bt_set_bit(u32 *bitmap, u32 idx)
{
BUG_ON(!bitmap);
*bitmap |= (1<<idx);
WARN_ON(!bitmap);
*bitmap |= (1 << idx);
}
static inline void bt_clear_bit(uint32_t *bitmap, uint32_t idx)
static inline void bt_clear_bit(u32 *bitmap, u32 idx)
{
BUG_ON(!bitmap);
*bitmap &= ~(1<<idx);
WARN_ON(!bitmap);
*bitmap &= ~(1 << idx);
}
#define SET_STATE(vn, st) bt_virnet_set_state(vn, st)
static inline void bt_virnet_set_state(bt_virnet_t *vn,
enum bt_virnet_state state)
#define SET_STATE(vn, st) bt_virnet_set_state(vn, st)
static inline void bt_virnet_set_state(struct bt_virnet *vn,
enum bt_virnet_state state)
{
BUG_ON(!vn);
vn->state = state;
WARN_ON(!vn);
vn->state = state;
}
static inline const struct cdev *bt_virnet_get_cdev(const bt_virnet_t *vn)
static inline const struct cdev *bt_virnet_get_cdev(const struct bt_virnet *vn)
{
BUG_ON(!vn);
return vn->io_file->bt_cdev->cdev;
WARN_ON(!vn);
return vn->io_file->bt_cdev->cdev;
}
static inline const dev_t bt_virnet_get_cdev_number(const bt_virnet_t *vn)
static inline const dev_t bt_virnet_get_cdev_number(const struct bt_virnet *vn)
{
BUG_ON(!vn);
return vn->io_file->bt_cdev->cdev->dev;
WARN_ON(!vn);
return vn->io_file->bt_cdev->cdev->dev;
}
static inline const char *bt_virnet_get_cdev_name(const bt_virnet_t *vn)
static inline const char *bt_virnet_get_cdev_name(const struct bt_virnet *vn)
{
BUG_ON(!vn);
return vn->io_file->bt_cdev->dev_filename;
WARN_ON(!vn);
return vn->io_file->bt_cdev->dev_filename;
}
static inline struct net_device *bt_virnet_get_ndev(const bt_virnet_t *vn)
static inline struct net_device *bt_virnet_get_ndev(const struct bt_virnet *vn)
{
BUG_ON(!vn);
return vn->ndev;
WARN_ON(!vn);
return vn->ndev;
}
static inline const char *bt_virnet_get_ndev_name(const bt_virnet_t *vn)
static inline const char *bt_virnet_get_ndev_name(const struct bt_virnet *vn)
{
BUG_ON(!vn);
return vn->ndev->name;
WARN_ON(!vn);
return vn->ndev->name;
}
static inline const char *bt_virnet_get_state_rep(const bt_virnet_t *vn)
static inline const char *bt_virnet_get_state_rep(const struct bt_virnet *vn)
{
BUG_ON(!vn);
return bt_virnet_state_rep[vn->state];
WARN_ON(!vn);
return bt_virnet_state_rep[vn->state];
}
static inline int bt_get_total_device(const bt_drv_t *bt_drv)
static inline int bt_get_total_device(const struct bt_drv *bt_drv)
{
BUG_ON(!bt_drv);
return bt_drv->devices_table->num;
WARN_ON(!bt_drv);
return bt_drv->devices_table->num;
}
static inline int bt_virnet_get_ring_packets(const bt_virnet_t *vn)
static inline int bt_virnet_get_ring_packets(const struct bt_virnet *vn)
{
int packets = 0;
BUG_ON(!vn);
packets = vn->tx_ring->head - vn->tx_ring->tail;
if (unlikely(packets < 0)) {
packets += BT_RING_BUFFER_SIZE;
}
return packets;
int packets = 0;
WARN_ON(!vn);
packets = vn->tx_ring->head - vn->tx_ring->tail;
if (unlikely(packets < 0))
packets += BT_RING_BUFFER_SIZE;
return packets;
}
static bt_table_t *bt_table_init(void);
static int bt_table_add_device(bt_table_t *tbl, bt_virnet_t *vn);
static void bt_table_remove_device(bt_table_t *tbl, bt_virnet_t *vn);
static void bt_table_delete_all(bt_drv_t *drv);
static bt_virnet_t *bt_table_find(bt_table_t *tbl, const char *ifa_name);
static void bt_table_destroy(bt_drv_t *drv);
static void bt_delete_io_files(bt_drv_t *drv);
static bt_io_file_t **bt_create_io_files(void);
static struct bt_table *bt_table_init(void);
static int bt_table_add_device(struct bt_table *tbl, struct bt_virnet *vn);
static void bt_table_remove_device(struct bt_table *tbl, struct bt_virnet *vn);
static void bt_table_delete_all(struct bt_drv *drv);
static struct bt_virnet *bt_table_find(struct bt_table *tbl, const char *ifa_name);
static void bt_table_destroy(struct bt_drv *drv);
static void bt_delete_io_files(struct bt_drv *drv);
static struct bt_io_file **bt_create_io_files(void);
static bt_ring_t *bt_ring_create(void);
static int bt_ring_is_empty(const bt_ring_t *ring);
static int bt_ring_is_full(const bt_ring_t *ring);
static void *bt_ring_current(bt_ring_t *ring);
static void bt_ring_produce(bt_ring_t *ring, void *data);
static void bt_ring_consume(bt_ring_t *ring);
static void bt_ring_clear(bt_ring_t *ring);
static void bt_ring_destroy(bt_ring_t *ring);
static struct bt_ring *bt_ring_create(void);
static int bt_ring_is_empty(const struct bt_ring *ring);
static int bt_ring_is_full(const struct bt_ring *ring);
static void *bt_ring_current(struct bt_ring *ring);
static void bt_ring_produce(struct bt_ring *ring, void *data);
static void bt_ring_consume(struct bt_ring *ring);
static void bt_ring_destroy(struct bt_ring *ring);
static int bt_virnet_produce_data(bt_virnet_t *dev, void *data);
static bt_virnet_t *bt_virnet_create(bt_drv_t *drv, uint32_t id);
static void bt_virnet_destroy(bt_virnet_t *dev);
static int bt_virnet_produce_data(struct bt_virnet *dev, void *data);
static struct bt_virnet *bt_virnet_create(struct bt_drv *drv, u32 id);
static void bt_virnet_destroy(struct bt_virnet *dev);
#endif
+29 -26
View File
@@ -1,46 +1,49 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*/
#ifndef _BTDEV_USER_H_
#define _BTDEV_USER_H_
#include <linux/if.h>
#include <linux/ioctl.h>
#define BT_VIRNET_NAME_PREFIX "btn"
#define BT_DEV_NAME_PREFIX "btdev"
#define BT_DEV_PATH_PREFIX "/dev/" BT_DEV_NAME_PREFIX
#define BT_VIRNET_NAME_PREFIX "btn"
#define BT_DEV_NAME_PREFIX "btdev"
#define BT_DEV_PATH_PREFIX "/dev/"BT_DEV_NAME_PREFIX
#define BT_DEV_PATH(idx) (BT_DEV_PATH_PREFIX#idx)
#define BT_DEV_NAME(idx) (BT_DEV_NAME_PREFIX#idx)
#define BT_DEV_PATH(idx) BT_DEV_PATH_PREFIX#idx
#define BT_DEV_NAME(idx) BT_DEV_NAME_PREFIX#idx
#define BT_DEV_NAME_MNG_FILE BT_DEV_NAME(0)
#define BT_DEV_PATH_MNG_FILE BT_DEV_PATH(0)
#define BT_DEV_NAME_IO_FILE(idx) BT_DEV_NAME(idx)
#define BT_DEV_PATH_IO_FILE(idx) BT_DEV_PATH(idx)
#define BT_VIRNET_NAME(idx) (BT_VIRNET_NAME_PREFIX#idx)
#define BT_DEV_NAME_MNG_FILE BT_DEV_NAME(0)
#define BT_DEV_PATH_MNG_FILE BT_DEV_PATH(0)
#define BT_DEV_NAME_IO_FILE(idx) BT_DEV_NAME(idx)
#define BT_DEV_PATH_IO_FILE(idx) BT_DEV_PATH(idx)
#define BT_VIRNET_NAME(idx) BT_VIRNET_NAME_PREFIX#idx
#define BT_PATHNAME_MAX 256
#define BT_VIRNET_MAX_NUM 16
#define BT_VIRNET_DATA_HEAD_LEN 2
#define BT_PATHNAME_MAX 256
#define BT_VIRNET_MAX_NUM 16
#define BT_VIRNET_DATA_HEAD_LEN 2
/*
/**
* ioctl cmd
*/
#define BT_IOC_CREATE _IO('b', 1)
#define BT_IOC_DELETE _IO('b', 2)
#define BT_IOC_CHANGE_MTU _IO('b', 3)
#define BT_IOC_QUERY_ALL _IO('b', 4)
#define BT_IOC_DELETE_ALL _IO('b', 5)
#define BT_IOC_ENABLE _IO('b', 6)
#define BT_IOC_DISABLE _IO('b', 7)
#define BT_IOC_PEEK_PACKET _IO('b', 8)
#define BT_IOC_CREATE _IO('b', 1)
#define BT_IOC_DELETE _IO('b', 2)
#define BT_IOC_CHANGE_MTU _IO('b', 3)
#define BT_IOC_QUERY_ALL _IO('b', 4)
#define BT_IOC_DELETE_ALL _IO('b', 5)
#define BT_IOC_ENABLE _IO('b', 6)
#define BT_IOC_DISABLE _IO('b', 7)
#define BT_IOC_PEEK_PACKET _IO('b', 8)
/**
* user space ioctl arguments
*/
struct bt_uioc_args {
char ifa_name[IFNAMSIZ];
char cfile_name[BT_PATHNAME_MAX];
char ifa_name[IFNAMSIZ];
char cfile_name[BT_PATHNAME_MAX];
};
#endif