root / xseg / drivers / user / xseg_segdev.c @ 7ce25cf6
History | View | Annotate | Download (3.7 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 |
if (ioctl(fd, SEGDEV_IOC_CREATESEG, size)) {
|
75 |
XSEGLOG("Failed to create segment");
|
76 |
closedev(); |
77 |
return -3; |
78 |
} |
79 |
|
80 |
return 0; |
81 |
} |
82 |
|
83 |
static long segdev_deallocate(const char *name) |
84 |
{ |
85 |
int fd;
|
86 |
fd = open(SEGDEV_DEVICE, O_RDWR); |
87 |
if (fd < 0) { |
88 |
XSEGLOG("Cannot open %s: %s\n", SEGDEV_DEVICE,
|
89 |
strerror_r(errno, errbuf, ERRSIZE)); |
90 |
return -1; |
91 |
} |
92 |
|
93 |
if (ioctl(fd, SEGDEV_IOC_DESTROYSEG, 0)) { |
94 |
XSEGLOG("Failed to destroy old segment");
|
95 |
return -2; |
96 |
} |
97 |
|
98 |
closedev(); |
99 |
return 0; |
100 |
} |
101 |
|
102 |
static void *segdev_map(const char *name, uint64_t size, struct xseg *seg) |
103 |
{ |
104 |
struct xseg *xseg;
|
105 |
int fd;
|
106 |
|
107 |
if (seg)
|
108 |
XSEGLOG("struct xseg * not NULL. Ignoring...\n");
|
109 |
|
110 |
fd = opendev(); |
111 |
if (fd < 0) |
112 |
return NULL; |
113 |
|
114 |
xseg = mmap ( XSEG_BASE_AS_PTR, |
115 |
size, |
116 |
PROT_READ | PROT_WRITE, |
117 |
MAP_SHARED | MAP_FIXED /* | MAP_LOCKED */,
|
118 |
fd, 0 );
|
119 |
|
120 |
if (xseg == MAP_FAILED) {
|
121 |
XSEGLOG("Could not map segment: %s\n",
|
122 |
strerror_r(errno, errbuf, ERRSIZE)); |
123 |
closedev(); |
124 |
return NULL; |
125 |
} |
126 |
|
127 |
return xseg;
|
128 |
} |
129 |
|
130 |
static void segdev_unmap(void *ptr, uint64_t size) |
131 |
{ |
132 |
struct xseg *xseg = ptr;
|
133 |
(void)munmap(xseg, xseg->segment_size);
|
134 |
} |
135 |
|
136 |
|
137 |
static struct xseg_type xseg_segdev = { |
138 |
/* xseg_operations */
|
139 |
{ |
140 |
.allocate = segdev_allocate, |
141 |
.deallocate = segdev_deallocate, |
142 |
.map = segdev_map, |
143 |
.unmap = segdev_unmap |
144 |
}, |
145 |
/* name */
|
146 |
"segdev"
|
147 |
}; |
148 |
|
149 |
static int segdev_signal_init(void) |
150 |
{ |
151 |
return 0; |
152 |
} |
153 |
|
154 |
static void segdev_signal_quit(void) |
155 |
{ |
156 |
return;
|
157 |
} |
158 |
|
159 |
static int segdev_prepare_wait(struct xseg *xseg, uint32_t portno) |
160 |
{ |
161 |
return -1; |
162 |
} |
163 |
|
164 |
static int segdev_cancel_wait(struct xseg *xseg, uint32_t portno) |
165 |
{ |
166 |
return -1; |
167 |
} |
168 |
|
169 |
static int segdev_wait_signal(struct xseg *xseg, uint32_t timeout) |
170 |
{ |
171 |
return -1; |
172 |
} |
173 |
|
174 |
static int segdev_signal(struct xseg *xseg, uint32_t portno) |
175 |
{ |
176 |
return write(opendev(), &portno, sizeof(portno)); |
177 |
} |
178 |
|
179 |
static void *segdev_malloc(uint64_t size) |
180 |
{ |
181 |
return NULL; |
182 |
} |
183 |
|
184 |
static void *segdev_realloc(void *mem, uint64_t size) |
185 |
{ |
186 |
return NULL; |
187 |
} |
188 |
|
189 |
static void segdev_mfree(void *mem) { } |
190 |
|
191 |
static struct xseg_peer xseg_peer_segdev = { |
192 |
/* xseg signal operations */
|
193 |
{ |
194 |
.signal_init = segdev_signal_init, |
195 |
.signal_quit = segdev_signal_quit, |
196 |
.prepare_wait = segdev_prepare_wait, |
197 |
.cancel_wait = segdev_cancel_wait, |
198 |
.wait_signal = segdev_wait_signal, |
199 |
.signal = segdev_signal, |
200 |
.malloc = segdev_malloc, |
201 |
.realloc = segdev_realloc, |
202 |
.mfree = segdev_mfree |
203 |
}, |
204 |
/* name */
|
205 |
"segdev"
|
206 |
}; |
207 |
|
208 |
void xseg_segdev_init(void) |
209 |
{ |
210 |
xseg_register_type(&xseg_segdev); |
211 |
xseg_register_peer(&xseg_peer_segdev); |
212 |
} |
213 |
|