Statistics
| Branch: | Tag: | Revision:

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
}