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