aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/litmus/ftdev.h5
-rw-r--r--litmus/ftdev.c16
2 files changed, 20 insertions, 1 deletions
diff --git a/include/litmus/ftdev.h b/include/litmus/ftdev.h
index 348387e9adf9..0b959874dd70 100644
--- a/include/litmus/ftdev.h
+++ b/include/litmus/ftdev.h
@@ -16,7 +16,8 @@ typedef int (*ftdev_can_open_t)(struct ftdev* dev, unsigned int buf_no);
16/* return 0 on success, otherwise -$REASON */ 16/* return 0 on success, otherwise -$REASON */
17typedef int (*ftdev_alloc_t)(struct ftdev* dev, unsigned int buf_no); 17typedef int (*ftdev_alloc_t)(struct ftdev* dev, unsigned int buf_no);
18typedef void (*ftdev_free_t)(struct ftdev* dev, unsigned int buf_no); 18typedef void (*ftdev_free_t)(struct ftdev* dev, unsigned int buf_no);
19 19/* Let devices handle writes from userspace. No synchronization provided. */
20typedef ssize_t (*ftdev_write_t)(struct ft_buffer* buf, size_t len, const char __user *from);
20 21
21struct ftdev_event; 22struct ftdev_event;
22 23
@@ -27,6 +28,7 @@ struct ftdev_minor {
27 /* FIXME: filter for authorized events */ 28 /* FIXME: filter for authorized events */
28 struct ftdev_event* events; 29 struct ftdev_event* events;
29 struct device* device; 30 struct device* device;
31 struct ftdev* ftdev;
30}; 32};
31 33
32struct ftdev { 34struct ftdev {
@@ -39,6 +41,7 @@ struct ftdev {
39 ftdev_alloc_t alloc; 41 ftdev_alloc_t alloc;
40 ftdev_free_t free; 42 ftdev_free_t free;
41 ftdev_can_open_t can_open; 43 ftdev_can_open_t can_open;
44 ftdev_write_t write;
42}; 45};
43 46
44struct ft_buffer* alloc_ft_buffer(unsigned int count, size_t size); 47struct ft_buffer* alloc_ft_buffer(unsigned int count, size_t size);
diff --git a/litmus/ftdev.c b/litmus/ftdev.c
index 216dc0b4cb94..06fcf4cf77dc 100644
--- a/litmus/ftdev.c
+++ b/litmus/ftdev.c
@@ -114,6 +114,7 @@ static int ftdev_open(struct inode *in, struct file *filp)
114 goto out; 114 goto out;
115 115
116 ftdm = ftdev->minor + buf_idx; 116 ftdm = ftdev->minor + buf_idx;
117 ftdm->ftdev = ftdev;
117 filp->private_data = ftdm; 118 filp->private_data = ftdm;
118 119
119 if (mutex_lock_interruptible(&ftdm->lock)) { 120 if (mutex_lock_interruptible(&ftdm->lock)) {
@@ -284,11 +285,25 @@ out:
284 return err; 285 return err;
285} 286}
286 287
288static ssize_t ftdev_write(struct file *filp, const char __user *from,
289 size_t len, loff_t *f_pos)
290{
291 struct ftdev_minor* ftdm = filp->private_data;
292 ssize_t err = -EINVAL;
293 struct ftdev* ftdev = ftdm->ftdev;
294
295 /* dispatch write to buffer-specific code, if available */
296 if (ftdev->write)
297 err = ftdev->write(ftdm->buf, len, from);
298
299 return err;
300}
287 301
288struct file_operations ftdev_fops = { 302struct file_operations ftdev_fops = {
289 .owner = THIS_MODULE, 303 .owner = THIS_MODULE,
290 .open = ftdev_open, 304 .open = ftdev_open,
291 .release = ftdev_release, 305 .release = ftdev_release,
306 .write = ftdev_write,
292 .read = ftdev_read, 307 .read = ftdev_read,
293 .unlocked_ioctl = ftdev_ioctl, 308 .unlocked_ioctl = ftdev_ioctl,
294}; 309};
@@ -308,6 +323,7 @@ int ftdev_init( struct ftdev* ftdev, struct module* owner,
308 ftdev->alloc = NULL; 323 ftdev->alloc = NULL;
309 ftdev->free = NULL; 324 ftdev->free = NULL;
310 ftdev->can_open = NULL; 325 ftdev->can_open = NULL;
326 ftdev->write = NULL;
311 327
312 ftdev->minor = kcalloc(ftdev->minor_cnt, sizeof(*ftdev->minor), 328 ftdev->minor = kcalloc(ftdev->minor_cnt, sizeof(*ftdev->minor),
313 GFP_KERNEL); 329 GFP_KERNEL);