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