5 #include <linux/module.h>
6 #include <linux/moduleparam.h>
7 #include <linux/init.h>
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/slab.h>
12 #include <linux/errno.h>
13 #include <linux/timer.h>
14 #include <linux/types.h>
15 #include <linux/vmalloc.h>
16 #include <linux/genhd.h>
17 #include <linux/blkdev.h>
18 #include <linux/bio.h>
19 #include <linux/device.h>
20 #include <linux/completion.h>
22 #include <xseg/xseg.h>
23 #include <sys/kernel/segdev.h>
26 MODULE_DESCRIPTION("xseg_segdev");
27 MODULE_AUTHOR("XSEG");
28 MODULE_LICENSE("GPL");
30 /* for now, support only one peer */
31 static struct xseg *xsegments[1];
32 static unsigned int nr_xsegments = 1;
38 static void *segdev_malloc(uint64_t size)
40 return kmalloc((size_t)size, GFP_KERNEL);
43 static void *segdev_realloc(void *mem, uint64_t size)
45 return krealloc(mem, (size_t)size, GFP_KERNEL);
48 static void segdev_mfree(void *ptr)
53 static long segdev_allocate(const char *name, uint64_t size)
56 struct segdev *segdev = segdev_get(0);
58 r = IS_ERR(segdev) ? PTR_ERR(segdev) : 0;
60 XSEGLOG("cannot acquire segdev");
64 if (segdev->segment) {
65 XSEGLOG("destroying existing segdev segment");
66 r = segdev_destroy_segment(segdev);
71 XSEGLOG("creating segdev segment size %llu", size);
72 r = segdev_create_segment(segdev, size, 1);
82 static long segdev_deallocate(const char *name)
84 struct segdev *segdev = segdev_get(0);
85 int r = IS_ERR(segdev) ? PTR_ERR(segdev) : 0;
89 clear_bit(SEGDEV_RESERVED, &segdev->flags);
90 XSEGLOG("destroying segment");
91 r = segdev_destroy_segment(segdev);
93 XSEGLOG(" ...failed");
98 static void *segdev_map(const char *name, uint64_t size, struct xseg *seg)
100 struct xseg *xseg = NULL;
101 /* map() holds a reference to the segment */
102 struct segdev *dev = segdev_get(0);
103 struct segpriv *priv;
105 r = IS_ERR(dev) ? PTR_ERR(dev) : 0;
112 if (size > dev->segsize)
116 if (priv->segno >= nr_xsegments)
120 xsegments[priv->segno] = seg;
122 xseg = (void *)dev->segment;
127 static void segdev_unmap(void *ptr, uint64_t size)
129 struct segdev *segdev = segdev_get(0);
130 struct segpriv *priv;
131 int r = IS_ERR(segdev) ? PTR_ERR(segdev) : 0;
136 if (priv->segno >= nr_xsegments)
139 xsegments[priv->segno] = NULL;
142 /* unmap() releases the reference taken by map() */
148 static void segdev_callback(struct segdev *dev, xport portno)
151 struct segpriv *priv = dev->priv;
152 struct xseg_private *xpriv;
153 struct xseg_port *port;
154 if (priv->segno >= nr_xsegments)
157 xseg = xsegments[priv->segno];
159 port = xseg_get_port(xseg, portno);
160 if (!port || !port->waitcue)
164 xpriv->wakeup(portno);
168 static struct xseg_type xseg_segdev = {
169 /* xseg operations */
171 .allocate = segdev_allocate,
172 .deallocate = segdev_deallocate,
174 .unmap = segdev_unmap
180 static int segdev_signal_init(void)
182 struct segdev *segdev = segdev_get(0);
183 struct segpriv *segpriv;
184 int r = IS_ERR(segdev) ? PTR_ERR(segdev) : 0;
193 segpriv = kmalloc(sizeof(struct segpriv), GFP_KERNEL);
198 segdev->callback = segdev_callback;
199 segdev->priv = segpriv;
206 static void segdev_signal_quit(void)
208 struct segdev *segdev = segdev_get(0);
209 int r = IS_ERR(segdev) ? PTR_ERR(segdev) : 0;
212 segdev->callback = NULL;
218 static int segdev_prepare_wait(struct xseg *xseg, uint32_t portno)
220 struct xseg_port *port = xseg_get_port(xseg, portno);
223 /* true/false value */
228 static int segdev_cancel_wait(struct xseg *xseg, uint32_t portno)
230 struct xseg_port *port = xseg_get_port(xseg, portno);
233 /* true/false value */
238 static int segdev_wait_signal(struct xseg *xseg, uint32_t timeout)
243 static int segdev_signal(struct xseg *xseg, uint32_t portno)
248 static struct xseg_peer xseg_peer_segdev = {
249 /* xseg signal operations */
251 .signal_init = segdev_signal_init,
252 .signal_quit = segdev_signal_quit,
253 .cancel_wait = segdev_cancel_wait,
254 .prepare_wait = segdev_prepare_wait,
255 .wait_signal = segdev_wait_signal,
256 .signal = segdev_signal,
257 .malloc = segdev_malloc,
258 .realloc = segdev_realloc,
259 .mfree = segdev_mfree
266 /* ************************* */
267 /* ** XSEG Initialization ** */
268 /* ************************* */
270 static int segdev_init(void)
274 XSEGLOG("registering xseg types");
275 r = xseg_register_type(&xseg_segdev);
279 r = xseg_register_peer(&xseg_peer_segdev);
285 xseg_unregister_type(xseg_segdev.name);
290 static int segdev_quit(void)
292 struct segdev *segdev;
294 /* make sure to unmap the segment first */
295 segdev = segdev_get(0);
296 clear_bit(SEGDEV_RESERVED, &segdev->flags);
299 xseg_unregister_peer(xseg_peer_segdev.name);
300 xseg_unregister_type(xseg_segdev.name);
305 /* *************************** */
306 /* ** Module Initialization ** */
307 /* *************************** */
309 static int __init xseg_segdev_init(void)
317 XSEGLOG("initialization complete");
322 static void __exit xseg_segdev_exit(void)
327 module_init(xseg_segdev_init);
328 module_exit(xseg_segdev_exit);