root / xseg / drivers / user / xseg_segdev.c @ 9fb0f83b
History | View | Annotate | Download (4.1 kB)
1 | 6e0a3771 | Georgios D. Tsoukalas | #define _GNU_SOURCE
|
---|---|---|---|
2 | 6e0a3771 | Georgios D. Tsoukalas | #include <stdio.h> |
3 | 6e0a3771 | Georgios D. Tsoukalas | #include <stdlib.h> |
4 | 6e0a3771 | Georgios D. Tsoukalas | #include <unistd.h> |
5 | 6e0a3771 | Georgios D. Tsoukalas | #include <sys/types.h> |
6 | 6e0a3771 | Georgios D. Tsoukalas | #include <sys/stat.h> |
7 | 6e0a3771 | Georgios D. Tsoukalas | #include <sys/ioctl.h> |
8 | 6e0a3771 | Georgios D. Tsoukalas | #include <sys/mman.h> |
9 | 6e0a3771 | Georgios D. Tsoukalas | #include <sys/syscall.h> |
10 | 6e0a3771 | Georgios D. Tsoukalas | #include <fcntl.h> |
11 | 6e0a3771 | Georgios D. Tsoukalas | #include <errno.h> |
12 | 6e0a3771 | Georgios D. Tsoukalas | #include <string.h> |
13 | 6e0a3771 | Georgios D. Tsoukalas | #include <signal.h> |
14 | 6e0a3771 | Georgios D. Tsoukalas | #include <xseg/xseg.h> |
15 | 6e0a3771 | Georgios D. Tsoukalas | #include <sys/util.h> |
16 | 6e0a3771 | Georgios D. Tsoukalas | #include <sys/kernel/segdev.h> |
17 | 6e0a3771 | Georgios D. Tsoukalas | |
18 | 6e0a3771 | Georgios D. Tsoukalas | #define ERRSIZE 512 |
19 | 6e0a3771 | Georgios D. Tsoukalas | static char errbuf[ERRSIZE]; |
20 | 6e0a3771 | Georgios D. Tsoukalas | |
21 | 6e0a3771 | Georgios D. Tsoukalas | #define SEGDEV_DEVICE "/dev/segdev" |
22 | 6e0a3771 | Georgios D. Tsoukalas | static int fdev = -1; |
23 | 6e0a3771 | Georgios D. Tsoukalas | |
24 | 6e0a3771 | Georgios D. Tsoukalas | static int opendev(void) |
25 | 6e0a3771 | Georgios D. Tsoukalas | { |
26 | 6e0a3771 | Georgios D. Tsoukalas | if (fdev >= 0) |
27 | 6e0a3771 | Georgios D. Tsoukalas | return fdev;
|
28 | 6e0a3771 | Georgios D. Tsoukalas | |
29 | 6e0a3771 | Georgios D. Tsoukalas | fdev = open(SEGDEV_DEVICE, O_RDWR); |
30 | 6e0a3771 | Georgios D. Tsoukalas | if (fdev < 0) { |
31 | 6e0a3771 | Georgios D. Tsoukalas | XSEGLOG("Cannot open %s: %s\n", SEGDEV_DEVICE,
|
32 | 6e0a3771 | Georgios D. Tsoukalas | strerror_r(errno, errbuf, ERRSIZE)); |
33 | 6e0a3771 | Georgios D. Tsoukalas | fdev = -1;
|
34 | 6e0a3771 | Georgios D. Tsoukalas | } |
35 | 6e0a3771 | Georgios D. Tsoukalas | return fdev;
|
36 | 6e0a3771 | Georgios D. Tsoukalas | } |
37 | 6e0a3771 | Georgios D. Tsoukalas | |
38 | 6e0a3771 | Georgios D. Tsoukalas | static int closedev(void) |
39 | 6e0a3771 | Georgios D. Tsoukalas | { |
40 | 6e0a3771 | Georgios D. Tsoukalas | int r;
|
41 | 6e0a3771 | Georgios D. Tsoukalas | if (fdev < 0) |
42 | 6e0a3771 | Georgios D. Tsoukalas | return 0; |
43 | 6e0a3771 | Georgios D. Tsoukalas | |
44 | 6e0a3771 | Georgios D. Tsoukalas | r = close(fdev); |
45 | 6e0a3771 | Georgios D. Tsoukalas | if (r < 0) { |
46 | 6e0a3771 | Georgios D. Tsoukalas | XSEGLOG("Cannot close %s: %s\n", SEGDEV_DEVICE,
|
47 | 6e0a3771 | Georgios D. Tsoukalas | strerror_r(errno, errbuf, ERRSIZE)); |
48 | 6e0a3771 | Georgios D. Tsoukalas | return -1; |
49 | 6e0a3771 | Georgios D. Tsoukalas | } else
|
50 | 6e0a3771 | Georgios D. Tsoukalas | fdev = -1;
|
51 | 6e0a3771 | Georgios D. Tsoukalas | |
52 | 6e0a3771 | Georgios D. Tsoukalas | return 0; |
53 | 6e0a3771 | Georgios D. Tsoukalas | } |
54 | 6e0a3771 | Georgios D. Tsoukalas | |
55 | 6e0a3771 | Georgios D. Tsoukalas | static long segdev_allocate(const char *name, uint64_t size) |
56 | 6e0a3771 | Georgios D. Tsoukalas | { |
57 | 6e0a3771 | Georgios D. Tsoukalas | int fd;
|
58 | 6e0a3771 | Georgios D. Tsoukalas | long oldsize;
|
59 | 6e0a3771 | Georgios D. Tsoukalas | |
60 | 6e0a3771 | Georgios D. Tsoukalas | fd = opendev(); |
61 | 6e0a3771 | Georgios D. Tsoukalas | if (fd < 0) |
62 | 6e0a3771 | Georgios D. Tsoukalas | return fd;
|
63 | 6e0a3771 | Georgios D. Tsoukalas | |
64 | 6e0a3771 | Georgios D. Tsoukalas | oldsize = ioctl(fd, SEGDEV_IOC_SEGSIZE, 0);
|
65 | 6e0a3771 | Georgios D. Tsoukalas | if (oldsize >= 0) { |
66 | 6e0a3771 | Georgios D. Tsoukalas | XSEGLOG("Destroying old segment\n");
|
67 | 6e0a3771 | Georgios D. Tsoukalas | if (ioctl(fd, SEGDEV_IOC_DESTROYSEG, 0)) { |
68 | 6e0a3771 | Georgios D. Tsoukalas | XSEGLOG("Failed to destroy old segment");
|
69 | 6e0a3771 | Georgios D. Tsoukalas | closedev(); |
70 | 6e0a3771 | Georgios D. Tsoukalas | return -2; |
71 | 6e0a3771 | Georgios D. Tsoukalas | } |
72 | 6e0a3771 | Georgios D. Tsoukalas | } |
73 | 6e0a3771 | Georgios D. Tsoukalas | |
74 | b04e0466 | User | XSEGLOG("creating segment of size %llu\n", size);
|
75 | b04e0466 | User | |
76 | 6e0a3771 | Georgios D. Tsoukalas | if (ioctl(fd, SEGDEV_IOC_CREATESEG, size)) {
|
77 | 6e0a3771 | Georgios D. Tsoukalas | XSEGLOG("Failed to create segment");
|
78 | 6e0a3771 | Georgios D. Tsoukalas | closedev(); |
79 | 6e0a3771 | Georgios D. Tsoukalas | return -3; |
80 | 6e0a3771 | Georgios D. Tsoukalas | } |
81 | 6e0a3771 | Georgios D. Tsoukalas | |
82 | 6e0a3771 | Georgios D. Tsoukalas | return 0; |
83 | 6e0a3771 | Georgios D. Tsoukalas | } |
84 | 6e0a3771 | Georgios D. Tsoukalas | |
85 | 6e0a3771 | Georgios D. Tsoukalas | static long segdev_deallocate(const char *name) |
86 | 6e0a3771 | Georgios D. Tsoukalas | { |
87 | 6e0a3771 | Georgios D. Tsoukalas | int fd;
|
88 | 6e0a3771 | Georgios D. Tsoukalas | fd = open(SEGDEV_DEVICE, O_RDWR); |
89 | 6e0a3771 | Georgios D. Tsoukalas | if (fd < 0) { |
90 | 6e0a3771 | Georgios D. Tsoukalas | XSEGLOG("Cannot open %s: %s\n", SEGDEV_DEVICE,
|
91 | 6e0a3771 | Georgios D. Tsoukalas | strerror_r(errno, errbuf, ERRSIZE)); |
92 | 6e0a3771 | Georgios D. Tsoukalas | return -1; |
93 | 6e0a3771 | Georgios D. Tsoukalas | } |
94 | 6e0a3771 | Georgios D. Tsoukalas | |
95 | 6e0a3771 | Georgios D. Tsoukalas | if (ioctl(fd, SEGDEV_IOC_DESTROYSEG, 0)) { |
96 | 6e0a3771 | Georgios D. Tsoukalas | XSEGLOG("Failed to destroy old segment");
|
97 | 6e0a3771 | Georgios D. Tsoukalas | return -2; |
98 | 6e0a3771 | Georgios D. Tsoukalas | } |
99 | 6e0a3771 | Georgios D. Tsoukalas | |
100 | 6e0a3771 | Georgios D. Tsoukalas | closedev(); |
101 | 6e0a3771 | Georgios D. Tsoukalas | return 0; |
102 | 6e0a3771 | Georgios D. Tsoukalas | } |
103 | 6e0a3771 | Georgios D. Tsoukalas | |
104 | 7ce25cf6 | Stratos Psomadakis | static void *segdev_map(const char *name, uint64_t size, struct xseg *seg) |
105 | 6e0a3771 | Georgios D. Tsoukalas | { |
106 | 6e0a3771 | Georgios D. Tsoukalas | struct xseg *xseg;
|
107 | 6e0a3771 | Georgios D. Tsoukalas | int fd;
|
108 | 7ce25cf6 | Stratos Psomadakis | |
109 | 7ce25cf6 | Stratos Psomadakis | if (seg)
|
110 | 7ce25cf6 | Stratos Psomadakis | XSEGLOG("struct xseg * not NULL. Ignoring...\n");
|
111 | 7ce25cf6 | Stratos Psomadakis | |
112 | 6e0a3771 | Georgios D. Tsoukalas | fd = opendev(); |
113 | 6e0a3771 | Georgios D. Tsoukalas | if (fd < 0) |
114 | 6e0a3771 | Georgios D. Tsoukalas | return NULL; |
115 | 6e0a3771 | Georgios D. Tsoukalas | |
116 | 6e0a3771 | Georgios D. Tsoukalas | xseg = mmap ( XSEG_BASE_AS_PTR, |
117 | 6e0a3771 | Georgios D. Tsoukalas | size, |
118 | 6e0a3771 | Georgios D. Tsoukalas | PROT_READ | PROT_WRITE, |
119 | 6e0a3771 | Georgios D. Tsoukalas | MAP_SHARED | MAP_FIXED /* | MAP_LOCKED */,
|
120 | 6e0a3771 | Georgios D. Tsoukalas | fd, 0 );
|
121 | 6e0a3771 | Georgios D. Tsoukalas | |
122 | 6e0a3771 | Georgios D. Tsoukalas | if (xseg == MAP_FAILED) {
|
123 | 6e0a3771 | Georgios D. Tsoukalas | XSEGLOG("Could not map segment: %s\n",
|
124 | 6e0a3771 | Georgios D. Tsoukalas | strerror_r(errno, errbuf, ERRSIZE)); |
125 | 6e0a3771 | Georgios D. Tsoukalas | closedev(); |
126 | 6e0a3771 | Georgios D. Tsoukalas | return NULL; |
127 | 6e0a3771 | Georgios D. Tsoukalas | } |
128 | 6e0a3771 | Georgios D. Tsoukalas | |
129 | 6e0a3771 | Georgios D. Tsoukalas | return xseg;
|
130 | 6e0a3771 | Georgios D. Tsoukalas | } |
131 | 6e0a3771 | Georgios D. Tsoukalas | |
132 | 6e0a3771 | Georgios D. Tsoukalas | static void segdev_unmap(void *ptr, uint64_t size) |
133 | 6e0a3771 | Georgios D. Tsoukalas | { |
134 | 6e0a3771 | Georgios D. Tsoukalas | struct xseg *xseg = ptr;
|
135 | 6e0a3771 | Georgios D. Tsoukalas | (void)munmap(xseg, xseg->segment_size);
|
136 | 6e0a3771 | Georgios D. Tsoukalas | } |
137 | 6e0a3771 | Georgios D. Tsoukalas | |
138 | 6e0a3771 | Georgios D. Tsoukalas | |
139 | 6e0a3771 | Georgios D. Tsoukalas | static struct xseg_type xseg_segdev = { |
140 | 6e0a3771 | Georgios D. Tsoukalas | /* xseg_operations */
|
141 | 6e0a3771 | Georgios D. Tsoukalas | { |
142 | 6e0a3771 | Georgios D. Tsoukalas | .allocate = segdev_allocate, |
143 | 6e0a3771 | Georgios D. Tsoukalas | .deallocate = segdev_deallocate, |
144 | 6e0a3771 | Georgios D. Tsoukalas | .map = segdev_map, |
145 | 6e0a3771 | Georgios D. Tsoukalas | .unmap = segdev_unmap |
146 | 6e0a3771 | Georgios D. Tsoukalas | }, |
147 | 6e0a3771 | Georgios D. Tsoukalas | /* name */
|
148 | 6e0a3771 | Georgios D. Tsoukalas | "segdev"
|
149 | 6e0a3771 | Georgios D. Tsoukalas | }; |
150 | 6e0a3771 | Georgios D. Tsoukalas | |
151 | 9fb0f83b | Filippos Giannakos | static int segdev_local_signal_init(void) |
152 | 9fb0f83b | Filippos Giannakos | { |
153 | 9fb0f83b | Filippos Giannakos | return -1; |
154 | 9fb0f83b | Filippos Giannakos | } |
155 | 9fb0f83b | Filippos Giannakos | |
156 | 9fb0f83b | Filippos Giannakos | static void segdev_local_signal_quit(void) |
157 | 9fb0f83b | Filippos Giannakos | { |
158 | 9fb0f83b | Filippos Giannakos | return;
|
159 | 9fb0f83b | Filippos Giannakos | } |
160 | 9fb0f83b | Filippos Giannakos | |
161 | 9fb0f83b | Filippos Giannakos | static int segdev_remote_signal_init(void) |
162 | 6e0a3771 | Georgios D. Tsoukalas | { |
163 | 6e0a3771 | Georgios D. Tsoukalas | return 0; |
164 | 6e0a3771 | Georgios D. Tsoukalas | } |
165 | 6e0a3771 | Georgios D. Tsoukalas | |
166 | 9fb0f83b | Filippos Giannakos | static void segdev_remote_signal_quit(void) |
167 | 6e0a3771 | Georgios D. Tsoukalas | { |
168 | 6e0a3771 | Georgios D. Tsoukalas | return;
|
169 | 6e0a3771 | Georgios D. Tsoukalas | } |
170 | 6e0a3771 | Georgios D. Tsoukalas | |
171 | 6e0a3771 | Georgios D. Tsoukalas | static int segdev_prepare_wait(struct xseg *xseg, uint32_t portno) |
172 | 6e0a3771 | Georgios D. Tsoukalas | { |
173 | 6e0a3771 | Georgios D. Tsoukalas | return -1; |
174 | 6e0a3771 | Georgios D. Tsoukalas | } |
175 | 6e0a3771 | Georgios D. Tsoukalas | |
176 | 6e0a3771 | Georgios D. Tsoukalas | static int segdev_cancel_wait(struct xseg *xseg, uint32_t portno) |
177 | 6e0a3771 | Georgios D. Tsoukalas | { |
178 | 6e0a3771 | Georgios D. Tsoukalas | return -1; |
179 | 6e0a3771 | Georgios D. Tsoukalas | } |
180 | 6e0a3771 | Georgios D. Tsoukalas | |
181 | 6e0a3771 | Georgios D. Tsoukalas | static int segdev_wait_signal(struct xseg *xseg, uint32_t timeout) |
182 | 6e0a3771 | Georgios D. Tsoukalas | { |
183 | 6e0a3771 | Georgios D. Tsoukalas | return -1; |
184 | 6e0a3771 | Georgios D. Tsoukalas | } |
185 | 6e0a3771 | Georgios D. Tsoukalas | |
186 | 6e0a3771 | Georgios D. Tsoukalas | static int segdev_signal(struct xseg *xseg, uint32_t portno) |
187 | 6e0a3771 | Georgios D. Tsoukalas | { |
188 | e2c7b35a | User | struct xseg_port *port = xseg_get_port(xseg, portno);
|
189 | e2c7b35a | User | if (!port)
|
190 | e2c7b35a | User | return -1; |
191 | ed7d5d7c | Giannakos Filippos | |
192 | e2c7b35a | User | if (!port->waitcue)
|
193 | e2c7b35a | User | return 0; |
194 | e2c7b35a | User | else
|
195 | e2c7b35a | User | return write(opendev(), &portno, sizeof(portno)); |
196 | 6e0a3771 | Georgios D. Tsoukalas | } |
197 | 6e0a3771 | Georgios D. Tsoukalas | |
198 | 6e0a3771 | Georgios D. Tsoukalas | static void *segdev_malloc(uint64_t size) |
199 | 6e0a3771 | Georgios D. Tsoukalas | { |
200 | 6e0a3771 | Georgios D. Tsoukalas | return NULL; |
201 | 6e0a3771 | Georgios D. Tsoukalas | } |
202 | 6e0a3771 | Georgios D. Tsoukalas | |
203 | 6e0a3771 | Georgios D. Tsoukalas | static void *segdev_realloc(void *mem, uint64_t size) |
204 | 6e0a3771 | Georgios D. Tsoukalas | { |
205 | 6e0a3771 | Georgios D. Tsoukalas | return NULL; |
206 | 6e0a3771 | Georgios D. Tsoukalas | } |
207 | 6e0a3771 | Georgios D. Tsoukalas | |
208 | 6e0a3771 | Georgios D. Tsoukalas | static void segdev_mfree(void *mem) { } |
209 | 6e0a3771 | Georgios D. Tsoukalas | |
210 | 6e0a3771 | Georgios D. Tsoukalas | static struct xseg_peer xseg_peer_segdev = { |
211 | 6e0a3771 | Georgios D. Tsoukalas | /* xseg signal operations */
|
212 | 6e0a3771 | Georgios D. Tsoukalas | { |
213 | 9fb0f83b | Filippos Giannakos | .local_signal_init = segdev_local_signal_init, |
214 | 9fb0f83b | Filippos Giannakos | .local_signal_quit = segdev_local_signal_quit, |
215 | 9fb0f83b | Filippos Giannakos | .remote_signal_init = segdev_remote_signal_init, |
216 | 9fb0f83b | Filippos Giannakos | .remote_signal_quit = segdev_remote_signal_quit, |
217 | 6e0a3771 | Georgios D. Tsoukalas | .prepare_wait = segdev_prepare_wait, |
218 | 6e0a3771 | Georgios D. Tsoukalas | .cancel_wait = segdev_cancel_wait, |
219 | 6e0a3771 | Georgios D. Tsoukalas | .wait_signal = segdev_wait_signal, |
220 | 6e0a3771 | Georgios D. Tsoukalas | .signal = segdev_signal, |
221 | 6e0a3771 | Georgios D. Tsoukalas | .malloc = segdev_malloc, |
222 | 6e0a3771 | Georgios D. Tsoukalas | .realloc = segdev_realloc, |
223 | 6e0a3771 | Georgios D. Tsoukalas | .mfree = segdev_mfree |
224 | 6e0a3771 | Georgios D. Tsoukalas | }, |
225 | 6e0a3771 | Georgios D. Tsoukalas | /* name */
|
226 | 6e0a3771 | Georgios D. Tsoukalas | "segdev"
|
227 | 6e0a3771 | Georgios D. Tsoukalas | }; |
228 | 6e0a3771 | Georgios D. Tsoukalas | |
229 | 6e0a3771 | Georgios D. Tsoukalas | void xseg_segdev_init(void) |
230 | 6e0a3771 | Georgios D. Tsoukalas | { |
231 | 6e0a3771 | Georgios D. Tsoukalas | xseg_register_type(&xseg_segdev); |
232 | 6e0a3771 | Georgios D. Tsoukalas | xseg_register_peer(&xseg_peer_segdev); |
233 | 6e0a3771 | Georgios D. Tsoukalas | } |