embox

Форк
0
/
char_dev.c 
143 строки · 2.4 Кб
1
/**
2
 * @brief
3
 *
4
 * @author Aleksey Zhmulin
5
 * @date 19.02.24
6
 */
7

8
#include <assert.h>
9
#include <errno.h>
10
#include <stddef.h>
11
#include <string.h>
12

13
#include <drivers/char_dev.h>
14
#include <embox/unit.h>
15
#include <lib/libds/array.h>
16
#include <lib/libds/dlist.h>
17

18
EMBOX_UNIT_INIT(char_dev_registry_init);
19

20
static DLIST_DEFINE(char_dev_list);
21

22
struct dlist_head *const __char_dev_registry = &char_dev_list;
23

24
static int char_dev_check_name(const char *name) {
25
	struct char_dev *tmp;
26
	size_t len;
27

28
	len = strlen(name);
29

30
	if (len == 0) {
31
		return -EINVAL;
32
	}
33

34
	if (len >= sizeof(((struct char_dev *)0)->name)) {
35
		return -ENAMETOOLONG;
36
	}
37

38
	char_dev_foreach(tmp) {
39
		if (!strcmp(tmp->name, name)) {
40
			return -EEXIST;
41
		}
42
	}
43

44
	return 0;
45
}
46

47
struct char_dev *char_dev_iterate(struct char_dev *cdev) {
48
	if (!cdev) {
49
		return dlist_first_entry_or_null(&char_dev_list, struct char_dev,
50
		    list_item);
51
	}
52

53
	return dlist_next_entry_if_not_last(cdev, &char_dev_list, struct char_dev,
54
	    list_item);
55
}
56

57
struct char_dev *char_dev_find(const char *name) {
58
	struct char_dev *cdev;
59

60
	assert(name);
61

62
	char_dev_foreach(cdev) {
63
		if (!strcmp(name, cdev->name)) {
64
			return cdev;
65
		}
66
	}
67

68
	return NULL;
69
}
70

71
int char_dev_register(struct char_dev *cdev) {
72
	int err;
73

74
	assert(cdev);
75
	assert(cdev->ops);
76

77
	if ((err = char_dev_check_name(cdev->name))) {
78
		return err;
79
	}
80

81
	dlist_add_next(&cdev->list_item, __char_dev_registry);
82

83
	return 0;
84
}
85

86
int char_dev_unregister(struct char_dev *cdev) {
87
	struct char_dev *tmp;
88

89
	assert(cdev);
90

91
	char_dev_foreach(tmp) {
92
		if (tmp == cdev) {
93
			dlist_del_init(&cdev->list_item);
94
			return 0;
95
		}
96
	}
97

98
	return -EINVAL;
99
}
100

101
int char_dev_rename(struct char_dev *cdev, const char *new_name) {
102
	int err;
103

104
	assert(cdev);
105
	assert(new_name);
106

107
	if ((err = char_dev_check_name(cdev->name))) {
108
		return err;
109
	}
110

111
	strcpy(cdev->name, new_name);
112

113
	return 0;
114
}
115

116
void char_dev_init(struct char_dev *cdev, const char *name,
117
    const struct char_dev_ops *ops) {
118
	assert(cdev);
119
	assert(name);
120
	assert(ops);
121

122
	dlist_init(&cdev->list_item);
123
	cdev->usage_count = 0;
124
	cdev->ops = ops;
125

126
	strncpy(cdev->name, name, sizeof(cdev->name) - 1);
127
	cdev->name[sizeof(cdev->name) - 1] = '\0';
128
}
129

130
ARRAY_SPREAD_DEF(struct char_dev *const, __char_dev_static_registry);
131

132
static int char_dev_registry_init(void) {
133
	struct char_dev *cdev;
134
	int err;
135

136
	array_spread_foreach(cdev, __char_dev_static_registry) {
137
		if ((err = char_dev_register(cdev))) {
138
			return err;
139
		}
140
	}
141

142
	return 0;
143
}
144

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.