]> git.proxmox.com Git - mirror_spl-debian.git/blobdiff - module/splat/splat-ctl.c
Imported Upstream version 0.6.4.1
[mirror_spl-debian.git] / module / splat / splat-ctl.c
index 09f0847109e5bde571cf272da0f7ff7585b1d86b..4b9bcb3f068d746e0bf8f0cba1ce817fc8273786 100644 (file)
@@ -6,7 +6,7 @@
  *  UCRL-CODE-235197
  *
  *  This file is part of the SPL, Solaris Porting Layer.
- *  For details, see <http://github.com/behlendorf/spl/>.
+ *  For details, see <http://zfsonlinux.org/>.
  *
  *  The SPL is free software; you can redistribute it and/or modify it
  *  under the terms of the GNU General Public License as published by the
  *  of regression tests or particular tests.
 \*****************************************************************************/
 
+#include <sys/debug.h>
+#include <sys/mutex.h>
+#include <sys/types.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
 #include "splat-internal.h"
 
-static spl_class *splat_class;
-static spl_device *splat_device;
 static struct list_head splat_module_list;
 static spinlock_t splat_module_lock;
 
 static int
 splat_open(struct inode *inode, struct file *file)
 {
-       unsigned int minor = iminor(inode);
        splat_info_t *info;
 
-       if (minor >= SPLAT_MINORS)
-               return -ENXIO;
-
        info = (splat_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
        if (info == NULL)
                return -ENOMEM;
 
-       spin_lock_init(&info->info_lock);
+       mutex_init(&info->info_lock, SPLAT_NAME, MUTEX_DEFAULT, NULL);
        info->info_size = SPLAT_INFO_BUFFER_SIZE;
        info->info_buffer = (char *)vmalloc(SPLAT_INFO_BUFFER_SIZE);
        if (info->info_buffer == NULL) {
                kfree(info);
                return -ENOMEM;
        }
+       memset(info->info_buffer, 0, info->info_size);
 
        info->info_head = info->info_buffer;
        file->private_data = (void *)info;
 
-        return 0;
+       splat_print(file, "%s\n", spl_version);
+
+       return 0;
 }
 
 static int
 splat_release(struct inode *inode, struct file *file)
 {
-       unsigned int minor = iminor(inode);
        splat_info_t *info = (splat_info_t *)file->private_data;
 
-       if (minor >= SPLAT_MINORS)
-               return -ENXIO;
-
        ASSERT(info);
        ASSERT(info->info_buffer);
 
+       mutex_destroy(&info->info_lock);
        vfree(info->info_buffer);
        kfree(info);
 
@@ -103,10 +107,10 @@ splat_buffer_clear(struct file *file, splat_cfg_t *kcfg, unsigned long arg)
        ASSERT(info);
        ASSERT(info->info_buffer);
 
-       spin_lock(&info->info_lock);
+       mutex_enter(&info->info_lock);
        memset(info->info_buffer, 0, info->info_size);
        info->info_head = info->info_buffer;
-       spin_unlock(&info->info_lock);
+       mutex_exit(&info->info_lock);
 
        return 0;
 }
@@ -121,7 +125,7 @@ splat_buffer_size(struct file *file, splat_cfg_t *kcfg, unsigned long arg)
        ASSERT(info);
        ASSERT(info->info_buffer);
 
-       spin_lock(&info->info_lock);
+       mutex_enter(&info->info_lock);
        if (kcfg->cfg_arg1 > 0) {
 
                size = kcfg->cfg_arg1;
@@ -146,7 +150,7 @@ splat_buffer_size(struct file *file, splat_cfg_t *kcfg, unsigned long arg)
        if (copy_to_user((struct splat_cfg_t __user *)arg, kcfg, sizeof(*kcfg)))
                rc = -EFAULT;
 out:
-       spin_unlock(&info->info_lock);
+       mutex_exit(&info->info_lock);
 
        return rc;
 }
@@ -442,20 +446,15 @@ splat_ioctl_cmd(struct file *file, unsigned int cmd, unsigned long arg)
        return rc;
 }
 
-static int
-splat_ioctl(struct inode *inode, struct file *file,
-           unsigned int cmd, unsigned long arg)
+static long
+splat_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-        unsigned int minor = iminor(file->f_dentry->d_inode);
        int rc = 0;
 
        /* Ignore tty ioctls */
        if ((cmd & 0xffffff00) == ((int)'T') << 8)
                return -ENOTTY;
 
