embox

Форк
0
137 строк · 2.5 Кб
1
/**
2
 * @file fpga.c
3
 * @brief
4
 * @author Denis Deryugin <deryugin.denis@gmail.com>
5
 * @version
6
 * @date 27.01.2020
7
 */
8

9
#include <errno.h>
10
#include <limits.h>
11
#include <stddef.h>
12
#include <stdio.h>
13
#include <sys/types.h>
14
#include <sys/uio.h>
15

16
#include <drivers/char_dev.h>
17
#include <drivers/fpga.h>
18
#include <framework/mod/options.h>
19
#include <kernel/task/resource/idesc.h>
20
#include <lib/libds/indexator.h>
21
#include <mem/misc/pool.h>
22
#include <util/log.h>
23

24
#define FPGA_MAX OPTION_GET(NUMBER, fpga_pool_sz)
25

26
static struct fpga fpga_tab[FPGA_MAX];
27
INDEX_DEF(fpga_idx, 0, FPGA_MAX);
28

29
static const struct char_dev_ops fpga_dev_ops;
30

31
static int fpga_dev_open(struct char_dev *cdev, struct idesc *idesc) {
32
	struct fpga *fpga;
33
	int err;
34

35
	fpga = (struct fpga *)cdev;
36

37
	err = fpga->ops->config_init(fpga);
38
	if (err) {
39
		log_error("Failed to init config for FPGA");
40
		return -1;
41
	}
42

43
	return 0;
44
}
45

46
static void fpga_dev_close(struct char_dev *cdev) {
47
	struct fpga *fpga;
48
	int err;
49

50
	fpga = (struct fpga *)cdev;
51

52
	err = fpga->ops->config_complete(fpga);
53
	if (err) {
54
		log_error(".conf_complete() finished with error code %d", err);
55
	}
56
}
57

58
static ssize_t fpga_dev_read(struct char_dev *cdev, void *buf, size_t nbyte) {
59
	/* Dumping FPGA config is currently NIY */
60
	return 0;
61
}
62

63
static ssize_t fpga_dev_write(struct char_dev *cdev, const void *buf,
64
    size_t nbyte) {
65
	struct fpga *fpga;
66
	int err;
67

68
	fpga = (struct fpga *)cdev;
69

70
	err = fpga->ops->config_write(fpga, buf, nbyte);
71
	if (err) {
72
		log_error("Failed to write FPGA config");
73
		return -1;
74
	}
75

76
	return nbyte;
77
}
78

79
struct fpga *fpga_register(struct fpga_ops *ops, void *priv) {
80
	size_t id;
81
	int err;
82
	char name[NAME_MAX];
83

84
	id = index_alloc(&fpga_idx, INDEX_MIN);
85
	snprintf(name, sizeof(name), "fpga%d", id);
86

87
	fpga_tab[id] = (struct fpga){
88
	    .id = id,
89
	    .ops = ops,
90
	    .priv = priv,
91
	};
92

93
	char_dev_init(&fpga_tab[id].cdev, name, &fpga_dev_ops);
94

95
	err = char_dev_register(&fpga_tab[id].cdev);
96
	if (err) {
97
		index_free(&fpga_idx, id);
98
		return NULL;
99
	}
100

101
	return &fpga_tab[id];
102
}
103

104
int fpga_unregister(struct fpga *fpga) {
105
	if (fpga == NULL) {
106
		return -EINVAL;
107
	}
108

109
	index_free(&fpga_idx, fpga->id);
110

111
	char_dev_unregister(&fpga->cdev);
112

113
	return 0;
114
}
115

116
struct fpga *fpga_by_id(size_t id) {
117
	if (id >= FPGA_MAX) {
118
		return NULL;
119
	}
120

121
	if (!index_locked(&fpga_idx, id)) {
122
		return NULL;
123
	}
124

125
	return &fpga_tab[id];
126
}
127

128
size_t fpga_max_id(void) {
129
	return FPGA_MAX;
130
}
131

132
static const struct char_dev_ops fpga_dev_ops = {
133
    .open = fpga_dev_open,
134
    .close = fpga_dev_close,
135
    .read = fpga_dev_read,
136
    .write = fpga_dev_write,
137
};
138

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

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

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

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