aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/ftdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'litmus/ftdev.c')
-rw-r--r--litmus/ftdev.c73
1 files changed, 36 insertions, 37 deletions
diff --git a/litmus/ftdev.c b/litmus/ftdev.c
index 4a4b2e3e56c2..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)) {
@@ -250,64 +251,61 @@ out:
250 return err; 251 return err;
251} 252}
252 253
253typedef uint32_t cmd_t; 254static long ftdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
254
255static ssize_t ftdev_write(struct file *filp, const char __user *from,
256 size_t len, loff_t *f_pos)
257{ 255{
256 long err = -ENOIOCTLCMD;
258 struct ftdev_minor* ftdm = filp->private_data; 257 struct ftdev_minor* ftdm = filp->private_data;
259 ssize_t err = -EINVAL;
260 cmd_t cmd;
261 cmd_t id;
262
263 if (len % sizeof(cmd) || len < 2 * sizeof(cmd))
264 goto out;
265
266 if (copy_from_user(&cmd, from, sizeof(cmd))) {
267 err = -EFAULT;
268 goto out;
269 }
270 len -= sizeof(cmd);
271 from += sizeof(cmd);
272
273 if (cmd != FTDEV_ENABLE_CMD && cmd != FTDEV_DISABLE_CMD)
274 goto out;
275 258
276 if (mutex_lock_interruptible(&ftdm->lock)) { 259 if (mutex_lock_interruptible(&ftdm->lock)) {
277 err = -ERESTARTSYS; 260 err = -ERESTARTSYS;
278 goto out; 261 goto out;
279 } 262 }
280 263
281 err = sizeof(cmd); 264 /* FIXME: check id against list of acceptable events */
282 while (len) { 265
283 if (copy_from_user(&id, from, sizeof(cmd))) { 266 switch (cmd) {
284 err = -EFAULT; 267 case FTDEV_ENABLE_CMD:
285 goto out_unlock; 268 if (activate(&ftdm->events, arg))
286 }
287 /* FIXME: check id against list of acceptable events */
288 len -= sizeof(cmd);
289 from += sizeof(cmd);
290 if (cmd == FTDEV_DISABLE_CMD)
291 deactivate(&ftdm->events, id);
292 else if (activate(&ftdm->events, id) != 0) {
293 err = -ENOMEM; 269 err = -ENOMEM;
294 goto out_unlock; 270 else
295 } 271 err = 0;
296 err += sizeof(cmd); 272 break;
297 } 273
274 case FTDEV_DISABLE_CMD:
275 deactivate(&ftdm->events, arg);
276 err = 0;
277 break;
278
279 default:
280 printk(KERN_DEBUG "ftdev: strange ioctl (%u, %lu)\n", cmd, arg);
281 };
298 282
299out_unlock:
300 mutex_unlock(&ftdm->lock); 283 mutex_unlock(&ftdm->lock);
301out: 284out:
302 return err; 285 return err;
303} 286}
304 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}
301
305struct file_operations ftdev_fops = { 302struct file_operations ftdev_fops = {
306 .owner = THIS_MODULE, 303 .owner = THIS_MODULE,
307 .open = ftdev_open, 304 .open = ftdev_open,
308 .release = ftdev_release, 305 .release = ftdev_release,
309 .write = ftdev_write, 306 .write = ftdev_write,
310 .read = ftdev_read, 307 .read = ftdev_read,
308 .unlocked_ioctl = ftdev_ioctl,
311}; 309};
312 310
313int ftdev_init( struct ftdev* ftdev, struct module* owner, 311int ftdev_init( struct ftdev* ftdev, struct module* owner,
@@ -325,6 +323,7 @@ int ftdev_init( struct ftdev* ftdev, struct module* owner,
325 ftdev->alloc = NULL; 323 ftdev->alloc = NULL;
326 ftdev->free = NULL; 324 ftdev->free = NULL;
327 ftdev->can_open = NULL; 325 ftdev->can_open = NULL;
326 ftdev->write = NULL;
328 327
329 ftdev->minor = kcalloc(ftdev->minor_cnt, sizeof(*ftdev->minor), 328 ftdev->minor = kcalloc(ftdev->minor_cnt, sizeof(*ftdev->minor),
330 GFP_KERNEL); 329 GFP_KERNEL);