-       if (minor >= SPLAT_MINORS)
-               return -ENXIO;
-
        switch (cmd) {
                case SPLAT_CFG:
                        rc = splat_ioctl_cfg(file, cmd, arg);
@@ -477,7 +476,7 @@ splat_ioctl(struct inode *inode, struct file *file,
 static long
 splat_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-       return splat_ioctl(NULL, file, cmd, arg);
+       return splat_unlocked_ioctl(file, cmd, arg);
 }
 #endif /* CONFIG_COMPAT */
 
@@ -488,17 +487,13 @@ splat_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 static ssize_t splat_write(struct file *file, const char __user *buf,
                          size_t count, loff_t *ppos)
 {
-        unsigned int minor = iminor(file->f_dentry->d_inode);
        splat_info_t *info = (splat_info_t *)file->private_data;
        int rc = 0;
 
-       if (minor >= SPLAT_MINORS)
-               return -ENXIO;
-
        ASSERT(info);
        ASSERT(info->info_buffer);
 
-       spin_lock(&info->info_lock);
+       mutex_enter(&info->info_lock);
 
        /* Write beyond EOF */
        if (*ppos >= info->info_size) {
@@ -518,24 +513,20 @@ static ssize_t splat_write(struct file *file, const char __user *buf,
        *ppos += count;
        rc = count;
 out:
-       spin_unlock(&info->info_lock);
+       mutex_exit(&info->info_lock);
        return rc;
 }
 
 static ssize_t splat_read(struct file *file, char __user *buf,
                        size_t count, loff_t *ppos)
 {
-        unsigned int minor = iminor(file->f_dentry->d_inode);
        splat_info_t *info = (splat_info_t *)file->private_data;
        int rc = 0;
 
-       if (minor >= SPLAT_MINORS)
-               return -ENXIO;
-
        ASSERT(info);
        ASSERT(info->info_buffer);
 
-       spin_lock(&info->info_lock);
+       mutex_enter(&info->info_lock);
 
        /* Read beyond EOF */
        if (*ppos >= info->info_size)
@@ -553,23 +544,19 @@ static ssize_t splat_read(struct file *file, char __user *buf,
        *ppos += count;
        rc = count;
 out:
-       spin_unlock(&info->info_lock);
+       mutex_exit(&info->info_lock);
        return rc;
 }
 
 static loff_t splat_seek(struct file *file, loff_t offset, int origin)
 {
-        unsigned int minor = iminor(file->f_dentry->d_inode);
        splat_info_t *info = (splat_info_t *)file->private_data;
        int rc = -EINVAL;
 
-       if (minor >= SPLAT_MINORS)
-               return -ENXIO;
-
        ASSERT(info);
        ASSERT(info->info_buffer);
 
-       spin_lock(&info->info_lock);
+       mutex_enter(&info->info_lock);
 
        switch (origin) {
        case 0: /* SEEK_SET - No-op just do it */
@@ -588,17 +575,16 @@ static loff_t splat_seek(struct file *file, loff_t offset, int origin)
                rc = offset;
        }
 
-       spin_unlock(&info->info_lock);
+       mutex_exit(&info->info_lock);
 
        return rc;
 }
 
-static struct cdev splat_cdev;
 static struct file_operations splat_fops = {
        .owner          = THIS_MODULE,
        .open           = splat_open,
        .release        = splat_release,
-       .ioctl          = splat_ioctl,
+       .unlocked_ioctl = splat_unlocked_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl   = splat_compat_ioctl,
 #endif
@@ -607,11 +593,16 @@ static struct file_operations splat_fops = {
        .llseek         = splat_seek,
 };
 
-static int
+static struct miscdevice splat_misc = {
+       .minor          = MISC_DYNAMIC_MINOR,
+       .name           = SPLAT_NAME,
+       .fops           = &splat_fops,
+};
+
+static int __init
 splat_init(void)
 {
-       dev_t dev;
-       int rc;
+       int error;
 
        spin_lock_init(&splat_module_lock);
        INIT_LIST_HEAD(&splat_module_list);
@@ -630,54 +621,31 @@ splat_init(void)
        SPLAT_SUBSYSTEM_INIT(list);
        SPLAT_SUBSYSTEM_INIT(generic);
        SPLAT_SUBSYSTEM_INIT(cred);
-
-       dev = MKDEV(SPLAT_MAJOR, 0);
-        if ((rc = register_chrdev_region(dev, SPLAT_MINORS, SPLAT_NAME)))
-               goto error;
-
-       /* Support for registering a character driver */
-       cdev_init(&splat_cdev, &splat_fops);
-       splat_cdev.owner = THIS_MODULE;
-       kobject_set_name(&splat_cdev.kobj, SPLAT_NAME);
-       if ((rc = cdev_add(&splat_cdev, dev, SPLAT_MINORS))) {
-               printk(KERN_ERR "SPLAT: Error adding cdev, %d\n", rc);
-               kobject_put(&splat_cdev.kobj);
-               unregister_chrdev_region(dev, SPLAT_MINORS);
-               goto error;
+       SPLAT_SUBSYSTEM_INIT(zlib);
+       SPLAT_SUBSYSTEM_INIT(linux);
+
+       error = misc_register(&splat_misc);
+       if (error) {
+               printk(KERN_INFO "SPLAT: misc_register() failed %d\n", error);
+       } else {
+               printk(KERN_INFO "SPLAT: Loaded module v%s-%s%s\n",
+                   SPL_META_VERSION, SPL_META_RELEASE, SPL_DEBUG_STR);
        }
 
-       /* Support for udev make driver info available in sysfs */
-        splat_class = spl_class_create(THIS_MODULE, "splat");
-       if (IS_ERR(splat_class)) {
-               rc = PTR_ERR(splat_class);
-               printk(KERN_ERR "SPLAT: Error creating splat class, %d\n", rc);
-               cdev_del(&splat_cdev);
-               unregister_chrdev_region(dev, SPLAT_MINORS);
-               goto error;
-       }
-
-       splat_device = spl_device_create(splat_class, NULL,
-                                        MKDEV(SPLAT_MAJOR, 0),
-                                        NULL, SPLAT_NAME);
-
-       printk(KERN_INFO "SPLAT: Loaded Solaris Porting LAyer "
-              "Tests v%s\n", SPL_META_VERSION);
-       return 0;
-error:
-       printk(KERN_ERR "SPLAT: Error registering splat device, %d\n", rc);
-       return rc;
+       return (error);
 }
 
-static int
+static void __exit
 splat_fini(void)
 {
-       dev_t dev = MKDEV(SPLAT_MAJOR, 0);
+       int error;
 
-        spl_device_destroy(splat_class, splat_device, dev);
-        spl_class_destroy(splat_class);
-        cdev_del(&splat_cdev);
-        unregister_chrdev_region(dev, SPLAT_MINORS);
+       error = misc_deregister(&splat_misc);
+       if (error)
+               printk(KERN_INFO "SPLAT: misc_deregister() failed %d\n", error);
 
+       SPLAT_SUBSYSTEM_FINI(linux);
+       SPLAT_SUBSYSTEM_FINI(zlib);
        SPLAT_SUBSYSTEM_FINI(cred);
        SPLAT_SUBSYSTEM_FINI(generic);
        SPLAT_SUBSYSTEM_FINI(list);
@@ -694,15 +662,14 @@ splat_fini(void)
        SPLAT_SUBSYSTEM_FINI(kmem);
 
        ASSERT(list_empty(&splat_module_list));
-       printk(KERN_INFO "SPLAT: Unloaded Solaris Porting LAyer "
-              "Tests v%s\n", SPL_META_VERSION);
-
-       return 0;
+       printk(KERN_INFO "SPLAT: Unloaded module v%s-%s%s\n",
+           SPL_META_VERSION, SPL_META_RELEASE, SPL_DEBUG_STR);
 }
 
-spl_module_init(splat_init);
-spl_module_exit(splat_fini);
+module_init(splat_init);
+module_exit(splat_fini);
 
-MODULE_AUTHOR("Lawrence Livermore National Labs");
 MODULE_DESCRIPTION("Solaris Porting LAyer Tests");
-MODULE_LICENSE("GPL");
+MODULE_AUTHOR(SPL_META_AUTHOR);
+MODULE_LICENSE(SPL_META_LICENSE);
+MODULE_VERSION(SPL_META_VERSION "-" SPL_META_RELEASE);