]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/staging/vme/devices/vme_user.c
Staging: vme: llseek support in user driver
[mv-sheeva.git] / drivers / staging / vme / devices / vme_user.c
index e228942ee081deec0e705c67605d015b301e8a4e..ddecbe5105b98c9c26e067c40efba05357f36543 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * VMEbus User access driver
  *
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Author: Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * Based on work by:
  *   Tom Armistead and Ajit Prem
@@ -400,8 +400,39 @@ static ssize_t vme_user_write(struct file *file, const char *buf, size_t count,
 
 static loff_t vme_user_llseek(struct file *file, loff_t off, int whence)
 {
-       printk(KERN_ERR "Llseek currently incomplete\n");
-       return -EINVAL;
+       loff_t absolute = -1;
+       unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
+       size_t image_size;
+
+       down(&image[minor].sem);
+       image_size = vme_get_size(image[minor].resource);
+
+       switch (whence) {
+       case SEEK_SET:
+               absolute = off;
+               break;
+       case SEEK_CUR:
+               absolute = file->f_pos + off;
+               break;
+       case SEEK_END:
+               absolute = image_size + off;
+               break;
+       default:
+               up(&image[minor].sem);
+               return -EINVAL;
+               break;
+       }
+
+       if ((absolute < 0) || (absolute >= image_size)) {
+               up(&image[minor].sem);
+               return -EINVAL;
+       }
+
+       file->f_pos = absolute;
+
+       up(&image[minor].sem);
+
+       return absolute;
 }
 
 /*
@@ -574,8 +605,8 @@ static int __init vme_user_init(void)
         * in future revisions if that ever becomes necessary.
         */
        if (bus_num > USER_BUS_MAX) {
-               printk(KERN_ERR "%s: Driver only able to handle %d PIO2 "
-                       "Cards\n", driver_name, USER_BUS_MAX);
+               printk(KERN_ERR "%s: Driver only able to handle %d buses\n",
+                       driver_name, USER_BUS_MAX);
                bus_num = USER_BUS_MAX;
        }
 
@@ -818,7 +849,7 @@ MODULE_PARM_DESC(bus, "Enumeration of VMEbus to which the driver is connected");
 module_param_array(bus, int, &bus_num, 0);
 
 MODULE_DESCRIPTION("VME User Space Access Driver");
-MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com");
+MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
 MODULE_LICENSE("GPL");
 
 module_init(vme_user_init);